上篇文章:Reids命令原理与应用3 - Redis 主线程,辅助线程与存储原理-CSDN博客
个人代码仓库:橘子真甜 (yzc-YZC) - Gitee.com
目录
[一. Redis淘汰策略](#一. Redis淘汰策略)
[1.1 设置过期key](#1.1 设置过期key)
[1.2 设置全部key](#1.2 设置全部key)
[1.3 禁止淘汰](#1.3 禁止淘汰)
[二. Redis持久化](#二. Redis持久化)
[2.1 rdb持久化](#2.1 rdb持久化)
[2.2 aof持久化](#2.2 aof持久化)
[a aof原理](#a aof原理)
[b aof 重写](#b aof 重写)
[c rdb-aof混合策略](#c rdb-aof混合策略)
[2.3 两种持久化优缺点](#2.3 两种持久化优缺点)
一. Redis淘汰策略
redis是内存数据库,如果键值对过多,需要淘汰部分键值。通过expire/pexpire可以淘汰键值,根据redisobjext中的一个lru时间字段来淘汰。
1.1 设置过期key
这种策略只会淘汰过期的key。我们可以设置的策略有:
volatile-lru:最近最久未使用
volatile-lfu:最不经常使用
volatile-ttl:设置过期时间
volatile-random:随机淘汰
1.2 设置全部key
这种策略会针对全部的key
allkeys-lru:最近最久未使用
allkeys-lfu:最不经常使用
allkeys-random:随机淘汰
1.3 禁止淘汰
这种策略不会淘汰任何一个字段
no-eviction
二. Redis持久化
redis是内存数据库,为了重新启动可以保留之前的数据。需要持久化
redis持久化有两种:rdb持久化和aof持久化
2.1 rdb持久化
rdb持久化是存储的是数据结构中的二进制数据,占用空间少,恢复快。
rdb持久化是通过fork子进程来实现的,fork子进程后,由于读时共享,写时拷贝保证子进程高效读取数据同时不会影响父进程。
为何要fork?
fork读时共享机制保证redis的效率较高,不会阻塞父进程
这种策略有什么缺点?
如果在fork持久化数据期间,我们的父进程进行了数据写操作。会导致数据丢失
2.2 aof持久化
a aof原理
由于rdb持久化会导致一定的数据不一致问题,redis引用了aof持久化。
aof持久化是由辅助线程 bio_aof_async 异步刷盘实现的。aof持久化记录的是对数据的写操作命令和select/multi等命令。恢复的时候根据命令来恢复。
这样能够保证数据丢失较少,不过aof文化占用内存较大,恢复速度较慢
aof针对时机也有不同的策略,一般有两种:
1 always表示每一次命令都会进行aof持久化,由主线程直接执行。这种效率较低,使用较少
2 every_sec表示每一秒由bio_aof_async异步持久化。aof使用这种策略较多
b aof 重写
由于aof会记录所有对数据的写命令,文件较大,而且会有很多冗余数据。比如我们对一个数据进行多次修改,这些命令不用全部保存,只记录最后一个即可。有些数据被删除了,不需要记录这些删除命令。
为了减少数据量,提高恢复速度。aof设置了一个 aof-rewrite机制
aof-rewrite:借鉴rdb策略,通过fork子进程来重写。会根据内存中的数据直接生成新aof文件,避免同一个数据的历史数据冗余。
aof重写期间,新数据到达或者修改会保存到重写缓冲区,aof结束后直接添加到新aof文件的末尾。最后将新aof文件替换原始的aof文件。
这样就能减少aof文件的大小,提高恢复速度,同时保证数据丢失较少。
c rdb-aof混合策略
如果同时使用aof和rdb策略,各自的实现是独立的。不过rdb运行时候会推迟aof的重写,aof重写也会退出rdb运行。
此时aof重写也会发生变化,不再针对内存数据进行获取写命令操作。而是直接将reb快照数据作为持久化数据记录到新aof文件中。此时如果有新写命令会直接写到重写缓冲区,最后添加到aof文件的末尾。
2.3 两种持久化优缺点
|----|-------------------|--------------|
| | aof | rdb |
| 优点 | 辅助进程开销小,记录命令数据丢失少 | 持久化文件小,速度恢复快 |
| 缺点 | 文件较大,恢复速度慢 | 子进程开销大,数据丢失多 |