Redis服务器是一个键值对数据库服务器,将所有数据都保存在redisServer结构的db数组。每个redisServer代表了一个数据库,初始化时,程序根据redis.conf中配置的属性来决定创建多少个数据库,默认是16个。
一些数据库的操作
1. 切换数据库。 select 0
切换到0号数据库。
2. 添加新键。例如插入一个键值对set k1 v1/LPUSH k2 1 2 3
3. 删除键。DEL K1
4. 更新键。set k1 v2
,将k1原来的值v1改成v2
5. 对键取值。GET k1、LRANGE k2 0 -1
6. 清空当前数据库。FLUSHDB
7. 设置过期时间。EXPIRE(PEXPIRE) k1 5
8. 查看生存时间。TTL(PTTL) k1
9. 移除过期时间。PERSIST k1
- 读写键空间时的维护操作
- 读取一个键后,根据键是否存在来更新键空间命中次数和不命中次数
- 读取到键后,更新键的LRU时间。
- 如果发现键已经过期,就删除这个过期键,再进行后续操作
- 键被修改时,如果客户端使用WATCH监视了这个键,就将这个键标记为脏,表明这个键被修改。
- 如果在一定时间内对键修改了一定的次数,如300s内修改了10次,900秒内修改了1次,60秒内修改了一万次,会出发RDB文件进行持久化。
- 过期策略:Redis中是惰性删除和定期删除
- 怎么判断键是否过期?
检查键是否存在于过期字典中,如果是就取出键的过期时间。检查当前UNIX时间戳是否大于过期时间,如果是则已经过期了,否则就是没过期。 - 定时删除策略:在为键设置过期时间的同时,创建一个定时器,在定时器时间到达时就进行删除操作。
优点:定时删除策略对内存最友好,能够在过期时间到达时尽快删除键,释放内存。
缺点:对CPU时间最不友好,在过期键比较多时,删除过期键需要消耗大量CPU时间,导致CPU时间用在删除和当前无关的过期键上,影响响应时间和吞吐量。同时创建一个定时器需要用到时间事件,而时间事件的实现方式是无序链表,导致查找一个事件时间复杂度为O(N),不能高效处理。 - 惰性删除策略:放任键过期不管,但每次从键空间获取键时,都检查取得的键是否过期,如果过期就删除该键,没过期就返回这个键。
优点:对CPU友好,因为只有在取出键的时候才进行过期检查,这可以保证删除操作只有在非做不可的时候才进行,并且目标也只是当前键,不会把CPU时间花在其他无关键上。
缺点:对内存不友好,如果一个键过期了且一直没有被访问,那么就一直保留在数据库中不被删除,如果这种键的数目太多而服务器却不去释放,会导致内存泄漏。 - 定期删除策略:每隔一段时间就对数据库进行一次检查,删除里面的过期键。
**优点:**对前面两种策略的折中,每隔一段时间就执行一次删除过期键的操作,并且限制删除操作执行的时长和频率来减少删除操作的CPU时间的影响,同时也减少了因为过期键带来的内存浪费
。
缺点:对执行时间和频率难以把控,如果执行的太少或太多,与上述两种策略一样。
- 怎么判断键是否过期?
- Redis中惰性删除策略的实现
在对所有读写数据库的命令执行前,都会调用expireIfNeed函数来进行检查,如果键已经过期了,那么就将键删除,如果没过期则该函数不做动作。
- Redis中定期删除策略的实现
通过内部的activeExpireCycle函数实现,每一次运行函数,都从一定数量的数据库中取出一定数量的随机键进行检查,并删除其中的过期键。这其中有一个全局变量current_db来记录当前检查进度,随着函数的不断执行,最终所有的数据库都会被检查,这是将变量置为0表示接下来要进行新一轮的检查。 - RDB对过期键的处理
- 生成RDB文件。在执行SAVE指令或者BGSAVE命令时,会创建一个新的RDB文件,此时程序对数据库的键进行检查,已过期的键不会被保存在新创建的RDB文件。
- 载入RDB文件。如果以主服务器运行,在载入RDB文件时,程序会对文件保存的键进行检查,过期的键不会载入到数据库中,所以过期键不会对载入RDB文件的主服务器造成影响。如果以从服务器运行,则会载入全部键到数据库中,不过因为主服务器在数据同步时,从服务器的数据库会被清空,所以过期键也不会对从服务器造成影响。
- AOF对过期键的处理
- 服务器在AOF持久模式运行时,如果某个键过期且还没执行惰性删除或者定期删除,那么AOF不会因为过期键而产生影响,但是当过期键被惰性删除或定期删除时,Redis会想AOF以文件追加的方式写入一条DEL命令,来显示记录删除操作。
- 在执行AOF重写时,过期键不会被保存在重写后的AOF文件中。
- 复制对过期键的处理
服务器运行在复制模式下,从服务器的删除动作由主服务器控制,这保证了主从服务器数据的一致性
:
1. 主服务器删除一个过期键,像从服务器发送一个DEL命令,告知从服务器删除这个过期键。
2. 从服务在执行客户端发送的读命令时不会删除过期键,而是当做未过期键处理,只有接到主服务器发来的DEL命令后才会删除过期键。 - 数据库通知
键空间通知:某个键执行了什么命令。
键事件通知:某个命令被什么键执行了。