Redis 学习——入门篇

一、Redis 简介

Redis 是完全开源的,遵守 BSD 协议,是一个高性能的 key-value 数据库,类似于 Java 中的 Map<key, value>。

Redis 与其他 key - value 缓存产品有以下特点:

(1)Redis 数据库中所有数据都存储在内存中,由于内存的读写速度远快于硬盘,因此 Redis 在性能上对比其他基于硬盘存储的数据库有非常明显的优势
(2)Redis 支持数据的持久化,可以将内存中的数据异步写入到磁盘中,重启的时候可以再次加载进行使用
(3)Redis 不仅仅支持简单的 key-value 类型的数据,同时还提供 list,set,zset,hash 等数据结构的存储。
(4)Redis 支持数据的备份,即 master-slave 模式的数据备份

Redis 的特点:

(1)速度快

1)纯内存操作
2)单线程操作,避免了频繁的上下文切换
3) 采用了非阻塞 I/O 多路复用机制

(2)原子性

Redis 的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过 MULTI 和 EXEC 指令包起来

(3)键值对的数据结构服务器

5种常用数据结构:String、hash、 list、 set、 zSet

(4)简单稳定

单线程,协议简单

(5)持久化

将内存数据写入磁盘

(6)主从复制

实现多个相同数据的 redis 副本

(7)高可用和分布式集群

哨兵机制实现高可用,保证 redis 节点故障发现和自动转移

(8)客户端语言多

java、php、python、c、c++、node.js等

使用 Redis 的缺点

(1)缓存和数据库双写一致性问题
(2)缓存雪崩问题
(3)缓存击穿问题
(4)缓存的并发竞争问题

Redis 应用场景

1、缓存数据库

合理使用缓存加快数据访问速度,降低关系型数据库压力

2、排行榜

按照热度排名,按照发布时间排行,主要用到列表和有序集合

3、计数器应用

视频网站播放数,网站浏览数

4、社交网络

赞、踩、粉丝、下拉刷新

5、消息队列

发布和订阅

6、其他场景。。

二、redis 配置、启动、操作、关闭

在这里插入图片描述
停止 redis 服务:redis-cli shutdown

注意:

a、 关闭时,断开连接,持久化文件生成,相对安全
b、 使用 kill 方式关闭进程时,不会做持久化,还会造成缓冲区非法关闭,会导致数据丢失
c、 关闭前持久化文件,登录 redis-cli 客户端,再 shutdown nosave|save 。

三、Redis 的数据结构

1、String

字符串类型:实际上可以是字符串(包括 XML JSON),还有数字(整形 浮点数),二进制(图片 音频 视频),最大不能超过 512MB

示例

// 1、设值指令
set age 22 ex 10 // 10秒后过期, ttl age 查询剩余时间
setnx name test // 不存在键name时,返回1设置为成功,返回0失败

// 2、获取指令
get age // 存在返回age的值

// 3、删除指令
del age // 删除age,返回1

// 4、批量操作
mset name wanglei age 22 // 批量set
mget name age // 批量get

// 5、计数
incr age // 必须为证书自加1,非整数返回错误,无age键从0开始自增返回1
decr age // 整数age减1
incrby age 2 // 整数age + 2
decrby age 2 // 整数age - 2
incrbyfloat score 1.1 // 浮点型 score + 1.1

// 5、追加、长度、截取字符串
set name hello;
append name zhangsan; // 追加字符串,变成 hellozhangsan
set zhangsan "张三";
strlen zhangsan // 字符串长度,结果为6,每个中文占3个字节
set name helloworld;
getrange name 0 2 // 截取字符串,返回hel

补充

1)EX seconds : 将键的过期时间设置为 seconds 秒。 执行 SET key value EX seconds 的效果等同于执行 SETEX key seconds value 。
2)PX milliseconds : 将键的过期时间设置为 milliseconds 毫秒。 执行 SET key value PX milliseconds 的效果等同于执行 PSETEX key milliseconds value 。
3)NX : 只在键不存在时, 才对键进行设置操作。 执行 SET key value NX 的效果等同于执行 SETNX key value 。
4)XX : 只在键已经存在时, 才对键进行设置操作。

2、Hash

Redis hash 是一个键值对集合。
Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象,类似 Java 里面的 Map<String,Object>,最大存储 512M。
在这里插入图片描述

示例:

hset user:1 name wanglei	// 设置指令,成功返回1,失败返回0
hget user:1 name 	// 读取指令,返回wanglei
hlen user:1 	// 计算field个数,返回2
hdel user:1 name 	// 删除field,返回删除个数
hmset user:2 name wanglei age 23 sex boy 	// 批量设置,返回OK
hmget user:2 name age sex    	// 批量读取,返回三行:wanglei 23 boy

// 判断field是否存在:
hexists user:2 name // 若存在返回1,不存在返回0

// 获取所有field: 
hkeys user:2 // 返回name age sex三个field

// 获取user:2所有value:
hvals user:2 // wanglei 23 boy

// 获取user:2所有field与value:
hgetall user:2

// 整型增加1:
hincrby user:2 age 1 // age+1

// 浮点型增加2:
hincrbyfloat user:2 age 2 // 浮点型加2

三种方式存储user信息比较

1)原生

set user:1:name wanglei;
set user:1:age 22;
set user:1:sex boy;

优点:简单直观,每个键对应一个值。
缺点:键数过多,占用内存多,用户信息过于分散,不用于生产环境。

2)将对象序列化存入 redis。

set user:1 serialize(userInfo);

优点:编程简单,若使用序列化合理内存使用率高。
缺点:序列化与反序列化有一定开销,更新属性时需要把 userInfo 全取出来进行反序列化,更新后再序列化到 redis。

3)使用 hash 类型。

hmset user:1 name wanglei age 23 sex boy

优点:简单直观,使用合理可减少内存空间消耗。
缺点:要控制 ziplist 与 hashtable 两种编码转换,且 hashtable 会消耗更多内存 serialize(userInfo)。

3、List

用来存储多个有序的字符串,一个列表可以存的最大元素:2的23次方减1 。

因为有序,可以通过索引下标获取元素或某个范围内的元素列表,列表元素可以重复

特点

单键多值,底层实际是个双向链表对两端的操作性能很高,通过索引下标操作中间的节点性能会较差
在这里插入图片描述

示例

rpush testlist c b a // 从右向左插入c b a, 返回3
lrange testlist 0 -1 // 从左往右获取列表元素,返回c b a,0 -1为索引下标
lpush testlist 1 2 3 // 从左向右插入1 2 3, 返回6
linsert testlist before 1 0 // 在1之前插入0,返回7,after为之后,使用lrange testlist 0 -1 查看,返回结果为3 2 0 1 c b a

lindex testlist -1 // 返回最右末尾a,-2返回b
llen testlist // 当前列表长度,返回7
lpop testlist // 把最左边的第一个元素删除,返回3
rpop testlist // 把最右边的第一个元素删除,返回a

4、 Set

用户标签,社交,查询有共同兴趣爱好的人,智能推荐。

保存多元素,与列表不一样的是不允许有重复元素,且集合是无序,一个集合最多可存2的32次方减1个元素,除了支持增删改查,还支持集合交集、并集、差集。
底层其实是一个 value 为 null 的哈希表
在这里插入图片描述

示例

exists user // 检查user键值是否存在,存在返回1,不存在返回0
sadd user a b c // 向user插入3个元素,返回3
sadd user a b // 若再加入相同的元素,则重复无效,返回0
smembers user // 获取user的所有元素,返回结果无序
srem user a // 返回1,删除a元素
scard user // 返回2,计算元素个数

// 场景,求共同爱好语言
// 使用方式,给用户添加标签,或者给标签添加用户。

// 给用户添加标签
sadd user:1:fav java js vue python
sadd user:2:fav vue python node.js
sadd user:3:fav c c++ c#

// 求共同爱好,即求交集
sinter user:1:fav user:2:fav // 返回vue、python
sinter user:1:fav user:2:fav user:3:fav // 返回(empty list or set)

5、zSet

Redis 有序集合 zset 与普通集合 set 非常相似,是一个没有重复元素的字符串集合。不同之处是有序集合的每个成员都关联了一个评分(score),这个评分(score)被用来按照从最低分到最高分的方式排序集合中的成员。集合的成员是唯一的,但是评分可以是重复的
zset 底层使用了两个数据结构:

1)hash:hash 的作用就是关联元素 value 和权重 score,保障元素 value 的唯一性,可以通过元素 value 找到相应的 score 值。
2)跳跃表:跳跃表的目的在于给元素 value 排序,根据 score 的范围获取元素列表。
在这里插入图片描述

常用于排行榜,如视频网站需要对用户上传视频做排行榜,或点赞数与集合有联系,不能有重复的成员。

示例

zadd user:zan 200 wanglei 120 zhangsan 140 lisi // 增加元素,返回3
zrange user:zan 0 -1 withscores // 查询元素,返回点赞数和成员名称,返回张三 120 lisi 140 wanglei 200
zrank user:zan lisi // 返回名次,返回1,排名为0,1,2
zrevrank user:zan wanglei // 反向排名,点赞越多排名越前,返回0

zadd test:1 nx 100 wanglei // 键test:1必须不存在,主要用于添加
zadd test:1 xx incr 200 wanglei // 键test:1必须存在,主要用于修改,此时300
zadd test:1 xx ch incr -299 wanglei // 返回操作结果1,300-29=1

zcard test:1 // 计算成员个数,返回1

list、set、zSet 比较

在这里插入图片描述

Redis6 的新数据类型

(1)Bitmaps

Redis提供了Bitmaps这个“数据类型”可以实现对位的操作:

(1)Bitmaps 本身不是一种数据类型, 实际上它就是字符串(key-value) , 但是它可以对字符串的位进行操作

(2)Bitmaps 单独提供了一套命令, 所以在 Redis 中使用 Bitmaps 和使用字符串的方法不太相同。 可以把 Bitmaps 想象成一个以位为单位的数组, 数组的每个单元只能存储 0 和 1, 数组的下标在 Bitmaps 中叫做偏移量。
在这里插入图片描述

(2)HyperLogLog

Redis HyperLogLog 是用来做基数统计的算法。
HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的。每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基数,这与元素越多耗费内存就越多的集合形成鲜明对比。

(3)Geospatial

redis 基于该类型,提供了经纬度设置,查询,范围查询,距离查询,经纬度 Hash 等常见操作。

四、redis 数据库管理

在这里插入图片描述
默认支持16个数据库;可以理解为一个命名空间。跟关系型数据库不一样的点:

redis 不支持自定义数据库名词
每个数据库不能单独设置授权。
每个数据库之间并不是完全隔离的。 可以通过 flushall 命令清空 redis 实例面的所有数据库中的数据。
通过 select dbid 去选择不同的数据库命名空间,dbid 的取值范围默认是 0 -15

全局命令

(1)查看所有键: keys * (可以查询所有key,也可以模糊搜索,如 keys user* ,但是线上不推荐使用。)
(2)键总数:dbsize (如果存在大量键,线上不建议使用。)
(3)检查键是否存在:exists key (存在返回 1,不存在返回 0。)
(4) 设置键过期时间: expire username 20 (设置 username 20秒过期,ttl username 查看剩余时间。)
(5)查看数据类型:type username (返回string,不存在返回none。)

五、Redis 持久化机制

redis 是一个支持持久化的内存数据库,也就是说 redis 需要经常将内存中的数据同步到磁盘来保证持久化,持久化可以避免因进程退出而造成数据丢失。

1、RDB 持久化方式

RDB 持久化把当前进程数据生成快照(.rdb)文件保存到硬盘的过程,有手动触发和自动触发。

手动触发有 save 和 bgsave 两命令 :

1) save命令:阻塞当前redis,直到RDB持久化过程完成为止,若内存实例比较大会造成长时间阻塞,线上环境不建议用它。
2)bgsave命令:redis 进程执行 fork 操作创建子进程,由子线程完成持久化,阻塞时间很短(微秒级),是 save 的优化,在执行 redis-cli shutdown 关闭 redis 服务时,如果没有开启 AOF 持久化,自动执行 bgsave。
在这里插入图片描述

RDB 如何恢复

redis.conf 文件配置了指定目录,重启 redis 恢复数据

RDB 持久化优缺点

优点:

压缩后的二进制文,适用于备份、全量复制,用于灾难恢复。
加载 RDB 恢复数据远快于 AOF 方式

缺点:

无法做到实时持久化,每次都要创建子进程,频繁操作成本过高
保存后的二进制文件,存在老版本不兼容新版本 rdb 文件的问题。

2、AOF 持久化

针对 RDB 不适合实时持久化,redis 提供了 AOF 持久化方式来解决

开启:redis.conf 设置:appendonly yes (默认不开启,为no)
默认文件名:appendfilename “appendonly.aof”

AOF 持久化流程

1)所有的写入命令(set hset)会 append 追加到 aof_buf 缓冲区中
2)AOF 缓冲区向硬盘做 sync 同步
3)随着 AOF 文件越来越大,需定期对 AOF 文件 rewrite 重写,达到压缩。
4)当 redis 服务重启,可 load 加载 AOF 文件进行恢复
在这里插入图片描述

AOP如何恢复

redis.conf 文件配置了指定目录,重启 redis 恢复数据。

AOP 配置详解

appendonly yes           // 启用aof持久化方式
# appendfsync always // 每收到写命令就立即强制写入磁盘,最慢的,但是保证完全的持久化,不推荐使用
appendfsync everysec // 每秒强制写入磁盘一次,性能和持久化方面做了折中,推荐
no-appendfsync-on-rewrite  yes  // 正在导出rdb快照的过程中,要不要停止同步aof
auto-aof-rewrite-percentage 100  // aof文件大小比起上次重写时的大小,增长率100%时,重写
auto-aof-rewrite-min-size 64mb   // aof文件,至少超过64M时,重写

Redis 重启时加载 AOF 和 RDB 的顺序

(1)当 AOF 和 RDB 文件同时存在时,优先加载 AOF
(2)若关闭了 AOF,加载 RDB 文件。
(3)加载 AOF/RDB 成功,redis 重启成功。
(4)AOF/RDB 存在错误,启动失败打印错误信息。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/IT__learning/article/details/121460323