从零开始学Redis系列(三)| 如何正确的操刀Redis的持久化

这是我参与更文挑战的第3天,活动详情查看:更文挑战

前言

Redis的数据都存放在内存中,如果没有配置持久化,redis重启后数据就全丢失了,那肯定不能让珍贵的数据因为这种外力而丢失,所以需要开启redis的持久化功能,将数据保存到磁盘上,当redis重启后,可以从磁盘中恢复数据。

这篇文章,从三个方面给大家一个比较直观的Redis持久化

  • Redis的持久化方式有哪几种
  • Redis的数据恢复步骤有哪些?
  • 企业中Redis的持久化策略应该怎么选择?

下面就从Redis持久化的方式开始吧!!!!

Redis持久化的方式

redis提供两种方式进行持久化:

  • 一种是RDB持久化(将Reids在内存中的数据库记录定时dump到磁盘上的RDB持久化)
  • 另外一种是AOF持久化(将Reids的操作日志以追加的方式写入文件)。

RDB快照(snapshot)

在默认的情况下,redis将内存数据库快照保存在名为dump.rdb的二进制文件中

生成dump.rdb文件的条件

自动触发

可以在redis.conf文件中设置,让它在N秒时间内至少有M个改动这一条件被满足时,自动保存一次,条件策略如下图所示:

image.png

例如:save 60 10000:意味着只要在60秒内至少有10000个操作,redis就会自动保存一次

可以添加多条策略,只要符合其中一条,redis就会自动保存一次,关闭RDB只需要将所有的save保存策略注释掉就可以了

手动执行

进入redis的客户端执行save命令bgsave命令可以生成dump.rdb文件,每次执行都会将所有redis的内存快照到一个新的rdb文件中,并覆盖原有rdb快照文件

例如:已存的dump.rdb文件的创建时间是20:19

image.png

执行一下save命令:

image.png

发现已存的dump.rdb文件的创建时间是当前时间,说明已经覆盖

image.png

dump.rdb的路径

dump.rdb的生成路径可以自行设置,在redis.conf配置文件设置,位置如下图所示

image.png

dump.rdb的文件名

dump.rdb的文件名可以自行设置,在redis.conf配置文件设置,位置如下图所示

image.png

同步or异步的生成dump.rdb文件

像上文中的save命令在生成dump.rdb文件的过程是同步的,也就是说在生成文件的过程中,会阻塞其他的redis命令执行,如果redis的内存越大,耗时越长,所以redis提供了一个bgsave的写时复制(copy-on-write)机制,在生成快照的同时,依然可以正常处理命令。

Reids主线程fork生成的子进程,共享主进程的所有内存数据,子进程写入到文件中。

此时,如果主线程对这些数据也都是读操作,那么主线程和子进程互不影响。如果主线程对数据中有修改操作,那么这些数据会被复制一份,生成该数据的副本。然后,主线程直接修改副本,bgsave在的子进程还是基于原先共享的内存数据写入到rdb文件中。

自动生成rdb文件后台使用的是bgsave方式

save和bgsave的对比

image.png

AOF(append-only file)

rdb这种方式有很严重的缺陷:如果Redis宕机了,那么服务器将丢失最近写入,且没有保存到快照中的那些命令。所以Redis增加了另外一种持久化方式:AOF,记录操作记录,然后重放操作,但是AOF文件只会记录修改数据的命令

开启AOF

可以在redis.conf文件中设置,把appendonly no修改成 appendonly yes,如下图所示:

image.png

AOF生成的文件名

image.png

AOF的策略

AOF支持三种策略:

  1. appendonly always:每次有新命令追加到AOF文件时就执行一次fsync,非常慢,也非常安全
  2. appendfsync everysec:每秒执行一次fsync,足够快,并且在故障时只会丢失1s
  3. appendfsync no:从不fsync,将数据交给操作系统来处理。更快,也更不安全的选择

image.png

推荐也是默认的措施是appendfsync everysec,兼容速度和安全性

测试AOF

  • 第一步:在redis中随便输入几个命令

image.png

  • 第二步:等待1s后观察有没有生产AOF文件

image.png

  • 第三步:使用cat命令查看AOF文件,发现命令已经追加到AOF文件中

image.png

  • 第四步:分析AOF文件

Redis的协议规范是 Redis Serialization Protocol (Redis序列化协议),AOF文件遵循这个协议,我们来举个set name miludexiaoguangtou例子来初步分析一下:

  • *3:aof文件记录每一个命令都是以*开始,3表示这个命令有几个参数,例如:set name miludexiaoguangtou就是3个参数,set、name和miludexiaoguangtou
  • $3$3意思就是下方的set有3个字符
  • $4$4意思就是下方的name有4个字符
  • $18$18意思就是下方的miludexiaoguangtou有18个字符

AOF的重写

AOF的文件里面可能有太多重复的、没用的指令。所以Redis支持定期根据内存的最新数据生产AOF文件,例如:执行了如下几条指令

image.png

重写后AOF文件里,后面的4条incr命令变成:

*3
$3
SET
$2
count
$1
4
复制代码

redis.conf配置文件中还可以对AOF重写的频率配置

// aof文件自上一次重写后文件大小增长了100%则再次触发
auto-aof-rewrite-percentage 100
// aof文件至少达到64mb才会自动重写,文件太小恢复速度本来就很快,重写的意义不大
auto-aof-rewrite-min-size 64mb
复制代码

AOF文件还支持手动重写,进入redis客户端,执行bgrewriteaof重写AOF

重写Redis会fork出一个子进程去做 (与bgsave命令类似),不会对正常命令处理有太多影响

RDB和AOF如何选择

命令 RDB AOF
启动优先级
体积
恢复速度
数据安全性 容易丢数据 根据策略决定

生产环境可以都启用,redis启动时如果既有rdb文件,又有aof文件,则优先选择aof文件恢复数据,因为aof一般来说数据更安全一点

混合持久化(Redis 4.0)

重启Redis时,很少使用RDB来恢复内存状态,因为会丢失大量的数据。通常使用AOF日志重放,但是重放AOF日志性能相对RDB来说会慢很多,这样在Redis实例很大的情况下,启动需要花费很长时间

Redis 4.0为了解决这个问题,带来了一个新的持久化方式-混合持久化

开启持久化配置(必须先开启AOF)

image.png

如果开启了混合持久化,AOF在重写时,不再是单纯的将内存数据转换为RESP命令,写入到AOF文件中,而是将重写这一刻之前的内存做RDB快照处理,并且将RDB快照内容和增量的AOF命令存在一起,都写入新的AOF文件中。

新的AOF文件一开始不叫appendonly.aof,等到重写完新的AOF文件才会进行改名,覆盖原有的AOF文件,完成新旧两个AOF文件的替换

所以总体上来看,在Redis启动的时候,先加载RDB格式的内存数据,然后再重放增量AOF日志就可以完全替代之前的AOF全量文件重放,因此重启的效率会大大提高

举例:混合持久化

手动执行AOF重写命令,发现已经将这一刻之前的内存做RDB快照处理,并写入到新的AOF文件中。

image.png

写入两个增量的Redis命令后,发现直接追加在AOF文件最后

image.png

混合持久化AOF文件的格式

上面是RDB的二进制格式 (那一刻的内存压缩数据),后面是AOF命令的格式 (增量的命令)

image.png

Redis的数据恢复

截止目前只讲了Redis的持久化,并且会生成RDB和AOF两种格式的文件,但是如何恢复没说,下面就开始根据案例一步步讲如何恢复Redis的数据

  • 第一步:先把redis关了,模拟宕机的情况

image.png

  • 第二步:把rdb文件和aof文件命名改了,先看下什么持久化文件都不存在的情况

image.png

  • 第三步:启动redis,观察里面的数据,发现什么key都不存在

image.png

image.png

  • 第四步:由于redis关闭的时候会自动执行一次持久化,所以我们把新生产的aof文件删了

image.png

  • 第五步:把原先的aof文件和rdb的文件命名恢复

image.png

  • 第六步:重新启动redis,观察数据,发现已经aof文件中的数据已经加载到redis中

image.png

image.png

Redis持久化的策略

  1. 写crontab定时调度脚本,每小时都copy一份rdb或者aof的备份到一个目录中去,仅仅保留最近48小时的备份
  2. 写crontab定时调度脚本,每天都保留一份当日的数据备份到一个目录中去,可以保留最近一个月的备份
  3. 每次copy备份的时候,可以把之前太旧的备份记录给删了
  4. 每天晚上将当前机器上的备份复制一份到其他机器上,以防机器损坏 (多地备份)

总结

这篇文章,从三个方面给大家一个比较直观的Redis持久化

  • Redis的持久化方式有哪几种
  • Redis的数据恢复步骤有哪些?
  • 企业中Redis的持久化策略应该怎么选择?

相信现在大家对Redis的持久化都有一个比较清晰的感受,现在赶快行动,去找你们的运维聊聊,看看各自所在的企业中用的是哪种持久化策略,为什么要这么设置,有没有更好的方案?

往期推荐

从零开始学Redis系列(一)| Redis环境搭建

从零开始学Redis系列(二)| Redis常用命令如何在企业中重拳出击

絮叨

最后,如果感到文章有哪里困惑的,请第一时间留下评论,如果各位看官觉得小沙弥我有点东西的话 求点赞? 求关注❤️ 求分享? ,因为这将是我输出更多优质文章的动力,感谢!!!

如果想获取Redis相关书籍,可以关注微信公众号Java百科全书输入Redis,即可获得

最后感谢各位看官的支持,我们下期再见!

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享