微信搜索【程序员囧辉】,关注这个坚持分享技术干货的程序员。
前言
本来说 Redis 分3篇,但是上周写持久化时发现持久化的内容还越多的,于是持久化就单拆一篇了。
我估计后面的主从复制、哨兵、集群内容也是不少,所以说实话,我也不知道之前说的3篇会拆成几篇了。
持久化机制的内容大纲其实很早就有了,但是实际写的时候断断续续写了有两周。
主要细节还是挺多的,在翻源码的过程中,会遇到一些疑惑点,也发现一些自己以前不知道的知识点,所以自己也要花点时间去搞清楚。
慢工出细活吧,本文还是有很多非常细节的内容的,如果能掌握,让大厂面试官眼前一亮还是问题不大的。
正文
Redis 核心主流程
AOF 和 RDB 的持久化过程中,有不少操作是在时间事件 serverCron 中被触发的。所以,这边有必要先了解下 Redis 中的事件核心流程。
Redis 的服务器进程就是一个事件循环,最重要的有两个事件:文件事件和时间事件。Redis 在服务器初始化后,会无限循环,处理产生的文件事件和时间事件。
文件事件常见的有:接受连接(accept)、读取(read)、写入(write)、关闭连接(close)等。
时间事件中常见的就是 serverCron,redis 核心流程中通常也只有这个时间事件。serverCron 默认配置下每100ms会被触发一次,在该时间事件中,会执行很多操作:清理过期键、AOF 后台重写、RDB 的 save point 的检查、将 aof_buf 内容写到磁盘上(flushAppendOnlyFile 函数)等等。
Redis 的核心主流程如下图:
相关源码在 server.c、ae.c,核心方法是:main、aeProcessEvents
Redis 的持久化机制有哪几种
RDB、AOF、混合持久化(redis4.0引入)
RDB的实现原理、优缺点
描述:类似于快照。在某个时间点,将 Redis 在内存中的数据库状态(数据库的键值对等信息)保存到磁盘里面。RDB 持久化功能生成的 RDB 文件是经过压缩的二进制文件。
命令:有两个 Redis 命令可以用于生成 RDB 文件,一个是 SAVE,另一个是 BGSAVE。
开启:使用 save point 配置,满足 save point 条件后会触发 BGSAVE 来存储一次快照,这边的 save point 检查就是在上文提到的 serverCron 中进行。
save point 格式:save <seconds> <changes>,含义是 Redis 如果在 seconds 秒内数据发生了 changes 次改变,就保存快照文件。例如 Redis 默认就配置了以下3个:
save 900 1 #900秒内有1个key发生了变化,则触发保存RDB文件
save 300 10 #300秒内有10个key发生了变化,则触发保存RDB文件
save 60 10000 #60秒内有10000个key发生了变化,则触发保存RDB文件
关闭:1)注释掉所有save point 配置可以关闭 RDB 持久化。2)在所有 save point 配置后增加:save "",该配置可以删除所有之前配置的 save point。
save ""
SAVE:生成 RDB 快照文件,但是会阻塞主进程,服务器将无法处理客户端发来的命令请求,所以通常不会直接使用该命令。
BGSAVE:fork 子进程来生成 RDB 快照文件,阻塞只会发生在 fork 子进程的时候,之后主进程可以正常处理请求,详细过程如下图: