redis持久化
总阅读次
文章目录
Redis持久化
RDB持久化方案
在Redis运行时,RDB程序将当前内存中的数据库快照保存到磁盘中,当Redis需要重启时,RDB程序会通过重载RDB文件来还原数据库。
RDB主要包括两个功能:
- 保存(rdSave)
rdSave负责将内存中的数据库数据以RDB格式保存到磁盘中,如果RDB文件已经存在将会替换已有的RDB文件。保存RDB文件期间会阻塞主进程,这段时间期间将不能处理新的客户端请求,直到保存完成为止。
为避免主进程阻塞,Redis提供了rdbSaveBackground函数。
在新建的子进程中调用rdSave,保存完成后会向主进程发送信号,同时进程可以继续处理新的客户端请求。 - 读取(rdbLoad)
当Redis启动时,会根据配置的持久化模式,决定是否读取RDB文件,并将其中的对象保存到内存中。载入RDB过程中,
每载入1000个键就处理一次已经等待处理的客户端请求,但是目前仅处理订阅功能的命令,其他一律返回错误信息,因为发布订阅功能是不写入数据库的,也就不保存Redis数据库的
RDB的缺点
要理解RDB的缺点,需要了解RDB有保存点的概念。在默认的redis.conf中可以看到如下的默认配置:123save 900 1 #如果15分钟内,有1个键被修改save 300 10 #如果6分钟内,有10个键被修改save 60 10000 #如果60秒内有10000个键被修改
上面表示只要满足任意一个条件时,将会进行快照保存。为了保证IO读写性能不会成为Redis的瓶颈,一般都会创建一个比较大的值作为保存点,会出现如下缺点:
- 此时如果保存点设置过大,就会导致宕机丢失的数据过多。保存点设置过小,又会造成IO瓶颈
- 当对数据进行保存时,可能会由于数据集过大导致操作耗时,这会导致Redis可能在短时间内无法处理客户端请求。
AOF持久化方案
以协议文本的方式,将所有对数据库进行写入命令记录到AOF文件,达到记录数据库状态的目的。
AOF功能:
- 保存
1.将客户端请求的命令转换成网络协议格式
2.将协议内容字符串追加到变量server.aof_buf中
3.当AOF系统达到设定的条件时,会调用aof_fsync(文件描述符)将数据写入磁盘
- 读取
1.创建模拟的客户端
2.读取AOF保存的文本,还原数据为原命令和原参数。然后使用模拟的客户端发出这个命令请求
3.继续执行第二步,直到读取完AOF文件
AOF系统设定条件:
- 在前面提到的AOF系统到达设定条件时,将会调用aof_fsync(文件描述符)将数据写入磁盘,这是AOF性能的关键点。目前Redis支持三种保存条件机制:
1.AOF_FSYNC_NO:不保存
此模式下,每执行一条客户端命令,都会将协议字符串追加到server.aof_buf中,但是不会执行写入磁盘。写入磁盘只发生在:redis被正常关闭、AOF功能关闭、系统写缓存已满或后台定时保存操作被执行,此三种情况都会阻塞主进程,导致客户端请求失败。
2.AOF_FSYNC_EVERYSECS:每一秒保存一次
由后台子进程调用写入保存,不会阻塞主进程。如果发生宕机,那么最大丢失数据会在2s以内的数据。这也是默认的设置选项
3.AOF_FSYNC_ALWAYS:每执行一个命令都保存一次
这种模式下,可以保证每一条客户端指令都被保存,保证数据不会丢失。但缺点是性能大大下降,因为每一次操作都是都独占性的,需要阻塞主进程
AOF缺点
- AOF文件通常会大于等于相同数据集的RDB文件
- AOF模式下性能与RDB模式性能高低,主要取决于AOF选用的fsync模式
AOF重写
AOF需要将所有的命令都保存到磁盘,那么这个文件会随着时间变得越来越大,读取也会变得很慢。
Redis提供了AOF重写机制,帮助减少文件的大小,具体实现如下:1LPUSH list 1 2 3 4 5
|
|
|
|
|
|
最初保存到AOF文件的将会是四条指令。但是经过AOF重写后,会变成一条指令:1LPUSH 1 3 4 5
AOF重写流程,主线程,子线程的工作:
- 主线程创建子线程,执行AOF文件重写
- 将子线程在执行写操作过程中的执行命令追加到AOF缓冲区和AOF重写缓冲区
- 当子线程完成AOF重写工作后,它会向主线程发送一个信号,主线程接收到该信号,会调用一个信号处理函数,并执行下面工作
- 将AOF重写缓冲区中的所有内容写入到新AOF文件中,这时新AOF文件所保存的数据库状态将和服务器当前的数据库状态一致
- 将新的AOF文件进行改名,原子地覆盖现有的AOF文件,完成新旧两个AOF文件的替换
- 这个信号处理函数执行完毕后,父进程可以继续接受请求命令
AOF重写过程,图表式:
时间 | 服务器进程(主进程) | 子进程 |
---|---|---|
T1 | 执行命令 set k1 v1 | |
T2 | 执行命令set k1 v2 | |
T3 | 执行命令set k1 v3 | |
T4 | 创建子进程,执行AOF文件重写 | 开始AOF文件重写 |
T5 | 执行命令set k2 10086 | 执行重写操作 |
T6 | 执行命令set k3 12345 | 执行重写操作 |
T7 | 执行命令set k4 23423 | 完成AOF文件重写,向父进程发送信号 |
T8 | 接收到子进程发来的信号,将命令set k2 10086、set k3 12345、set k4 22222追加到新AOF文件的末尾 | |
T9 | 用新的AOF文件覆盖旧AOF文件 |
Redis Server端持久化部分操作图解