2.2AOF(文件追加)
上面已经介绍了RDB持久化是通过将某一时刻数据库的数据“快照”来实现的,下面我们来看看AOF是怎么实现的。
- AOF是通过保存Redis服务器所执行的写命令来记录数据库的数据的。
AOF原理图
比如说我们对空白的数据库执行以下写命令:
redis> SET meg "hello" OK redis> SADD fruits "apple" "banana" "cherry" (integer) 3 redis> RPUSH numbers 128 256 512 (integer) 3
Redis会产生以下内容的AOF文件:
AOF文件
这些都是以Redis的命令请求协议格式保存的。Redis协议规范(RESP)参考资料:
AOF持久化功能的实现可以分为3个步骤:
- 命令追加:命令写入aof_buf缓冲区
- 文件写入:调用flushAppendOnlyFile函数,考虑是否要将aof_buf缓冲区写入AOF文件中
- 文件同步:考虑是否将内存缓冲区的数据真正写入到硬盘
AOF持久化步骤
flushAppendOnlyFile函数的行为由服务器配置的appendfsyn选项来决定的:
appendfsync always # 每次有数据修改发生时都会写入AOF文件。 appendfsync everysec # 每秒钟同步一次,该策略为AOF的默认策略。 appendfsync no # 从不同步。高效但是数据不会被持久化。
从字面上应该就更好理解了,这里我就不细说了…
下面来看一下AOF是如何载入与数据还原的:
- 创建一个伪客户端(本地)来执行AOF的命令,直到AOF命令被全部执行完毕。
redis伪客户端载入AOF文件
2.2.1AOF重写
从前面的示例看出,我们写了三条命令,AOF文件就保存了三条命令。如果我们的命令是这样子的:
redis > RPUSH list "Java" "3y" (integer)2 redis > RPUSH list "Java3y" integer(3) redis > RPUSH list "yyy" integer(4)
同样地,AOF也会保存3条命令。我们会发现一个问题:上面的命令是可以合并起来成为1条命令的,并不需要3条。这样就可以让AOF文件的体积变得更小。
AOF重写由Redis自行触发(参数配置),也可以用BGREWRITEAOF
命令手动触发重写操作。
- 要值得说明的是:AOF重写不需要对现有的AOF文件进行任何的读取、分析。AOF重写是通过读取服务器当前数据库的数据来实现的!
比如说现在有一个Redis数据库的数据如下:
Redis数据库的数据
新的AOF文件的命令如下,没有一条是多余的!
AOF重写后的命令
2.2.2AOF后台重写
Redis将AOF重写程序放到子进程里执行(BGREWRITEAOF
命令),像BGSAVE
命令一样fork出一个子进程来完成重写AOF的操作,从而不会影响到主进程。
AOF后台重写是不会阻塞主进程接收请求的,新的写命令请求可能会导致当前数据库和重写后的AOF文件的数据不一致!
为了解决数据不一致的问题,Redis服务器设置了一个AOF重写缓冲区,这个缓存区会在服务器创建出子进程之后使用。
AOF后台重写过程
2.3RDB和AOF对过期键的策略
RDB持久化对过期键的策略:
- 执行
SAVE
或者BGSAVE
命令创建出的RDB文件,程序会对数据库中的过期键检查,已过期的键不会保存在RDB文件中。 - 载入RDB文件时,程序同样会对RDB文件中的键进行检查,过期的键会被忽略。
RDB持久化对过期键的策略:
- 如果数据库的键已过期,但还没被惰性/定期删除,AOF文件不会因为这个过期键产生任何影响(也就说会保留),当过期的键被删除了以后,会追加一条DEL命令来显示记录该键被删除了
- 重写AOF文件时,程序会对RDB文件中的键进行检查,过期的键会被忽略。
复制模式:
- 主服务器来控制从服务器统一删除过期键(保证主从服务器数据的一致性)
2.4RDB和AOF用哪个?
RDB和AOF并不互斥,它俩可以同时使用。
- RDB的优点:载入时恢复数据快、文件体积小。
- RDB的缺点:会一定程度上丢失数据(因为系统一旦在定时持久化之前出现宕机现象,此前没有来得及写入磁盘的数据都将丢失。)
- AOF的优点:丢失数据少(默认配置只丢失一秒的数据)。
- AOF的缺点:恢复数据相对较慢,文件体积大
如果Redis服务器同时开启了RDB和AOF持久化,服务器会优先使用AOF文件来还原数据(因为AOF更新频率比RDB更新频率要高,还原的数据更完善)
可能涉及到RDB和AOF的配置:
redis持久化,两种方式 1、rdb快照方式 2、aof日志方式 ----------rdb快照------------ save 900 1 save 300 10 save 60 10000 stop-writes-on-bgsave-error yes rdbcompression yes rdbchecksum yes dbfilename dump.rdb dir /var/rdb/ -----------Aof的配置----------- appendonly no # 是否打开 aof日志功能 appendfsync always #每一个命令都立即同步到aof,安全速度慢 appendfsync everysec appendfsync no 写入工作交给操作系统,由操作系统判断缓冲区大小,统一写入到aof 同步频率低,速度快 no-appendfsync-on-rewrite yes 正在导出rdb快照的时候不要写aof auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb ./bin/redis-benchmark -n 20000
官网文档:
三、最后
如果大家有更好的理解方式或者文章有错误的地方还请大家不吝在评论区留言,大家互相学习交流~~~