写点什么

看完这篇文章,你对 Redis 持久化的迷惑就全解开了,超全面

用户头像
极客good
关注
发布于: 刚刚


3.用修改之后,指定该配置文件重启 redis-server,然后开始测试;



4.尝试打开 dump.rdb 看看,咋一看是看不懂,但其实是有对应关系的,这里就不深究了



Redis 强大吧,不知不觉的就把数据备份,主要是还不影响正常操作,上图中第四步中就有体现,主进程 fork 了子进程进行备份,主进程不参与备份持久化操作。既然备份文件有了,如何进行恢复数据呢??redis-server 在启动的时候自动将当前目录中的备份文件(dump.rdb)数据加载到内存中;如下图所示:


RDB 其他配置项

那为什么是 dump.rdb 文件?,为什么又是当前目录?,如果 rdb 备份文件写入失败了怎么办?这些通过配置文件中 SNAPSHOTTING 部分都有详细的说明,并提供相关配置项进行设置,如下:


  • stop-writes-on-bgsave-error:默认设置为 yes,即当 RDB 备份数据失败时,Redis 会停止接收数据,保证数据的一致性;如果对数据一致性要求不高的,可以将其进行关闭,设置为 no,但推荐都开启;

  • rdbcompression:默认设置为 yes,开启压缩之后会采用 LZF 算法对备份文件 dump.rdb 进行压缩,但会消耗点 CPU 性能进行处理,但影响并不大,推荐都开启;

  • rdbchecksum:默认设置为 yes,即开启之后会对备份文件数据进行校验,但会消耗 CPU 性能,如果追求性能提高可以将其关闭,但影响也不大,推荐都开启;

  • dbfilename:默认为 dump.rdb,即默认的备份文件名为 dump.rdb,可以通过这个配置进行修改;

  • dir:默认为当前目录,即备份的文件存放的目录。

RDB 手动触发备份

上面说到自动触发备份,其实在实际应用场景中,有些需求很急,如果要求等到满足条件备份完成之后才处理问题,间隔时间短还好点,如果间隔时间超过 5 分钟,估计等待处理问题的人要上房揭瓦啦;Redis 同样为大家考虑到了,提供手动备份的方式,如下:


  • save:直接执行 save 命令,但会阻塞主进程操作,只能等待备份完成之后才能进行其他处理;

  • bgsave:直接执行 bgsave 命令,主进程会 fork 一个子进程进行备份操作,不阻塞主进程;当数据过大时,可能会在 fork 的时候有短暂的耗时,但影响不大; 上面的自动备份其实最后也是 bgsave 这种模式。

  • flushall:执行 flushall 命令会触发 RBD 备份,但是备份文件是空的,在本地测试一把就行了,没有任何意义,千万别在生产库上用


简单测试一下,删除 dump.rdb 文件,将配置文件恢复到默认值,然后指定配置文件重启 redis-server,如下:


如何停止或禁用 RDB 快照自动备份

可以通过配置文件的形式配置,也可以通过命令的形式进行关闭,但通过命令的方式,服务器重启之后就失效了,所以一般建议通过配置文件进行配置;


  • 配置文件方式:去除所有关于 save 的配置,或者配置一个 save ""即可,重启 redis-server;

  • 命令方式:在客户端中执行 config set save ""即可,但 redis-server 重启时就恢复默认值了;

RDB 备份流程


简要说明:


  1. 当触发 bgsave 持久化时(满足配置条件或手动执行 bgsave 命令),主进程 fork 一个子进程进行持久化操作,主进程不参与任何持久化 IO 操作;

  2. 为了不影响原有 rdb 文件的使用,子进程会将快照数据先写入到临时文件;

  3. 当快照数据完全备份到临时文件时,就替换掉原有的 rdb 文件,从而得到最新数据的 rdb 文件;


注:当执行 sava 命令的时候,会导致阻塞,只有等快照数据持久化完成之后,才能做其他事情;

RDB 持久化优缺点

每一项技术在解决已有问题的时候,肯定也会带来新问题,RDB 用来解决持久化问题,那它有什么优缺点呢?


优点


  • RDB 保存的数据文件比较紧凑,对比 AOF 来说,相同数据的文件大小比较小;

  • 大量数据持久化时速度相对 AOF 比较快;

  • RDB 中 bgsave 模式对主进程影响比较小,只有在主进程 fork 子进程的时候耗费资源,但影响不大;自动备份后台用的就是 bgsave 模式;


缺点


  • RDB 可能会丢失最后一次没有备份的数据,如果在最后一次没开始备份之前,服务器挂了,那最后一次的数据就没了;

  • 当数据量巨大时,主进程在 fork 子进程的时候,可能会导致稍微的卡顿;

AOF 持久化

既然已经有了 RDB 持久化了,那为什么还得出一个 AOF 呢?从 RDB 的缺点来看,很大程度上是因为可能会丢失最后一次备份之前的数据,对于一些重要数据来说,是不能接受的。而 AOF 的出现,将数据丢失风险极大的降低。先不说那么多,实操一把再慢慢聊。


AOF 默认情况是没开启的,打开配置文件,为了不让 RDB 备份影响,这里暂时先将 RDB 备份禁用掉,如下:


1.禁用 RDB 备份:



2.开启 AOF 备份:根据上一篇文章提到的,先找到 APPEND ONLY MODE 配置块,将 AOF 备份开启 appendonly yes



3.配置好了,指定配置文件重启 redis-server,先来看看效果:


当一启动 redis-server 的时候,appendonly.aof 文件就已经生成了;来,咱们接着敲点命令,如下↓↓↓



4.尝试打开 appendonly.aof 文件看看,和 dump.rdp 文件有什么不同;


![image.png](https://upload-images.jianshu.io/upload_images/24195226-ea510


【一线大厂Java面试题解析+核心总结学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
复制代码


20db2dad854.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


appendonly.aof 只记录写命令,读命令不记录,而且记录方式是以追加的方式,所以速度相对比较快;


同 RDB 一样,在 redis-server 重启时,自动加载 AOF 文件命令依次执行,最终将数据进行恢复

AOF 其他配置项

这就是 Redis 的强大,针对每一个功能都可以通过配置项进行完成,使用非常方便;


  • appendonly:默认 no,不开启 AOF 持久化;可以通过设置为 yes 开启;

  • appendfilename:默认 appendonly.aof,代表生成的 AOF 日志文件名,可以更改;

  • appendfsync:默认 everysec,设置同步命令到磁盘的策略,即默认每秒通过 fsync 进行一次命令同步到磁盘;有三种命令同步策略可以选择,如下:always:只要有写入命令就通过 fsync 同步到磁盘,数据完整性好,但效率不好;everysec:每秒通过 fsync 进行一次命令同步到磁盘,可能会导致一秒中数据的丢失,因为可能在命令还没同步的时候,机器挂掉等操作,但可接受;综合考虑,推荐使用这种策略;no:不同步,由操作系统处理,这种数据不能保证安全;

  • auto-aof-rewrite-percentage:默认 100,搭配 auto-aof-rewrite-min-size 一起触发 AOF 文件重写策略,即默认当当前 AOF 文件大小是上次重写的两倍时才重写,为了避免比率达到触发条件,但文件很小就触发重写的情况,所以搭配 auto-aof-rewrite-min-size 设置 AOF 文件的最小重写大小;即当前 AOF 文件大小达到比率的同时文件大小不低于 auto-aof-rewrite-min-size 设置的值才触发重写;

  • auto-aof-rewrite-min-size:默认 64mb,搭配 auto-aof-rewrite-percentage 使用;

AOF 触发重写

当执行的写命令过多时,就会导致 AOF 文件过度增大,而对于一些重复性的命令存在 AOF 文件中是没有必要的,如下图所示:



上图中多次对 a1 这个 Key 进行多次写入,最终的值为 10,可见如果 AOF 文件中只记录一条最终值的写命令岂不是最好,从而减少 AOF 文件的大小;这里文件大小肯定达不到自动触发重写的条件,这里就手动触发,然后再看看 AOF 文件内容,是否进行了优化,如下:



如上图可见,重写之后的 AOF 文件的确是我们自己想要,是不是觉得 Redis 更加牛 X 了;触发重写有以下两种方式:


  • 自动触发:即当满足设置的 auto-aof-rewrite-percentage auto-aof-rewrite-min-size 值会自动触发重写;

  • 手动触发:在客户端中执行 bgrewriteaof 命令;

AOF 重写流程


简要说明:


  1. 当触发到重写 AOF 文件时,主进程 fork 一个子进程,子进程根据内存中的现有数据进行命令精简化,重写到新的 AOF 文件中;

  2. 在子进程正在重写 AOF 文件时,如果有新的写命令,将其存放到重写缓冲区,同时也同步到原来的 AOF 文件;

  3. 当子进程重写完成之后,通知主进程将重写缓冲区中的新命令写入到新 AOF 文件中,完成之后,用新的 AOF 文件将原来的 AOF 文件替换;

  4. 最后得到优化之后的 AOF 文件,减少文件大小;

AOF 文件修复

用户头像

极客good

关注

还未添加个人签名 2021.03.18 加入

还未添加个人简介

评论

发布
暂无评论
看完这篇文章,你对Redis持久化的迷惑就全解开了,超全面