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

Redis线上数据怎么持久化,实操和注意点聊聊

聊到Redis的线上数据持久化,说白了就是怎么把内存里飞快跑着的数据,弄一份到硬盘上存起来,防止服务器突然宕机或者重启导致数据全部丢失,这就像你在电脑上写一份很重要的文档,你得时不时地按一下“Ctrl+S”保存,不然突然停电就白干了,Redis提供了两种主要的“保存”方式,一种叫RDB,另一种叫AOF,在实际生产环境中,我们经常是两者结合着用,而不是二选一。

第一种方式:RDB(快照)

你可以把RDB理解成“拍照片”,在某个时间点,Redis会把当前内存中所有的数据生成一个快照,然后压缩成一个后缀为.rdb的二进制文件,存到硬盘上。

实操上怎么触发RDB呢? 主要有两种方法:

  1. 自动触发: 这是最常用的,你在Redis的配置文件redis.conf里设置好规则就行,你可能会看到这样的配置: save 900 1 # 在900秒(15分钟)内,如果至少有1个key发生变化,就拍一张快照。 save 300 10 # 在300秒(5分钟)内,如果至少有10个key发生变化,就拍一张。 save 60 10000 # 在60秒内,如果至少有10000个key发生变化,就拍一张。 Redis会检查这些条件,只要满足其中一条,就会自动在后台启动一个子进程来执行RDB持久化。

  2. 手动触发: 在命令行里执行save命令或者bgsave命令。

    Redis线上数据怎么持久化,实操和注意点聊聊

    • save:这个命令会立刻开始拍快照,但是在拍完之前,整个Redis会阻塞,不能处理任何新的请求。线上环境绝对不要用这个命令,除非你确定可以接受服务暂停。
    • bgsave:这个命令是“background save”的意思,Redis会fork一个子进程到后台去生成RDB文件,主进程继续正常提供服务,这是我们手动操作时推荐的方式。

RDB的注意点:

  • 优点:
    • 恢复速度快: 因为就是一个完整的压缩文件,重启Redis时,直接把RDB文件读回内存,速度非常快。
    • 文件紧凑: RDB文件是二进制压缩的,体积相对较小,适合做灾难备份,比如每天把RDB文件拷贝到别的机房或者云存储上。
  • 缺点:
    • 可能丢数据: 这是最大的问题,如果上次拍快照之后,到服务器宕机之前的这段时间里,有任何数据写入,这些数据都会丢失,根据你设置的save规则,你可能会丢失最近5分钟、甚至15分钟的数据,对于数据一致性要求非常高的业务,这是不能接受的。
    • fork操作的潜在风险: 虽然bgsave是子进程操作不阻塞主进程,但fork这个创建子进程的动作本身,在数据量特别大的时候,可能会引起主进程短暂的停顿(停顿时间和机器硬件尤其是内存有关)。

第二种方式:AOF(日志追加)

AOF的思路和RDB完全不同,它不拍照片,而是“写日记”,Redis会把每一个会修改数据的写命令(比如set, hset, sadd等),记录到一个日志文件(后缀是.aof)的末尾,当Redis重启时,它会从头到尾重新执行一遍这个AOF文件里的所有命令,从而还原数据。

Redis线上数据怎么持久化,实操和注意点聊聊

实操上怎么配置AOF? 也是在redis.conf文件里设置: appendonly yes # 把默认的no改成yes,就开启了AOF功能。 开启后,你还需要设置日志文件“写回”硬盘的策略,这关系到性能和数据安全性的权衡: appendfsync always # 每个写命令都立刻同步到硬盘,最安全,基本不会丢数据,但性能最差,因为每个命令都要等硬盘IO。 appendfsync everysec # 每秒同步一次,这是默认的也是推荐的策略,就算宕机,最多丢失1秒钟的数据,在性能和安全性之间取得了很好的平衡。 appendfsync no # 让操作系统自己决定什么时候同步,性能最好,但丢数据的风险最大。

AOF的注意点:

  • 优点:
    • 数据安全度高: 特别是用appendfsync everysec策略,最多丢1秒数据,比RDB通常要安全。
    • 可读性好: AOF文件是纯文本格式,记录的是命令(虽然实际是特定格式,但可理解),万一出问题,你甚至可以用文本编辑器打开进行人工修复(不过要非常小心)。
  • 缺点:
    • 文件体积大: 随着时间推移,AOF文件会越来越大,因为记录了所有的写操作,比如你对一个key修改了100次,AOF会记录100条命令,而RDB最后只存一份最终值。
    • 恢复速度慢: 重启时回放AOF日志通常比加载RDB文件要慢得多。
    • 需要处理文件膨胀: 为了解决AOF文件过大的问题,Redis提供了AOF重写机制(可以执行bgrewriteaof命令触发),这个机制会fork一个子进程,根据当前数据库的状态,生成一个新的、更小的AOF文件(比如那个被修改了100次的key,新文件里只记录它最后的值),重写过程也会有一定的资源消耗。

线上实战建议

在真实的线上环境,我们一般不会孤注一掷,而是采用“混合持久化”的策略,取长补短。

  1. 同时开启RDB和AOF: 在配置文件里,既设置save规则,也设置appendonly yes,这样做的目的是,利用AOF来保证尽可能少的数据丢失(作为数据的第一道保障),同时利用RDB来做快速的灾难恢复和定期归档。
  2. RDB配置: 根据业务对数据丢失的容忍度来设定,比如可以设置save 300 100,在5分钟内有100次写入就做一次快照,不要太频繁,否则会影响性能。
  3. AOF配置: 使用默认的appendfsync everysec通常是个好选择。
  4. 监控磁盘空间: 一定要监控服务器磁盘的使用情况,确保有足够空间存放RDB文件和不断增长的AOF文件,如果磁盘满了,Redis会写失败,进而可能导致服务停止。
  5. 做好备份: 定期把RDB文件和AOF文件备份到远端的存储系统(比如对象存储、另一台服务器),这是最后的救命稻草。
  6. 重启恢复流程: 当Redis重启时,如果AOF功能是开启的,它会优先使用AOF文件来恢复数据,因为AOF的数据完整性通常更高,只有在AOF关闭时,才会用RDB文件恢复。

核心思想就是:用AOF保证数据不丢或少丢,作为首选恢复方案;用RDB做冷备,加快某些场景下的恢复速度,并便于归档。 具体配置参数需要根据你的业务数据量、写操作的频繁程度、以及对数据丢失的容忍度来仔细调整和测试。