redis中的AOF持久化和RDB持久化

马谦马谦马谦 Redis评论802字数 2211阅读7分22秒阅读模式

一、AOF持久化

1.1 实现机制

AOF(Append Only File)是redis持久化方式的一种,它通过把所有redis执行过的命令都写入到文件来维持持久化。一旦服务崩溃,则可以重放这些命令来恢复服务数据。

例如,在redis上执行下面2条语句:

那么AOF文件中的内容就类似是:

当然,文件中保存不是直接的命令语句。而是按照redis命令请求协议保存的,除了执行的命令以外还有一些其他的内容也会保存到文件。redis协议是redis执行命令专用的一种协议,当客户端向服务端发送请求也是使用的redis协议,AOF也使用redis协议的好处是可以直接使用redis协议解析库,不用再单独实现一套。

AOF数据并不是实时写入到文件中的,而是优先保存在缓冲区。redisServer对象中保存了一个aof_buf字段,它就是aof命令的保存缓冲区。当执行完命令后,会先把指令保存到这里,然后根据策略把缓冲区中的内容写入到磁盘。

一个要注意的是,文件写入磁盘并不会立马刷新到文件系统,因为操作系统对系统IO有缓存,缓存到达一定条件后才会同步缓存到文件系统。为了避免数据没有及时写入到文件系统(还在缓存中),AOF提供了三种策略来同步缓存:

策略 描述
always 每处理一次事件循环,就把aof文件写入到文件。这种办法最稳妥,数据丢失后的恢复效果最好。
Everysec 每秒同步一次AOF文件缓存到文件系统。
no 不主动同步缓存,由操作系统决定什么时候写入到文件系统。

1.2 AOF重写

当服务运行久了之后,AOF文件会变得很大,redis提供了AOF重写功能来优化AOF文件数据。

所做的优化就是整合指令,例如:

执行完这两个命令后,数据库保存了一个有序集合age,里面包含了两个元素world和nginx。其中hello在第一个命令中加进来了,但是第二个指令又删除了,所以实际上写入AOF文件并不需要上面两行,只需要一行就可以完成:

AOF重写就是基于这种策略来重写的,但是有一个要注意的地方是:在执行AOF写入的时候,会导致redis阻塞。所以一般建议是使用后台重写来完成整个AOF文件的重写,后台重写会新建一个子进程,避免在父进程中操作阻塞正常业务。执行后台重写的指令是BGREWRITEAOF

二、RDB持久化

RDB持久化是redis的第二种持久化方式,它持久化的原理是把数据库中所有键值对的二进制数据直接写入到文件。RDB持久化的优先级一般低于AOF持久化,因为AOF持久化的实时性高于RDB,所以在系统启动的时候如果存在AOF持久化,redis会优先通过AOF持久化恢复数据。

执行持久化的操作指令是SAVEBGSAVE,一个是前台执行,一个是后台执行。和AOF持久化一样,前台执行会阻塞当前redis进程,所有客户断请求都会被阻塞,因此一般建议是用BGSAVE,它也会新创建一个子进程来做持久化操作。RDB备份是全量备份。

可以在redis.conf中配置RDB相关的操作,主要有以下几个配置:

第一个配置是执行BGSAVE的策略,当在secnods秒之内执行了changes次操作时,会自动把改动写入到RDB文件。可以同时有多个save配置段存在,例如官方默认的配置中就有三个save配置:

这三个配置,只要在任意时间段内满足了任意一条就会执行(三者互不影响,互相独立,各自备份各自的):

  1. 900秒内执行了一次更新,BGSAVE就会执行。
  2. 300秒内执行了10次更新,BGSAVE就会执行。
  3. 60秒呢执行了10000次更新,BGSAVE就会执行。

dbfilenamedir指定了备份文件名和路径,执行后就会把RDB文件写入到这个文件中。例如,设置保存的路径为/appdata/redis/dump.rdb,执行save命令后,就会生成这个文件:

redis中的AOF持久化和RDB持久化-图片1

RDB持久化文件可以使用官方的redis-check-rdb程序(低版本叫redis-check-dump)来检测相关数据:

redis中的AOF持久化和RDB持久化-图片2

当然,这个文件只提供了基本检测功能(即验证rdb文件是否合法),并不包含导出所有数据的功能。

如果需要处理实际的数据可以通过其他工具来实现,google一下redis rdb parser就能看到了。

github上也有很多,例如https://github.com/sripathikrishnan/redis-rdb-tools

三、AOF和RDB对比

RDB持久化 AOF持久化
全量备份,一次保存整个数据库 增量备份,只保存新修改的数据
保存的间隔较长 保存的间隔默认一秒
更适合数据备份,默认开启 更适合用来保存数据,和一般SQL持久化方式一样,默认关闭
save会阻塞,但bgsave或者自动不会阻塞 无论是平时还是AOF重写,都不会阻塞
轻重 : 重 轻重: 轻
启动优先级 : 低 启动优先级 : 高
体积 : 小 体积 : 大
恢复速度 : 快 恢复速度 : 慢
数据安全性 : 丢数据 数据安全性 : 根据策略决定

表格从Redis持久化AOF和RDB对比整理得来。

 
马谦马谦马谦
  • 本文由 马谦马谦马谦 发表于 2020年2月17日21:18:10
  • 转载请务必保留本文链接:https://www.dyxmq.cn/databases/redis/redis-persistence.html
redis中的键值淘汰策略 Redis

redis中的键值淘汰策略

当使用的内存到达上限后,redis提供了6种策略来淘汰键值: 策略 描述 volatile-lru 在所有设置了过期时间的键值中根据LRU算法淘汰最近最少使用的 allkeys-lru 对数据库中所有...
redis源码分析:链表实现 Redis

redis源码分析:链表实现

一、链表定义 链表在redis中的使用十分广泛,例如列表的底层实现之一就是链表,包括发布、订阅等等功能都是有用到链表的。redis中链表在adlist.h和adlist.c中实现,只用了300+行代码...
redis中的发布和订阅 Redis

redis中的发布和订阅

一、发布和订阅 除了任务队列以外,redis还有一种基于“发布/订阅”模式的消息传递,使得客户端可以订阅某个频道,当频道有消息产生时,会把消息传递到所有的订阅者。和列表不一样的是,发布和订阅可以是一对...
Redis小案例(二):redis实现消息队列 Redis

Redis小案例(二):redis实现消息队列

一、任务队列概述 消息队列,顾名思义就是一个用来传递任务的队列。消息队列在开发中十分常见,经常用在页面后台处理需要很长时间的操作时,例如发送邮件、短信以及进行复杂数据运算操作等,这些操作通常会阻塞页面...
匿名

发表评论

匿名网友
:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:
确定

拖动滑块以完成验证