当前位置:首页 > 问答 > 正文

Redis硬盘持久化那点事,数据安全和可靠存储怎么搞才靠谱

Redis虽然以速度快著称,但它的数据都放在内存里,内存一断电,数据就全没了,把内存里的数据想办法存到硬盘上,这个过程就叫“持久化”,这就像是给内存这个“工作台”拍个快照或者记个流水账,万一工作台被清空了,我们还能从快照或流水账里恢复过来。

Redis主要提供了两种方法来“拍快照”和“记流水账”,分别是RDB和AOF,咱们一个一个说。

RDB:定时拍个快照

RDB的方式很简单,就是在特定的时间点,把当前内存里完整的数据集生成一个快照文件(一个.rdb结尾的文件),然后存到硬盘上,你可以自己设定拍快照的规则,900秒内至少有1个键被改变”就拍一次,或者“300秒内至少有10个键被改变”拍一次。

  • 优点:

    Redis硬盘持久化那点事,数据安全和可靠存储怎么搞才靠谱

    1. 恢复速度快: RDB文件是一个紧凑的二进制文件,里面就是某个时刻的全部数据,当Redis重启时,直接把这个文件读回内存就行了,速度非常快,这对于数据量很大,但追求快速重启恢复的场景非常合适。
    2. 适合备份: 因为就是一个单独的文件,你可以很方便地把这个文件拷贝到别的地方,比如另一台服务器或者云存储上,做灾难备份,每天定时生成一个RDB文件,就等于有了一个每日的数据备份。
    3. 对性能影响小: Redis会通过fork一个子进程来干生成RDB文件的活儿,这个子进程几乎不会影响主进程处理客户端的命令(除了fork瞬间可能有的延迟),所以持久化过程对Redis本身的读写性能影响相对较小。
  • 缺点:

    1. 可能丢失的数据多: 这是RDB最大的问题,因为它是定时拍快照,如果Redis意外宕机了,那么从上一次拍快照到宕机这个时间间隔内,所有写入的数据就全都丢了,比如你设置5分钟拍一次,结果在第4分59秒的时候断电了,那这5分钟内的数据就没了,数据可靠性不够高。
    2. fork可能阻塞服务: 当数据量特别大的时候(比如几十个GB),fork子进程这个过程可能会消耗较多CPU,并且导致主进程短暂停顿(卡一下),如果硬件性能跟不上,这个卡顿会很明显。

AOF:记录每一次操作

AOF的思路和RDB完全不同,它不拍整体快照,而是把Redis服务器执行的所有写命令(比如set, hset, lpush等)一条一条记录下来,追加到一个日志文件的末尾(一个.aof结尾的文件),当Redis重启时,它会把这个日志文件里的命令从头到尾再执行一遍,通过“重放”来重建数据。

  • 优点:

    Redis硬盘持久化那点事,数据安全和可靠存储怎么搞才靠谱

    1. 数据可靠性极高: 这是AOF最大的优势,你可以配置AOF的同步策略,如果设置为“每执行一个写命令就同步一次硬盘”(appendfsync always),那么即使宕机,也最多只丢失一个命令的数据,这几乎是金融级别的数据安全要求了,即使是设置为每秒同步一次(appendfsync everysec),也最多丢失1秒的数据,比RDB要安全得多。
    2. 可读性好: AOF文件是纯文本格式,记录的是原始的Redis命令(后来也有混合格式,但本质可读),如果你不小心用flushall命令删光了所有数据,只要AOF文件还没被重写,你还可以手动编辑这个文件,删掉最后那条错误的flushall命令,然后恢复数据,有“后悔药”可以吃。
  • 缺点:

    1. 文件体积大: AOF文件通常会比RDB文件大很多,因为RDB是某一时刻的数据全集,而AOF是持续增长的操作记录,比如你对一个键值对修改了100次,RDB文件里只存最终的值,但AOF文件里会记录100条命令。
    2. 恢复速度慢: 因为恢复数据需要重新执行所有命令,当数据量很大时,这个恢复过程会比加载RDB文件慢很多。
    3. 对性能有一定影响: 虽然通常配置为每秒同步一次,但对硬盘IO的压力还是比RDB大,而且在AOF文件太大时,Redis需要对其进行重写(rewrite)来压缩体积,这个重写过程也和RDB一样会fork子进程,可能引起延迟。

怎么搞才靠谱?混合使用才是王道

看到这里你可能会纠结,RDB怕丢数据,AOF又慢又大,到底选哪个?Redis官方和社区的普遍最佳实践是:两者同时开启,混合使用。

在Redis 4.0及以后的版本,开启AOF重写时,重写后的新AOF文件会以RDB格式来存储当前的数据快照,然后再追加后续的AOF命令,这样,这个混合文件既拥有了RDB的快速加载特性,又拥有了AOF的增量数据安全性。

Redis硬盘持久化那点事,数据安全和可靠存储怎么搞才靠谱

具体的靠谱做法可以参考如下几点(根据《Redis设计与实现》等资料中的建议思路):

  1. 基本配置: 在Redis的配置文件redis.conf中,同时启用RDB和AOF。

    • 保持RDB的默认备份规则(save 900 1, save 300 10, save 60 10000),让它作为一个定期的完整备份。
    • 把AOF开启(appendonly yes),并且设置同步策略为每秒一次(appendfsync everysec),这个配置在数据安全性和性能之间取得了很好的平衡,是生产环境最常用的设置。
  2. 做好备份: 光有持久化还不够,必须把生成的RDB文件和AOF文件备份到别的地方,比如用脚本定时把文件拷贝到另一台机器,或者上传到云存储服务,这样即使当前服务器的硬盘坏了,数据也能从远程备份中恢复。

  3. 监控磁盘和内存: 确保硬盘有足够的空间来存放AOF和RDB文件,尤其是在数据增长快的情况下,要监控内存使用,避免因为内存不足导致系统不稳定。

  4. 定期检查备份文件: 定期(比如每个月)可以尝试用备份的RDB或AOF文件在测试环境恢复一下Redis,确保你的备份文件是有效的、可用的,备份的最终目的是为了恢复,定期演练恢复流程非常重要。

想让Redis的数据存储靠谱,不能单靠一种方法。最稳妥的办法就是“RDB做定期全量备份,AOF做实时增量日志,两者结合开启,并且把生成的持久化文件再做异地备份”,这样,即使发生最坏的情况,你也能将数据损失降到最低,并快速恢复服务。