REDIS持久化相关
RDB和AOF的区别?
- RDB: REDIS DATABASE BACKUP,是二进制形式的全量保存的数据快照,缓存宕机时,会损失较多数据,但是它回复也快,RDB每次都是全量保存,开销较大
- AOF:APPEND ONLY FILE ,是文本文件形式的追加日志,缓存宕机时,如果采用everysec,最多有一秒的数据丢失,因为是文本文件,回复较慢,每秒都是写操作的附加文本文件操作,开销较小
如果RDB和AOF只能选择一个?
如果接受分钟级的数据丢失,可以用RDB;如果使用AOF,策略可以选择EVERYSEC;也可以使用中和方案混合AOF保存,官方默认的是始终开启RDB
RDB持久化的触发时机?
- 到达配置文件的阈值,配置文件中有类似于SAVE 900 1【每900s有一条写数据】这种
- 使用SAVE 主线程同步持久化
- 使用BGSAVE 子线程异步持久化
- 每一次servercron循环时
- REDIS SHUTDOWN之前
- 执行FLUSHALL【清除所有数据】之前
- 主从全量复制之前
RDB持久化过程?
- 打开临时的RDB文件
- 写入I/O缓冲区
- 写入内核缓冲区
- 刷到磁盘中的RDB临时文件
- 关闭
RDB对主流程有什么影响?
- 当执行SAVE主线程同步持久化的时候,会阻塞主线程
- 当执行BGSAVE子线程异步持久化的时候,如果数据量很大,子线程耗时过长,也可能阻塞主线程
- 写时复制,会新建一个进程从新节点开始,修改操作在新的节点上进行,保证了主节点的数据完整性,如果修改量较大,就会导致从主内存中再多拷贝一份数据,占用内存是。
AOF刷盘时机
- REDIS SHUTWODN之前
- 通过配置指令关闭AOF之前【找到 appendonly 配置项,并将其设置为 no】
- 每一次SERVERCRON事件循环的时候
AOF步骤
- 命令追加
- 文件写入到内核缓冲区
- 文件同步到磁盘
AOF刷盘策略
- ALWAYS
- EVERYSEC
- NO
描述AOF重写过程?
- 新建子进程,将DB中的数据以字符串形式写入到新的AOF文件中
- 如果有新的数据,则写入到内核重写缓冲区中
- 等到第一步子进程完成后,再将内核缓冲区中的数据传给子进程,子进程以字符串形式写入到新的AOF文件中
AOF重写有什么不足?
- 会带来额外的CPU开销,主进程需要将新数据放到AOF重写缓冲区中,也需要通过管道将重写缓冲区中的文件传给子进程,子进程然后再写入到AOF文件中
- 内存开销和磁盘凯开销,子进程写新的数据的时候,这部分数据在重写缓冲区和缓冲区中都有
如何解决AOF的不足?
- 依旧新建一个进程,不过AOF日志分为BASE-AOF和INC-AOF
- DB中的数据写入到BASE中
- 新的数据写入到INC中
AOF对主流程有什么影响?
- 当AOF很大时,REDIS就会FORK一个子线程 对AOF进行重写,合并一些相同的key操作等,这个过程会很耗时,从而阻塞主线程
- 当采用AWAYS策略时会导致写入压力很大,主线程响应变慢
- 当采用EVERYSEC时,可能上一轮从内核缓冲区刷盘的同步还没完成,下一秒就要开始了,从而发生等待。
AOF混合持久化是什么?
AOF之前的文件不管依旧是文本文件格式,新追加的文件,以RDB二进制数据文件的形式 写入到AOF中。
为什么先执行命令,再把数据写入AOF?‘’
-
好处:
- 保证正确的写入,AOF刷盘的日志都是正确的命令‘
- 不阻塞当前写操作,因为AOF写日志可能会很耗时
-
缺点:
- 可能会造成数据的丢失
AOF子进程的数据和主进程的数据不一致怎么办?
- 参考AOF的重写
- 在没有优化之前,主进程将修改的数据写入到重写缓冲区,再通过通道发送给子进程。
- 优化之后,AOF分为BASE和INC
RDB执行快照时,数据能修改吗?
可以修改,执行RDB的写时复制,会新建子节点新进程 优先在子节点上进行修改操作,保证RDB数据快照的正常复制。
Redis的过期策略
- 定时删除,比如SETEX/SETPX
- 惰性删除,不主动删除,每次访问数据库的时候删除
- 定期删除,每隔一段时间,去DB中查找过期的KEY,进行删除
REDIS官方采用惰性删除+定期删除的策略
REDIS内存淘汰策略?
-
从范围上划分:
- 在过期数据范围内淘汰
- 在全局数据内淘汰
-
从算法上划分
- 随机淘汰
- LRU LEAST RECENTLY USED 最少使用的淘汰
- LFU 频率最低的淘汰
- TTL 过期范围内生效
主从模式,怎么删除过期键
从客户端访问,依旧可以得到过期键的值,是通过AOF日志来确定的,会追加DEL指令,同步到从服务器