Redis里各种数据类型怎么持久化,技术细节和方法探讨
- 问答
- 2025-12-26 17:07:35
- 3
Redis的持久化,就是把内存中的数据想办法保存到硬盘上,这样即使Redis服务重启,数据也不会丢失,Redis本身主要提供了两种机制来做这件事:RDB和AOF,需要注意的是,这两种机制持久化的对象是整个Redis数据库,而不是针对某一个特定的数据类型(比如String、List、Hash等),无论你的数据库里存的是字符串、列表还是集合,它们都会被这两种机制以各自的方式记录下来。
第一种方法:RDB(快照)
可以把RDB想象成给当前的内存数据拍一张完整的照片,Redis会在特定的时间点,将内存中所有数据生成一个二进制的快照文件(默认叫dump.rdb)保存到磁盘上。
技术细节和方法:
-
触发方式:RDB的触发有三种主要方式。
- 自动触发:这是最常用的,你可以在Redis的配置文件(redis.conf)里设置规则,save 900 1”表示在900秒内如果至少有1个键被改变,就触发一次快照,可以配置多条规则,满足任意一条就会执行。
- 手动触发:通过运行命令来触发,主要有两个命令:
SAVE和BGSAVE。SAVE命令会阻塞整个Redis服务器,在创建快照期间,Redis不能处理任何其他请求,所以线上环境基本不用。BGSAVE命令则是通过Redis创建一个子进程(fork出一个子进程)来在后台完成快照的生成工作,主进程可以继续正常提供服务,这是推荐的方式。 - 停机触发:当使用
shutdown命令正常关闭Redis服务器时,如果没有开启AOF,Redis会自动执行一个BGSAVE。
-
持久化过程:当执行
BGSAVE时,Redis主进程会fork一个子进程,这个子进程会拥有主进程此刻内存数据的一个副本,然后子进程负责将这份数据副本写入一个临时的RDB文件,写入完成后,再用这个新文件替换掉旧的RDB文件,这里有一个关键点:由于子进程是父进程的副本,所以它在持久化过程中,数据内容是开始那一刻的定格,期间主进程对数据的任何修改,子进程是“看不见”的,这保证了快照数据的一致性。 -
优点:
- 性能高:RDB文件是紧凑的二进制压缩文件,恢复大数据集时速度非常快,非常适合做灾难恢复。
- 适合备份:由于是完整的快照,可以很方便地将RDB文件拷贝到其他地方做备份。
- 对主进程影响小:
BGSAVE方式下,除了fork子进程的瞬间可能会有延迟(如果数据量非常大,fork操作本身可能耗时),之后主进程可以继续工作。
-
缺点:
- 可能丢失数据:这是最大的问题,因为快照是间隔一段时间拍的,如果Redis意外宕机,从上一次快照到宕机之间的数据修改就会全部丢失。
- fork可能阻塞:当数据集非常大时(比如几十GB),fork子进程的过程可能会消耗大量CPU时间,导致Redis服务短暂停顿(可能达到秒级)。
第二种方法:AOF(追加日志)

AOF的思路和RDB完全不同,它不像拍照,而是像写日记,Redis会把每一个会引起数据变化的写命令(比如SET、LPUSH、SADD等)记录到一个日志文件的末尾,当Redis重启时,会重新按顺序执行一遍AOF文件中的所有命令,从而重建出整个内存数据。
技术细节和方法:
-
开启与日志同步:AOF默认是关闭的,需要在配置文件中开启(appendonly yes),它涉及到日志写入磁盘的时机,有三个可配置的选项,这直接决定了数据的可靠性和性能:
- appendfsync always:每个写命令都立即同步到磁盘,这是最安全的方式,能保证数据基本不丢失(除非磁盘本身损坏),但性能也是最差的,因为每次写入都要进行磁盘IO。
- appendfsync everysec:每秒同步一次,这是一种折中方案,也是默认的推荐设置,它最多只会丢失1秒钟的数据,性能比
always好很多。 - appendfsync no:由操作系统来决定何时同步,性能最好,但丢失数据的风险最大。
-
AOF重写:由于AOF文件是不断追加的,时间长了会变得非常大,而且里面可能有很多冗余命令,比如对一个键先后执行了
set key 10和set key 20,那么第一条命令其实就是多余的,为了解决这个问题,AOF提供了重写机制,重写会创建一个新的AOF文件,这个文件包含重建当前数据集所需的最少命令序列,对于一个List,重写后可能直接用一条RPUSH命令插入所有当前元素,而不是记录成百上千条LPUSH或RPUSH命令。 -
重写触发:重写也是通过
BGREWRITEAOF命令在后台由子进程完成的,不会阻塞主进程,可以手动触发,也可以在配置文件中设置当AOF文件大小增长到一定比例时自动触发。
-
优点:
- 数据可靠性高:通过合理的
appendfsync配置(如everysec),可以将数据丢失控制在秒级,甚至不丢失。 - 可读性好:AOF文件是纯文本格式,记录了所有操作命令,便于人工理解和分析。
- 数据可靠性高:通过合理的
-
缺点:
- 文件体积大:通常AOF文件会比同数据集的RDB文件大。
- 恢复速度慢:在数据量很大时,重新执行所有命令来恢复数据会比加载RDB慢。
- 性能消耗:虽然
everysec模式影响不大,但持续的写入对IO还是有压力的。
混合持久化
由于RDB和AOF各有优缺点,Redis从4.0版本开始引入了混合持久化(在配置文件中开启aof-use-rdb-preamble yes),它的原理是:在AOF重写时,子进程不再是直接将数据转换成命令写入AOF,而是先像RDB一样,将当前内存的数据快照以RDB格式写入新的AOF文件的开头,然后再将重写缓冲区的增量写命令以AOF格式追加到文件后面,这样得到的AOF文件,前半部分是RDB格式的二进制数据,后半部分是AOF格式的文本命令。
这样做的优点是结合了两者的长处:重启恢复时,首先加载RDB部分,速度非常快,然后再重放增量AOF命令,数据完整性也很好,既保证了恢复速度,又降低了数据丢失的风险。
选择哪种持久化方式,或者是否使用混合模式,需要根据业务对数据安全性和性能的要求来权衡,如果可以容忍几分钟的数据丢失,用RDB可以获得更高的性能,如果对数据安全性要求极高,应该使用AOF的everysec或always策略,而在大多数场景下,开启混合持久化是一个比较理想的选择。
本文由革姣丽于2025-12-26发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://waw.haoid.cn/wenda/68906.html
