本文以 Redis 5.0.7 为准。
基本概念
Redis 是开源的(BSD 协议)内存数据存储。
以 KV 的方式存储数据。
key 类型固定为 string,value 支持的类型有:
- string
- list
- set
- zset
- hashtable
淘汰策略
- volatile-lru:从已设置过期的数据集中挑选最近最少使用的淘汰
- volatile-lfu:从已设置过期的数据集中挑选使用频率最少的淘汰
- volatile-ttl:从已设置过期的数据集中挑选将要过期的数据淘汰
- volatile-random:从已设置过期的数据集中任意挑选数据淘汰
- allkeys-lru:从数据集中挑选最近最少使用的数据淘汰
- allkeys-lfu:从数据集中挑选使用频率最少的淘汰
- allkeys-random:从数据集中随机挑选数据淘汰
- noenviction:不淘汰
持久化
RDB
定期将数据全量保存到磁盘。
保存的文件名默认为 dump.rdb,所在目录默认为 %REDIS_HOME%/etc。
文件名和所在目录均可配。
#x秒内如果有超过y个key被修改则发起保存快照
save x y
#900秒内如果有超过1个key被修改则发起保存快照
save 900 1
#300秒内如果有超过10个key被修改则发起保存快照
save 300 10
#60秒内如果有超过1000个key被修改则发起保存快照
save 60 10000
AOF
记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集。 AOF 文件中的命令全部以 Redis 协议的格式来保存,新命令会被追加到文件的末尾。
这种方式也可能丢数据:程序将记录写入文件,但操作系统实际上是将修改保存到了缓冲区,还没来得及同步到磁盘。
#启用AOF
appendonly yes
# always - 每次有新命令追加到 AOF 文件时就调用 fsync
# everysec - 每秒调用一次 fsync
# no - 从不调用 fsnyc,即交给操作系统去同步
# 这三种方式,可靠性递减,性能递增
appendfsync always
事务
MULTI 开启一个事务。当客户端发出了MULTI 命令时,客户端和服务端的连接就进入了一个事务上下文的状态。MULTI 执行之后, 客户端可以继续向服务器发送任意多条命令, 这些命令不会立即被执行, 而是被放到一个队列中, 当 EXEC 命令被调用时, 所有队列中的命令才会被执行。
EXEC 顺序执行事务队列中的命令。
192.168.2.129:6379> multi
OK
192.168.2.129:6379> set name "zhangsan"
QUEUED
192.168.2.129:6379> set age 20
QUEUED
192.168.2.129:6379> exec
1) OK
2) OK
192.168.2.129:6379> keys *
1) "age"
2) "name"
DISCARD 取消事务。当执行 DISCARD 命令时, 事务会被放弃, 事务队列会被清空, 并且客户端会从事务状态中退出。
192.168.2.129:6379> multi
OK
192.168.2.129:6379> set name2 "lisi"
QUEUED
192.168.2.129:6379> set age 22
QUEUED
192.168.2.129:6379> discard
OK
192.168.2.129:6379> exec
(error) ERR EXEC without MULTI
发布订阅
Redis的发布以及订阅有点类似于聊天,是一种消息通信模式。在这个模式中,发送者(发送信息的客户端)不是将信息直接发送给特定的接收者(接收信息的客户端), 而是将信息发送给频道(channel), 然后由频道将信息转发给所有对这个频道感兴趣的订阅者。SUBSCRIBE 、 UNSUBSCRIBE 和 PUBLISH 三个命令实现了消息的发布与订阅。如下
Client1发布频道mychannel与消息
192.168.2.129:6379> publish mychannel "message from channel1"
(integer) 1
Client2 订阅频道mychannel并接受Client1通过频道发过来的消息
192.168.2.129:6379> subscribe mychannel
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "mychannel"
3) (integer) 1
1) "message"
2) "mychannel"
3) "message from channel1"
延迟队列
运用 zset 实现
zset 的成员为事件的编号,score 为时间或时间戳(视情况)
周期性地扫描 zset,取出执行时间小于等于当前时间的任务。