理解Redis持久化,RDB持久化和AOF持久化的不同处理方式
为什么需要持久化?
redis对数据的操作都是基于内存的,当遇到了进程退出、服务器宕机等意外情况,如果没有持久化机制,那么redis中的数据将会丢失无法恢复。有了持久化机制,redis在下次重启时可以利用之前持久化的文件进行数据恢复。理解和掌握redis的持久机制,对于redis的日常开发和运维都有很大帮助,也是在大厂面试经常被问到的知识点。redis支持的两种持久化机制:
- rdb:把当前数据生成快照保存在硬盘上。
- aof:记录每次对数据的操作到硬盘上。
接下来,我们详细了解一下这两种持久化机制。
欢迎关注微信公众号:万猫学社,每周一分享java技术干货。
rdb持久化
rdb(redis database)持久化是把当前redis中全部数据生成快照保存在硬盘上。rdb持久化可以手动触发,也可以自动触发。
手动触发
save
和bgsave
命令都可以手动触发rdb持久化。
save命令
执行save
命令会手动触发rdb持久化,但是save
命令会阻塞redis服务,直到rdb持久化完成。当redis服务储存大量数据时,会造成较长时间的阻塞,不建议使用。
> save ok
执行后,redis的日志中记录:
* db saved on disk
bgsave命令
执行bgsave
命令也会手动触发rdb持久化,和save
命令不同是:redis服务一般不会阻塞。redis进程会执行fork操作创建子进程,rdb持久化由子进程负责,不会阻塞redis服务进程。redis服务的阻塞只发生在fork阶段,一般情况时间很短。
> bgsave background saving started
执行后,redis的日志中记录:
* background saving started by pid 2645 * db saved on disk * rdb: 0 mb of memory used by copy-on-write * background saving terminated with success
bgsave
命令的具体流程如下图:
-
执行
bgsave
命令,redis进程先判断当前是否存在正在执行的rdb或aof子线程,如果存在就是直接结束。 - redis进程执行fork操作创建子线程,在fork操作的过程中redis进程会被阻塞。
-
redis进程fork完成后,
bgsave
命令就结束了,自此redis进程不会被阻塞,可以响应其他命令。 - 子进程根据redis进程的内存生成快照文件,并替换原有的rdb文件。
- 子进程通过信号量通知redis进程已完成。
欢迎关注微信公众号:万猫学社,每周一分享java技术干货。
自动触发
除了执行以上命令手动触发以外,redis内部可以自动触发rdb持久化。自动触发的rdb持久化都是采用bgsave
的方式,减少redis进程的阻塞。那么,在什么场景下会自动触发呢?
-
在配置文件中设置了save的相关配置,如
sava m n
,它表示在m秒内数据被修改过n次时,自动触发bgsave
操作。 -
当从节点做全量复制时,主节点会自动执行
bgsave
操作,并且把生成的rdb文件发送给从节点。 -
执行
debug reload
命令时,也会自动触发bgsave
操作。 -
执行
shutdown
命令时,如果没有开启aof持久化也会自动触发bgsave
操作。
rdb优点
rdb文件是一个紧凑的二进制压缩文件,是redis在某个时间点的全部数据快照。所以使用rdb恢复数据的速度远远比aof的快,非常适合备份、全量复制、灾难恢复等场景。
rdb缺点
每次进行bgsave
操作都要执行fork操作创建子经常,属于重量级操作,频繁执行成本过高,所以无法做到实时持久化,或者秒级持久化。
另外,由于redis版本的不断迭代,存在不同格式的rdb版本,有可能出现低版本的rdb格式无法兼容高版本rdb文件的问题。
欢迎关注微信公众号:万猫学社,每周一分享java技术干货。
aof持久化
aof(append only file)持久化是把每次写命令追加写入日志中,当需要恢复数据时重新执行aof文件中的命令就可以了。aof解决了数据持久化的实时性,也是目前主流的redis持久化方式。
aof持久化流程
aof流程如下图:
- 命令追加(append):所有写命令都会被追加到aof缓存区(aof_buf)中。
- 文件同步(sync):根据不同策略将aof缓存区同步到aof文件中。
- 文件重写(rewrite):定期对aof文件进行重写,以达到压缩的目的。
- 数据加载(load):当需要恢复数据时,重新执行aof文件中的命令。
文件同步策略
aof持久化流程中的文件同步有以下几个策略:
- always:每次写入缓存区都要同步到aof文件中,硬盘的操作比较慢,限制了redis高并发,不建议配置。
- no:每次写入缓存区后不进行同步,同步到aof文件的操作由操作系统负责,每次同步aof文件的周期不可控,而且增大了每次同步的硬盘的数据量。
- eversec:每次写入缓存区后,由专门的线程每秒钟同步一次,做到了兼顾性能和数据安全。是建议的同步策略,也是默认的策略。
触发文件重写
aof持久化流程中的文件重写可以手动触发,也可以自动触发。
-
手动触发:使用
bgrewriteaof
命令。 - 自动触发:根据auto-aof-rewrite-min-size和auto-aof-rewrite-percentage配置确定自动触发的时机。auto-aof-rewrite-min-size表示运行aof重写时文件大小的最小值,默认为64mb;auto-aof-rewrite-percentage表示当前aof文件大小和上一次重写后aof文件大小的比值的最小值,默认为100。只用前两者同时超过时才会自动触发文件重写。
aof持久化配置
对aof持久化的具体流程有了了解后,我们来看一下如何配置aof。aof持久化默认是不开启的,需要修改配置文件,如:
# appendonly改为yes,开启aof appendonly yes # aof文件的名字 appendfilename "appendonly.aof" # aof文件的写入方式 # everysec 每个一秒将缓存区内容写入文件 默认开启的写入方式 appendfsync everysec # 运行aof重写时aof文件大小的增长率的最小值 auto-aof-rewrite-percentage 100 # 运行aof重写时文件大小的最小值 auto-aof-rewrite-min-size 64mb
原文来自:https://www.cnblogs.com/heihaozi/p/12866948.html