一、数据库
-
redis的key过期时间设置:EXPIRE设置ttl秒,PEXPIRE设置ttl毫秒,EXPIREAT设置过期时间戳秒,PEXPIREAT设置过期时间戳毫秒。
-
保存过期时间:redis过期时间存放于expires字典中,其中都是转为PEXPIREAT命令存储的。
-
删除过期时间:PERSIST key
-
过期键删除策略:redis采用惰性删除+定期删除
-
定时删除:设置过期时间的同时,创建定时器,定时器在键过期时立即执行删除操作(内存友好,但CPU不友好,暂未实现)
-
惰性删除:获取key时,哦按段是否过期,过期则删除。
-
定期删除:每隔一段时间,对数据库检查一次,删除过期键。
-
-
惰性删除如下:

-
定期删除如下:

5.
过期键在RDB、AOF、复制中的处理
RDB中的过期键处理:
-
SAVE或BGSAVE创建RDB,不会将过期key保存到RDB文件中。
-
master载入RDB文件,会过滤掉过期的key;slave载入RDB文件,全部载入,不过滤过期key。
AOF中的过期键处理:
-
保存时不做任何处理。
-
在惰性删除或者定期删除时,会在AOF文件追加删除命令。
-
BGREWRITEAOF重写时,会检查过期key,过期的key不会写到AOF中。
复制模式过期键处理:
-
从服务器不处理过期key,而是等主服务器发送DEL命令。
-
GET key访问从服务器,key过期,依然返回key的值。
6.
数据库通知
notify-keyspace-event:
-
AKE:键空间通知、键事件通知
-
AK:键空间通知
-
AE:键事件通知
-
K$:和字符串键有关的键空间通知
-
E1:和列表键有关的键事件通知
二、RDB持久化
-
RDB文件的创建与载入
-
创建:SAVE BGSAVE
-
载入:开启了AOF,优先使用AOF恢复;否则使用RDB恢复。
-
-
自动间隔性保存
-
save 900 1 、save 300 10 、 save 60 10000,900秒之内至少1次修改,300秒内至少10次修改,60秒内至少10000次修改,满足其一自动执行BGSAVE
-
dirty计数器与lastsave属性
-
dirty:上次SAVE后多少次修改
-
lastsave:上一次SAVE的时间
-
-
-
RDB文件结构
-
REDIS|db_version|databases|EOF|check_sum,例如”REDIS”|”0006”|EOF|2826376271
-
REDIS就是常量REDIS五个字符
-
db_version一个整数,版本号,例如0006
-
databases一个或多个数据库,也可为空,结构SELECTDB|db_number|key_value_pairs
-
SELECTDB:常量
-
db_number:数据库号,用于SELECT db_number切换数据库
-
key_value_pairs:EXOIRETIME_MS|ms|TYPE|key|value,在开启压缩后,大于20字节的字符串value对象会被压缩。
-
-
EOF1字节,代表文件正文内容结束
-
check_sum8字节,校验和
-
-
分析RDB文件
-
R E D I S 0 0 0 6 377 334 263 C 360 Z 334 362 V
-
R E D I S 常量;0006 版本;337 EOF常量;334 263 C 360 Z 334 362 V:8字节校验和。
-
-
R E D I S 0 0 0 6 376 \0 \0 003 M S G 005 H E L L O 337 207 Z = 304 F T L 343
-
R E D I S 常量;0006 版本;336 SELECTDB常量;\0 数据库号;\0 TYPE常量;003 key长度;MSG key值;005 value长度;HELLO value值;337 EOF常量;207 Z = 304 F T L 343 8字节校验和。
-
-
-
三、AOF持久化
-
AOF持久化实现:命令追加、文件写入、文件同步
-
命令追加:服务器执行完一个命令,会将该命令追加到aof_buf缓冲区。
-
文件写入与同步:Redis运行一个循环,会将aof_buf的内容写入文件,并判断是否需要同步文件,参数appendfsync设置。
-
写入与同步:操作系统写入文件并不是直接写入文件,而是写入缓冲区,待达到一定量或者时间或者主动同步,才会真正写入文件。
-
always:每次写入后同步AOF文件。
-
everysec:每次写入后判断上次同步距离时间,超过1s则执行AOF文件同步。
-
no:每次写完后不同步,等待操作系统自己同步。
-
-
-
AOF文件的载入与数据还原
-
读取AOF文件还原数据库
-
创建一个伪客户端
-
从AOF文件读取一条命令
-
使用伪客户端执行命令
-
重复2、3直到AOF的所有命令均执行完毕
-
-
-
AOF重写(文件过大,重写会大大减少文件的大小)aof_write
-
创建一个新的AOF文件
-
以当前数据库状态为准,生成命令并写入AOF文件
-
命令过长,则拆分,依赖参数REDIS_AOF_REWRITEITEMS_PER_CMD,最大64的元素。
-
后台重写:BGREWRITEAOF,使用子进程处理AOF重写,父进程可以继续处理命令请求,子进程拥有服务器进程的数据副本,避免锁。
-
开启子进程处理AOF同时,也开启一个AOF重写缓冲区,当AOF重写完毕后,会将AOF重写缓冲区的内容写到新的AOF文件,然后重命名替换老的AOF文件。
-
四、事件
-
文件事件
1. 处理器构成,如图

2. I/O多路复用实现:底层使用select、epoll、evport、kqueue实现。
3.常见文件处理器
1.连接应答处理器
2.命令请求处理器
3.命令回复处理器
一次完整的事件:
-
-
Redis服务器正常运行,服务器的监听套接字的AE_READABLE事件处于监听下,并对应连接应答处理器;
-
当一个Redis客户端像服务器发起连接,监听套接字将产生AE_READABLE事件,触发连接应答处理器执行,处理器会对客户端应答,并创建客户端套接字、客户端状态,并将客户端套接字的AE_READABLE事件与命令请求处理器关联;
-
客户端向服务器发送命令请求,客户端套接字产生AE_READABLE事件,触发命令请求处理器执行,执行命令产生命令回复,服务器将客户端套接字的AE_WRITABLE事件与命令回复处理器关联;
-
客户端读取命令回复时,客户端套接字产生AE_WRITABLE事件,触发命令回复执行,将命令回复写入套接字,删除客户端套接字的AE_WRITABLE与命令回复处理器的关联。
-
-
时间事件(定时事件与周期事件)
五、客户端
PUBSUB与SCRIPT LOAD命令会导致数据库状态或者客户端状态变化,所以也会写入AOF文件。
六、服务端
命令执行器:
-
查找命令的实现:命令表查找
-
执行预备操作:检查cmd指针、参数、身份验证、内存占用、BGSAVE、订阅模式判断、是否正在载入数据、客户端是否阻塞与lua、是否开启了事务、是否有监视器
-
调用命令实现函数
-
执行后续工作:慢查询日志记录、cmd命令计数器修改calls、AOF缓冲、slave复制
-
回复客户端