1. 前言
今天呢,我们来了解下Redis的持久化技术。都知道Redis是内存型key-value型数据库。其实叫缓存中间件更合适。既然是内存性数据库就知道存入磁盘的必要性了。所以就需要持久化技术来支持了
2. 合适人群
- 对Redis 持久化技术不了解的人
3. RDB
RDB
其实就是Redis持久化方式的一种实现。其实更好的方式可以理解为一种快照。而且有多种方式来启动RDB
模式
3.1 启动方式
- 执行
save
命令。通过主线程来执行,会阻塞主线程的
通过上述的命令就可以得知,其实我们手动执行
save
方法后,会出现文件dump.rdb
。 其实这个就是持久化文件,每次启动Redis的时候可以用这个来恢复
- 执行命令
bgsave
来进行持久化。基于主线程fork一个子线程来进行数据备份。不会阻塞主线程
- 执行命令
bgsave
的过程 其实跟save保持一致。只不过内部运行不同
3.2 QA
3.2.1 Q 难道每次进行备份的时候 都需要手动备份吗??
no,no,no 其实我们在配置文件中可以配置触发
RDB
备份的方式
- 可以将上述表框的注释放开。只要满足任何一项都会触发
RDB
备份的 - 如果想关闭
RDB
的持久化。可以设置命令save " "
3.2.2 Q 如果想修改 备份文件的名称怎么办???
可以通过上述的配置文件来修改 生成文件的名称
3.3 RDB
实现备份原理
-
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 数据丢失的问题
所以这里可以看出,如果想丢失较少的数据,那么T4-T0就要尽可能的小,但是如果频繁地执行全量
快照,也会带来两方面的开销:
1、频繁将全量数据写入磁盘,会给磁盘带来很大压力,多个快照竞争有限的磁盘带宽,前一个快照还没有做完,后一个又开始做了,容易造成恶性循环。
2、另一方面,bgsave 子进程需要通过 fork 操作从主线程创建出来。虽然子进程在创建后不会再阻塞主线程,但是,fork 这个创建过程本身会阻塞主线程,而且主线程的内存越大,阻塞时间越长。如果频繁fork出bgsave 子进程,这就会频繁阻塞主线程了。
所以基于这种情况,我们就需要AOF的持久化机制。
4. AOF
以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中的命令达到恢复数据的目的。AOF的主要作用是解决了数据持久化的实时性,目前已经是Redis持久化的主流方式。理解掌握好AOF持久化机制对我们兼顾数据安全性和性能非常有帮助
4.1 启动方式
通过上述文件中的配置来启动AOF模式
4.2 QA
4.2.1 Q 如果想修改 备份文件的名称怎么办???
4.3 AOF 的工作流程
AOF的工作流程主要是4个部分:命令写入( append)、文件同步( sync)、文件重写(rewrite)、重启加载( load)。
- 其实到这一步我们需要了解
AOF
以及RDB
的不同。RDB
是备份数据的,将数据进行二进制存储。但是AOF
是以文本协议来存储命令的。通过命令来进行恢复数据- 通过上述截图中可能大家有一个疑问: 为什么不直接写入到磁盘中呢??? 如果每次写AOF文件命令都直接追加到硬盘,那么性能完全取决于当前硬盘负载。先写入缓冲区aof_buf中,还有另一个好处,Redis可以提供多种缓冲区同步硬盘的策略,在性能和安全性方面做出平衡
- 所以每次都会写到缓冲区中。再通过某种机制进行同步。同步的过程中会触发
rewrite
- 可能有的人 会问了
rewrite
是做什么的???可以理解为 为了减少占用内存大小,而优化命令的。
4.4 触发AOF
时机
上述的配置其实其实就是通过不同的时机来 触发
AOF
的命令写入
4.5 rewrite
机制
- 其实满足上述的条件就会触发
rewrite
。- 另外,如果在Redis在进行AOF重写时,有写入操作,这个操作也会被写到重写日志的缓冲区。这样,重写日志也不会丢失最新的操作。
5. RDB-AOF混合持久化
其实最好的方式就是集两家之所长。 利用
RDB
的全量文件备份 + 利用AOF
命令的实时性。 来尽最大可能性保证数据的不丢失。 其实现在的Redis配置默认就是这个模式
该状态开启后,如果执行bgrewriteaof命令,则会把当前内存中已有的数据弄成二进程存放在aof文件中,这个过程模拟了rdb生成的过程,然后Redis后面有其他命令,在触发下次重写之前,依然采用AOF追加的方式
6. 总结
上述截图中的配置,可以参照这个。其实我们应该更加认识Redis只是一个高性能的缓存中间件。通过rdb + aof的方式尽可能保持数据备份,做不到百分之百的数据不丢失。其实总体上就两点:1. rdb 在某一个时间点,进行数据二进制的全量备份 2. aof 通过日志的形式来保存命令,通过命令反推数据,可以做到数据的实时性,但是基于Redis默认配置,其实是以秒为单位的。所以说有可能会丢失某一秒内的数据。