Redis单机数据库 - ZhenLinTechnologySalon/- GitHub Wiki
Redis单机数据库
服务器中数据库与数据库选择
Redis服务器将所有数据库都保存在服务器状态redisServer结构中的db数组中, db数组中每一个项都是一个redisDb结构,代表一个数据库
redisServer结构中有个dbnum属性默认值16,在服务器初始化的时候决定创建多少个数据库。
客户端状态redisClient结构的db属性记录客户端当前目标数据库,是一个指向当前数据库的指针。 也就是说redisClient.db指针指向redisServer.db数组中的一个元素,如下图:
通过select [index] 命令可以改变目标数据库,让redisClient.db指针指向不同的目标数据库
数据库键空间
我们知道,Redis是一个键值对数据库服务器,每一个键值对,实际存放在redisDb结构中的dict字典中,我们将此字典称为键空间。 键空间和用户所见的数据库是对应的:
- 键空间的键就是数据库的键,每个键都是一个字符串对象
- 键空间的值就是数据库的值,每一个值可能是一个字符串对象、列表对象、哈希表对象、集合对象、有序集合对象
例子:
redis>set message "hello world"
OK
redis>rpush alphabet "a" "b" "c"
(integer)3
redis>hset book name "Redis in Action"
(integer)1
redis>hset book author "Josiah L . Carlson"
(integer)1
redis>hset book publisher "Manning"
(integer)1
这些命令执行完后,数据库键空间如图:
所以,对数据库添加一个键值对,删除一个键值对,都是对数据库键空间的操作。
设置过期时间
命令 | 用处 |
---|---|
expire | 将key生存时间设置为ttl秒 |
pexpire | 将key生存时间设置为ttl毫秒 |
expireat | 将key生存时间设置为指定的秒数时间戳 |
pexpireat | 将key生存时间设置为指定的毫秒数时间戳 |
上三个命令在底层最终转化成pexpireat来执行
redisDb结构中expires字典保存了数据库所有键的过期时间。这个字典就是过期字典
- 过期字典的键是一个指针,指向键空间的某个键
- 过期字典的值是一个long类型的整数----毫秒精度的UNIX时间戳
通过过期字典,检查给定键是否在过期字典中,如果在,取得过期时间检查是否超过当前时间,来判定该键是否过期。
过期键删除策略
定时删除
定期删除就是每隔一段时间执行删除过期键的操作,服务器根据情况,合理配置删除操作的时长和频率
定期删除依靠 activeExpireCycle,当redis周期性操作serverCron 函数执行时,就会调用activeExpireCycle ,在规定时间内遍历服务器的各个数据库,在过期字典中随机检查一部分键的过期时间并删除其中过期键。
惰性删除
惰性删除就是在取值时再检查是否过期并删除,惰性删除对cpu是最友好的,但是会造成内存浪费的情况。
惰性删除依靠 expireIfNeeded,所有读写数据库的命令之前都会调用expireIfNeeded,犹如一个过滤器
- 如果输入键已过期,则删除
- 如果输入键未过期,不做操作
AOF,RDB和复制功能对过期键的处理
生成rdb文件
在执行save命令或bgsave时会创建一个新的rdb文件,过期键不会保存到新的rdb文件中。
载入rdb文件
启动redis服务器时,如果开启了rdb功能,将会载入rdb文件:
- 如果服务器以主服务器模式运行,程序检查rdb中的键,只有未过期的键加载进数据库。
- 如果服务器以从服务器模式运行,载入rdb文件中,会载入所有键,但是主从同步时,还是会删除过期键。
AOF文件写入
在过期键被惰性删除或定期删除后,AOF会追加一条del命令,显示记录该键被删除。
AOF重写
和生成rdb文件类型,重写时会对过期键进行检查,已过期的键不会加入到重写后的AOF文件中去。
复制
服务器运行在复制模式下时,从服务器的过期键删除由主服务器控制:
- 主服务器删除一个键的时候,会显式的向所有服务器发送一个del命令;
- 从服务器在执行客户端发送的读命令时,即是碰到过期键也不会删除;
- 从服务器只有在接到主服务器的del命令时,才删除 通过由主服务器控制服务器统一删除,保证主从服务器的一致性。
数据库通知
//待补充