个人学习redis的笔记和摘抄,主要来自《Reids设计与实现》一书
Ch9-数据库
数据库概念
服务器中有一个指向redisDb的数组,默认大小是16,即默认创建16个数据库
每个redis客户端都有自己的目标数据库,可以通过SELECT命令切换
键空间
redisDb结构中有一个dict保存了数据库中的所有键值对,键string对象,值可以是5种对象类型。
对数据库的CRUD操作即发生在这个dict上面,还支持FLUSHDB(清空数据库)、RANDOMKEY、DBSIZE、EXISTS、RENAME、KEYS等操作
过期KEY
设置
-
通过EXPIRE或者PEXPIRE设置剩余生存时间
-
通过ExpireAt或者PExpireAt设置过期时间
-
E精确到秒,P精确到毫秒,最终否是通过转换到PExpireAt命令来实现的
移除
- 通过PERSIST移除键的过期时间
查看
- 通过TTL、PTTL查看剩余过期时间
实现
redisDb结构中的expires字典保存了数据库中所有键的过期时间,值是毫秒精度的unix时间戳
redis采用惰性删除和定时删除两种策略,在合理使用CPU时间和内存浪费取得平衡
- 惰性删除:所有读写命令在执行之前都会调用expireIfNeeded进行检查,若已经过期则删除,未过期则继续执行
- 定时删除:在服务器周期事件serverCron执行时,会去调用检查函数,在规定时间内遍历数据库,通过expires字典检查一部分过期键,超时返回并记录检查位置下次继续执行
Ch10-RDB持久化
redis是内存型数据库,进程退出数据消失,有RDB和AOF两种持久化方案
RDB是保存数据库快照,AOF(Append Only File)是保存命令
RDB文件的创建和载入
SAVE和BGSAVE命令用于生成RDB文件
- SAVE会阻塞服务器进程直到创建完成,期间服务器不能处理命令
- BGSAVE会派生出一个子进程(在子进程内存上操作),由子进程复制创建RDB文件,父进程继续处理命令请求
服务器在载入RDB文件时会一直阻塞,直到载入完成
自动间隔保存
可以通过设置让服务每隔一段时间自动执行一次BGSAVE命令
服务器记录上次save时间和自上次修改次数,在severCron函数执行时会检查是否有满足条件的配置(如30s内修改超过100次),满足则执行BGSAVE
Ch11-AOF持久化
AOF持久化是通过保存所执行的写命令来记录数据库状态的
实现
- 命令追加:将服务器的写命令追加到aof_buf缓冲区末尾
- 文件写入:在结束一次事件循环后,服务器会考虑是否将缓冲区中的内容写入地AOF文件中
- 文件同步:有三种同步选项可配置
- always:写入并同步到AOF文件
- everysec:写入,如果上次同步操作超过一秒钟,那么在此将AOF文件同步
- no:写入,但不对AOF文件同步,何时同步由操作系统决定
- 同步是指是否强制将内存缓存区的内容写入到磁盘,这个操作会影响到AOF的效率和安全性,同步时间过长可能会丢失较长时间的数据,同步时间过短会影响服务器效率
AOF载入
创建一个不带网络连接的伪客户端,将AOF文件中的命令执行
AOF重写
解决AOF文件冗余,多次对同一对象操作会存在大量浪费空间的冗余命令。产生一个新的AOF文件,体积更小
原理:
- 从数据库中读取键现在的值,然后用一条命令去记录键值对,代替之前记录这个键值对的多条命令
实现:
- 创建子进程进行AOF重写,父进程继续处理命令请求,将写命令写入AOF缓冲区和AOF重写缓冲区
- 子进程重写完成后,父进程将AOF重写缓存区的命令写入AOF文件,并原子地覆盖旧的AOF文件
Ch12-事件
Redis服务器是一个事件驱动程序,处理文件事件和时间事件
- 文件事件:与客户端(或其他服务器)通过套接字进行连接,文件事件就是对套接字事件的抽象
- 时间事件:serverCron函数
文件事件
文件事件处理器使用I/O多路复用来监听多个套接字,并为不同套接字关联不同的事件处理器。
文件事件处理器单线程运行,设计的简单性
时间事件
目前一般情况下,只有serverCron函数一个时间事件,主要工作包括:
- 更新服务器各类统计信息,时间、内存占用等
- 清理过期键
- 尝试AOF或RDB持久化
- 主服务器与从同步
- 集群同步和连接测试
默认每秒运行10次,平均间隔100ms
事件的调度和执行
文件事件和时间事件是合作关系,服务器会轮流处理这两种事件,并且处理事件的过程中也不会出现抢占
Ch13/14 客户端、服务器
客户端
几个比较关键的属性值:
- 正在使用的套接字描述符
- flags客户端状态信息
- 输入缓冲区
- 输出缓冲区(定长和可变两种)
服务器
了解性质,主要讲了3个方面:
- 处理命令的过程
- severCron函数
- 服务器的启动过程