前言
Redis的读写操作都是再内存中进行,非常的快速。但也恰恰是需要重点加固的地方,一旦Redis出现任何原因宕机都会清空内存数据。虽然可以通过应用程序重新恢复数据。但是如果这些数据是经过非常复杂的运算计算出来的,或者是每天定时大量访问数据库缓存下来的数据。那么这些数据就不能轻易的丢失。否则对服务器、数据库都会是莫大的压力。
Redis给我们提供了两种持久化机制来恢复数据。分别是Rdb快照与Aof指令追加方式。Redis以 5.x版本讲解,本文主要介绍RDB,避免视觉劳累,Aof下一篇讲解。
RDB
通过简单的配置即可实现,当满足配置的要求时会将redis的数据快照一份保存在磁盘中,配置如下
dbfilename dump-6001.rdb # 快照在磁盘中的文件名
dir /home/cache/data # 快照保存
save 900 1 # 定时任务触发 15分钟内数据集至少有1个变动 server.c#serverCron()
save 300 10 # 5分钟内数据集至少有10个变动
save 60 10000 # 60秒内数据集至少有10000个变动
如果说不需要Rdb持久化将其注释掉就可以了。
除了上面通过配置方式自动持久化外,还可以手动执行命令立刻持久化,分别由save与 bgsave两个命令
save
save命令是直接使用Redis的主线程,同步执行,这段时间会影响业务的使用,如果说数据比较大,业务又访问频繁,不建议使用。
bgsave
fork一个子线程去处理持久化逻辑,主线程依然可以处理业务逻辑
写时复制
save命令毋庸置疑,肯定不会出现数据不一致情况。但是bgsave是通过子线程去持久化,主线程依然可以写,主线程与子线程共享着同一块内存,那么子线程持久化期间有写请求进来怎么办呢。
子线程持久化期间有读请求进来,两种自然可以并行,但是有写请求进来,试图修改数据,那么该共享数据会被复制一份,生成该数据的副本(只是针对于被修改的数据,并不会直接内存翻倍),主线程在该副本下修改数据,数据备份完后,副本数据将替换原来的数据。
上面配置的定时任务触发就是通过bgsave指令来备份的。
演示
备份前
[redis@master data]$ ls -l
total 4
-rw-rw-r-- 1 redis redis 92 Nov 26 23:25 dump.rdb
添加数据
127.0.0.1:7000> mset key1 value1 key2 value2
OK
备份
127.0.0.1:7000> save
OK
127.0.0.1:7000> bgsave
Background saving started
备份后
[redis@master data]$ ls -l
total 4
-rw-rw-r-- 1 redis redis 123 Nov 26 23:28 dump.rdb
可以见备份后大小由原来的92变成123,修改时间也变了。
总结
RDB是保存某一时刻的一个快照,并且数据以二进制形式保存在磁盘中,占用磁盘空间还是比较小的,对磁盘的io操作全部由子线程完成,主线程无任何io操作,恢复数据时文件直接加载到内存了,速度比较快,后面介绍的AOF需要一条条执行命令。速度相对较慢。
但其实fork子线程也是比较耗时的,这段期间主线程是无法工作的。由于备份的只是某个时间的快照,所以在两次备份期间机器宕机还是会丢失部分数据的。一般来说都是可容忍的,实在不能容忍的数据丢失的情况建议AOF也要配合使用。
欢迎关注,学习不迷路!