1. 前言

今天呢,我们来了解下Redis的持久化技术。都知道Redis是内存型key-value型数据库。其实叫缓存中间件更合适。既然是内存性数据库就知道存入磁盘的必要性了。所以就需要持久化技术来支持了

2. 合适人群

  • 对Redis 持久化技术不了解的人

3. RDB

RDB 其实就是Redis持久化方式的一种实现。其实更好的方式可以理解为一种快照。而且有多种方式来启动RDB模式

3.1 启动方式

  • 执行 save 命令。通过主线程来执行,会阻塞主线程的

通过上述的命令就可以得知,其实我们手动执行save方法后,会出现文件dump.rdb。 其实这个就是持久化文件,每次启动Redis的时候可以用这个来恢复

  • 执行命令bgsave来进行持久化。基于主线程fork一个子线程来进行数据备份。不会阻塞主线程

windows中配置redis持久化 redis持久化一般用哪个_redis


windows中配置redis持久化 redis持久化一般用哪个_windows中配置redis持久化_02


windows中配置redis持久化 redis持久化一般用哪个_windows中配置redis持久化_03

  • 执行命令bgsave的过程 其实跟save保持一致。只不过内部运行不同

3.2 QA

3.2.1 Q 难道每次进行备份的时候 都需要手动备份吗??

no,no,no 其实我们在配置文件中可以配置触发RDB备份的方式

windows中配置redis持久化 redis持久化一般用哪个_java_04

  • 可以将上述表框的注释放开。只要满足任何一项都会触发RDB 备份的
  • 如果想关闭RDB 的持久化。可以设置命令save " "

3.2.2 Q 如果想修改 备份文件的名称怎么办???

windows中配置redis持久化 redis持久化一般用哪个_数据库_05

可以通过上述的配置文件来修改 生成文件的名称

3.3 RDB 实现备份原理

windows中配置redis持久化 redis持久化一般用哪个_java_06

  • bgsave 子进程是由主线程 fork 生成的,可以共享主线程的所有内存数据。bgsave 子进程运行后,开始读取主线程的内存数据,并把它们写入 RDB 文件。
  • 如果主线程对这些数据也都是读操作(例如图中的键值对 A),那么,主线程和bgsave 子进程相互不影响。但是,如果主线程要修改一块数据(例如图中的键值对 B),那么,这块数据就会被复制一份,生成该数据的副本。然后,bgsave 子进程会把这个副本数据写入 RDB 文件,而在这个过程中,主线程仍然可以直接修改原来的数据。

3.4 优缺点

3.4.1 优点

  • RDB是一个紧凑压缩的二进制文件,代表Redis在某个时间点上的数据快照。非常适用于备份,全量复制等场景。
  • Redis加载RDB恢复数据远远快于AOF的方式。

3.4.2 缺点

  • RDB方式数据没办法做到实时持久化/秒级持久化。因为bgsave每次运行都要执行fork操作创建子进程,属于重量级操作,频繁执行成本过高。
  • RDB文件使用特定二进制格式保存,Redis版本演进过程中有多个格式的RDB版本,存在老版本Redis服务无法兼容新版RDB格式的问题。

3.5 数据丢失的问题

windows中配置redis持久化 redis持久化一般用哪个_windows中配置redis持久化_07


所以这里可以看出,如果想丢失较少的数据,那么T4-T0就要尽可能的小,但是如果频繁地执行全量

快照,也会带来两方面的开销:

1、频繁将全量数据写入磁盘,会给磁盘带来很大压力,多个快照竞争有限的磁盘带宽,前一个快照还没有做完,后一个又开始做了,容易造成恶性循环。

2、另一方面,bgsave 子进程需要通过 fork 操作从主线程创建出来。虽然子进程在创建后不会再阻塞主线程,但是,fork 这个创建过程本身会阻塞主线程,而且主线程的内存越大,阻塞时间越长。如果频繁fork出bgsave 子进程,这就会频繁阻塞主线程了。

所以基于这种情况,我们就需要AOF的持久化机制。

4. AOF

以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中的命令达到恢复数据的目的。AOF的主要作用是解决了数据持久化的实时性,目前已经是Redis持久化的主流方式。理解掌握好AOF持久化机制对我们兼顾数据安全性和性能非常有帮助

4.1 启动方式

windows中配置redis持久化 redis持久化一般用哪个_数据_08

通过上述文件中的配置来启动AOF模式

4.2 QA

4.2.1 Q 如果想修改 备份文件的名称怎么办???

windows中配置redis持久化 redis持久化一般用哪个_数据_09

4.3 AOF 的工作流程

AOF的工作流程主要是4个部分:命令写入( append)、文件同步( sync)、文件重写(rewrite)、重启加载( load)。

windows中配置redis持久化 redis持久化一般用哪个_windows中配置redis持久化_10

  • 其实到这一步我们需要了解AOF 以及RDB的不同。RDB是备份数据的,将数据进行二进制存储。但是AOF 是以文本协议来存储命令的。通过命令来进行恢复数据
  • 通过上述截图中可能大家有一个疑问: 为什么不直接写入到磁盘中呢??? 如果每次写AOF文件命令都直接追加到硬盘,那么性能完全取决于当前硬盘负载。先写入缓冲区aof_buf中,还有另一个好处,Redis可以提供多种缓冲区同步硬盘的策略,在性能和安全性方面做出平衡
  • 所以每次都会写到缓冲区中。再通过某种机制进行同步。同步的过程中会触发rewrite
  • 可能有的人 会问了rewrite 是做什么的???可以理解为 为了减少占用内存大小,而优化命令的。

4.4 触发AOF时机

windows中配置redis持久化 redis持久化一般用哪个_windows中配置redis持久化_11

上述的配置其实其实就是通过不同的时机来 触发AOF的命令写入

4.5 rewrite 机制

windows中配置redis持久化 redis持久化一般用哪个_redis_12

  • 其实满足上述的条件就会触发rewrite
  • 另外,如果在Redis在进行AOF重写时,有写入操作,这个操作也会被写到重写日志的缓冲区。这样,重写日志也不会丢失最新的操作。

5. RDB-AOF混合持久化

其实最好的方式就是集两家之所长。 利用RDB的全量文件备份 + 利用AOF 命令的实时性。 来尽最大可能性保证数据的不丢失。 其实现在的Redis配置默认就是这个模式

windows中配置redis持久化 redis持久化一般用哪个_redis_13


windows中配置redis持久化 redis持久化一般用哪个_数据库_14

该状态开启后,如果执行bgrewriteaof命令,则会把当前内存中已有的数据弄成二进程存放在aof文件中,这个过程模拟了rdb生成的过程,然后Redis后面有其他命令,在触发下次重写之前,依然采用AOF追加的方式

6. 总结

上述截图中的配置,可以参照这个。其实我们应该更加认识Redis只是一个高性能的缓存中间件。通过rdb + aof的方式尽可能保持数据备份,做不到百分之百的数据不丢失。其实总体上就两点:1. rdb 在某一个时间点,进行数据二进制的全量备份 2. aof 通过日志的形式来保存命令,通过命令反推数据,可以做到数据的实时性,但是基于Redis默认配置,其实是以秒为单位的。所以说有可能会丢失某一秒内的数据。