文章目录

  • Redis持久化操作
  • RDB
  • AOF
  • AOF文件异常恢复
  • 总结


Redis持久化操作

Redis提供了两种持久化的方式:
1、RDB(Redis DataBase)
2、AOF(Append Only File)

RDB

RDB:在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话将的 Snapshot 快照,他恢复时是将快照文件直接读到内存里。

使用RDB的优势:
1、适合大规模的数据恢复
2、对数据完整性和一致性要求不高,更适合使用
3、节省磁盘空间
4、恢复速度快

使用RDB的劣势:
1、Fork的时候,内存中的数据被克隆了一份,大致2倍的膨胀性需要考虑
2、虽然Redis在fork时使用了写时拷贝技术,但是如果数据比较庞大时,也会比较消耗性能。
3、在备份周期一定时间间隔内做一次备份,所以,如果Redis意外down掉的话,最后一次快照的所有修改将会丢失。

举个例子,我们让redis每1分钟保存将数据集快照写入磁盘。那么9:00, 9:01, 9:02,每分钟,我们都会保存一次redis此时的数据集到我们的磁盘中。这就是RDB。

Redis的备份是怎么执行的?
答:Redis会单独创建(Fork)一个子进程进行持久化,他会将数据写入到一个临时文件中,等持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程不进行任何IO操作的,这就满足了极高的性能。如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加高效。RDB的缺点是最后一次持久化后的数据可能丢失。

Fork的作用是复制一个与当前进程一样的进程。新进程的所有数据(变量、环境变量、程序计数器等)数值和原进程一致,但是是一个全新的进程,并作为原进程的子进程

在Linux中,fork()会产生一个和父进程完全相同的子进程,但是子进程在此后多会exec系统调用,出于效率考虑,Linux中引入了“写时复制技术”。
一般情况父进程和子进程会共用同一段物理内存,只有进程空间的各段的内容要发生变化时,才会将父进程的内容复制一份给子进程。

在Redis配置文件中的配置解析:

搜索SNAP往下看即可。

这个图解释有点问题哈,这里是900秒内,至少有1个key发生变化或者300秒内至少有10个key发生变化,60秒内至少有10,000个key发生变化,那么保存快照。

RDB的原理 redis redis rdb fork_linux


RDB的原理 redis redis rdb fork_服务器_02


RDB的原理 redis redis rdb fork_linux_03


savebgsave

  • save:只管保存,其他不管,全部阻塞,手动保存,不建议。
  • bgsave:Redis会在后台进行快照操作,快照同时还可以响应客户端请求。

可以通过lastsave命令获取最后一次成功执行快照的时间。

AOF

AOF:以日志的形式来记录每个写操作(增量保存),将Redis执行过的所有写指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之,redis重启的话就根据日志文件的内容将写执行从前都后执行一次以完成数据的恢复工作。

使用AOF的优势:
1、备份机制更稳健,丢失数据概率更低。
2、可读的日志文本,通过处理AOF稳健,可以处理误操作。

使用AOF的劣势:
1、比如RDB占用更多的磁盘空间。
2、恢复备份速度要慢。
3、每次读写同步的话,有一定的性能压力。
4、存在个别bug,造成恢复不能。

AOF的持久化流程:(下面会有详细的讲解)
1、客户端的请求写命令会被append追加到AOF缓冲区;
2、AOF缓冲区根据AOF持久化策略将操作sync(同步)到磁盘的AOF文件中。
3、AOF文件大小超过重写策略或手动重写时,会对AOF文件rewrite(重写),压缩AOF文件容量。
4、Redis服务重启时,会reload(重载)AOF文件中的写操作达到数据恢复的目的。

AOF默认不开启。 开启需要修改我们的配置文件如下:

默认情况下,配置文件的appendonly为no,我们需要把他改为yes,以此来开启redis的aof持久化。

RDB的原理 redis redis rdb fork_Redis_04


aof 文件的生成路径跟rdb一样。即,dir 的属性值为什么,那么rdb 和 aof 文件的生成路径就在哪儿。

注意:如果AOF和RBD同时开启,那么redis会读取AOF的数据。(初开AOF并重启redis服务器后,redis 的数据将为空。)

AOF文件异常恢复

如果我们的AOF文件损坏的话,那么我们可以进入 /usr/local/bin 目录下。
执行命令redis-check-aof --fix appendonly.aof修复我们的AOF文件。

AOF同步频率设置——appendfsync
配置文件中的appendfsync有几个常用的可选值:
1、appendfsync always:始终同步,每次redis的写入都立刻记入日志;性能较差但是数据完整性比较好。
2、appendfsync everysec:每秒同步,每秒记入日志一次,如果Redis宕机,本秒的数据可能会丢失。
3、appendfsync no:redis不主动进行同步,把同步时机交给操作系统。

AOF文件的压缩——Rewrite
AOF采用文件追加方式,文件会越来越大,为了避免这种情况,新增了重写机制,当AOF文件的大小超过所设定的阈值的时候,Redis会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集,可以使用命令 bgrewriteaof。(什么叫保留可以恢复数据的最小指令集,简单说就是,比如我们set a 1,set a 2, set a 3,最后a的值是3,那么压缩之后,就只剩下一个set a 3)。

当我们的aof文件大于64M的时候(默认情况下),且大于等于base_size + base_size * 100%(默认),会触发redis的rewrite(重写)操作。(也就是64MB重写一次,128M重写一次)。这里的64MB和100%我们也可以在配置文件中修改。(配置文件中对应的属性如下)

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

重写的流程如下:(跟RDB类似)
1、bgrewriteaof 触发重写,判断当前是否有bgsave 或 bgrewriteaof 在运行,如果有,则等待该命令结束后再继续执行。
2、主进程fork出子进程执行重写操作,保证主进程不会阻塞。
3、子进程遍历redis内存中数据到临时文件,客户端的写请求同时写入 aof_buf 缓冲区 和 aof_rewrite_buf 重写缓冲区保证原AOF文件完整以及新AOF文件生成期间新的数据修改动作不会丢失。
4、子进程写完新的AOF文件后,向主进程发信号,父进程更新统计信息。主进程把aof_rewrite_buf中的数据写入到新的AOF文件。
5、使用新的AOF文件覆盖旧的AOF文件,完成AOF重写。

AOF的持久化流程:(点一下题,回顾一下刚才的知识点)
1、客户端的请求写命令会被append追加到AOF缓冲区;
2、AOF缓冲区根据AOF持久化策略将操作sync(同步)到磁盘的AOF文件中。
3、AOF文件大小超过重写策略或手动重写时,会对AOF文件rewrite(重写),压缩AOF文件容量。
4、Redis服务重启时,会reload(重载)AOF文件中的写操作达到数据恢复的目的。

总结

说了这么多,那我们应该用哪个呢?
官方推荐我们两个都启用。如果对数据不敏感,可以单独用RDB,不建议单独用AOF,因为可能会出现Bug,如果只是做纯内存缓存,可以都不用。