目录
一、概述
为什么要做数据持久化?
我们的Redis必须使用数据持久化吗?如果我们的Redis服务器只作为缓存使用,Redis中存储的所有数据都是从其他地方同步过来的备份,那么就没必要开启数据持久化的选项,但是如果我们希望将内存中的数据保留下来的话,就必须做数据持久化.
Redis提供了将数据定期自动持久化至硬盘的能力,包括RDB和AOF两种方案,两种方案分别有其长处和短板,可以配合起来同时运行,确保数据的稳定性。
RDB
Redis会定期保存数据快照至一个rbd文件中,并在启动时自动加载rdb文件,恢复之前保存的数据。可以在配置文件中配置Redis进行快照保存的时机:
save [seconds] [changes]
意为在[seconds]秒内如果发生了[changes]次数据修改,则进行一次RDB快照保存,例如
save 60 100
会让Redis每60秒检查一次数据变更情况,如果发生了100次或以上的数据变更,则进行RDB快照保存。可以配置多条save指令,让Redis执行多级的快照保存策略。Redis默认开启RDB快照。
也可以通过BGSAVE命令手动触发RDB快照保存。
RDB的优点
对性能影响最小。如前文所述,Redis在保存RDB快照时会fork出子进程进行,几乎不影响Redis处理客户端请求的效率。每次快照会生成一个完整的数据快照文件,所以可以辅以其他手段保存多个时间点的快照(例如把每天0点的快照备份至其他存储媒介中),作为非常可靠的灾难恢复手段。使用RDB文件进行数据恢复比使用AOF要快很多。
RDB的缺点
快照是定期生成的,所以在Redis crash时或多或少会丢失一部分数据。如果数据集非常大且CPU不够强(比如单核CPU),Redis在fork子进程时可能会消耗相对较长的时间,影响Redis对外提供服务的能力。
AOF
采用AOF持久方式时,Redis会把每一个写请求都记录在一个日志文件里。在Redis重启时,会把AOF文件中记录的所有写操作顺序执行一遍,确保数据恢复到最新。AOF默认是关闭的,如要开启,进行如下配置:
appendonly yes
AOF提供了三种fsync配置,通过配置项[appendfsync]指定:
appendfsync no:不进行fsync,将flush文件的时机交给OS决定,
速度最快appendfsync always:每写入一条日志就进行一次fsync操作,数据安全性最高,但速度最慢
appendfsync everysec:折中的做法,交由后台线程每秒fsync一次
随着AOF不断地记录写操作日志,因为所有的操作都会记录,所以必定会出现一些无用的日志。大量无用的日志会让AOF文件过大,也会让数据恢复的时间过长。不过Redis提供了AOF rewrite功能,可以重写AOF文件,只保留能够把数据恢复到最新状态的最小写操作集。
AOF的优点
最安全,在启用appendfsync always时,任何已写入的数据都不会丢失,使用在启用appendfsync everysec也至多只会丢失1秒的数据。AOF文件在发生断电等问题时也不会损坏,即使出现了某条日志只写入了一半的情况,也可以使用redis-check-aof工具轻松修复。AOF文件易读,可修改,在进行了某些错误的数据清除操作后,只要AOF文件没有rewrite,就可以把AOF文件备份出来,把错误的命令删除,然后恢复数据。
AOF的缺点
AOF文件通常比RDB文件更大性能消耗比RDB高数据恢复速度比RDB慢
数据持久化引发的延迟
Redis的数据持久化工作本身就会带来延迟,需要根据数据的安全级别和性能要求制定合理的持久化策略:
AOF + fsync always的设置虽然能够绝对确保数据安全,但每个操作都会触发一次fsync,会对Redis的性能有比较明显的影响AOF + fsync every second是比较好的折中方案,每秒fsync一次AOF + fsync never会提供AOF持久化方案下的最优性能使用RDB持久化通常会提供比使用AOF更高的性能,但需要注意RDB的策略配置每一次RDB快照和AOF Rewrite都需要Redis主进程进行fork操作。fork操作本身可能会产生较高的耗时,与CPU和Redis占用的内存大小有关。根据具体的情况合理配置RDB快照和AOF Rewrite时机,避免过于频繁的fork带来的延迟
Redis在fork子进程时需要将内存分页表拷贝至子进程,以占用了24GB内存的Redis实例为例,共需要拷贝24GB / 4kB * 8 = 48GB的数据。在使用单Xeon 2.27Ghz的物理机上,这一fork操作耗时216ms。
可以通过INFO命令返回的latest_fork_usec字段查看上一次fork操作的耗时(微秒)
最后:
不过大多数应用场景下,建议至少开启RDB方式的数据持久化。Redis 对于数据备份是非常友好的, 因为你可以在服务器运行的时候对 RDB 文件进行复制: RDB 文件一旦被创建, 就不会进行任何修改。 当服务器要创建一个新的 RDB 文件时, 它先将文件的内容保存在一个临时文件里面, 当临时文件写入完毕时, 程序才使用 rename(2) 原子地用临时文件替换原来的 RDB 文件。
二、RDB
RDB介绍
Redis数据库文件,全称Reids DataBase,是Redis数据持久化方式之一。工作方式是在指定时间间隔内,将内存中的数据集快照写入硬盘。专业术语又叫Snapshot快照。恢复时,将快照文件直接读到内存里。
我们通过以下案例来看看如何用RDB持久化数据
具体要求如下:
- 启用RDB
- 设置存盘间隔为120秒且10个key改变数据自动存盘
- 备份RDB文件
- 删除数据
- 使用RDB文件恢复数据
1.修改配置文件并触发RDB快照
找到配置文件中的save一行(提示,可以在通过vim在命令模式按/键后输入save,按n向下翻查找)
- [root@redisA ~]# vim /etc/redis/6379.conf
- dbfilename dump.rdb
- save 900 1
- #save 300 10 //注释原有设置
- save 120 10 //时间修改为 120秒 10次变化
- save 60 10000
- :wq
- [root@redisA ~]# /etc/init.d/redis_6379 stop //停止服务
- Stopping ...
- Waiting for Redis to shutdown ...
- Redis stopped
- [root@redisA ~]#
- [root@redisA ~]# rm –rf /var/lib/redis/6379/* //清空数据库目录
- [root@redisA ~]# /etc/init.d/redis_6379 start //启动服务
- Starting Redis server...
- [root@redisA ~]#
- [root@redisA ~]# ls /var/lib/redis/6379 //此时,查看数据库目录下没有dump.rdb文件
- [root@redisA ~]#
- [root@redisA ~]# redis-cli -h 192.168.4.51 -p 6351 -a 123456 //连接服务,在120秒内存储10个变量,就会自动在数据库目录下创建dump.rdb 文件
- 192.168.4.51:6351> set v1 k1
- OK
- 192.168.4.51:6351> set v2 k1
- OK
- 192.168.4.51:6351> set v3 k1
- OK
- 192.168.4.51:6351> set v4 k1
- OK
- 192.168.4.51:6351> set v45 k1
- OK
- 192.168.4.51:6351> set v46 k1
- OK
- 192.168.4.51:6351> set v7 k1
- OK
- 192.168.4.51:6351> set v8 k1
- OK
- 192.168.4.51:6351> set v9 k1
- OK
- 192.168.4.51:6351> set v10 k1
- OK
- 192.168.4.51:6351> keys *
- 1) "v2"
- 2) "v9"
- 3) "v10"
- 4) "v45"
- 5) "v4"
- 6) "v1"
- 7) "v46"
- 8) "v8"
- 9) "v7"
- 10) "v3"
- 192.168.4.51:6351>exit
- [root@redisA ~]# ls /var/lib/redis/6379 //此时,查看数据库目录下有dump.rdb文件
- dump.rdb
- [root@redisA ~]#
2.备份数据
- [root@redisA ~]# cd /var/lib/redis/6379/
- [root@redisA 6379]# ls
- dump.rdb
- [root@redisA 6379]# cp dump.rdb /tmp/dump.rdb //备份dump.rdb文件
- [root@redisA 6379]# scp /tmp/dump.rdb root@192.168.4.56:/root/ //传递备份文件给目标主机
3.恢复数据
我们在其他机器上通过dump.rdb恢复数据
- [root@redis56 ~]# redis-cli -h 192.168.4.56 –p 6356 //连接服务
- 192.168.4.56:6356> flushall
- OK
- 192.168.4.51:6379> keys * //已经没有数据
- (empty list or set)
- 192.168.4.56:6356> exit
- [root@redis56 ~]#
恢复数据(56主机使用备份文件恢复数据)
- [root@redis56 ~]# /etc/init.d/redis_6379 stop //停止服务
- Stopping ...
- Waiting for Redis to shutdown ...
- Redis stopped
- [root@redis56 ~]#
- [root@redis56 ~]# rm -rf /var/lib/redis/6379/* //清空数据库目录
- [root@redis56 ~]# cp /tmp/dump.rdb /var/lib/redis/6379/ //拷贝备份文件到数据库目录下
- [root@redis56 ~]# /etc/init.d/redis_6379 start // 启动服务
- Starting Redis server...
- [root@redis56 ~]# redis-cli -h 192.168.4.56 –p 6356 //访问服务
- 192.168.4.56:6356> keys * //查看数据,可以看到有数据
- 1) "v7"
- 2) "v46"
- 3) "v45"
- 4) "v8"
- 5) "v4"
- 6) "v2"
- 7) "v1"
- 8) "v3"
- 9) "v9"
- 10) "v10"
- 192.168.4.56:6356>
4.手动触发
除了通过修改配置文件,自动触发快照条件外,还可以通过手动触发来实现持久化,在redis服务下执行命令
save:阻塞存盘,执行这个命令时在执行结束前不允许插入数据
bgsave:不阻塞存盘,执行这个命令时允许插入数据
三、AOF
我们通过一下案例来看看如何使用AOF持久化数据
具体要求如下:
- 启用AOF
- 备份AOF文件
- 删除数据
- 使用AOF文件恢复数据
1.使用AOF文件恢复数据
1)修改配置文件
- [root@redisA ~]# redis-cli -h 192.168.4.51 –p 6351 -a 123456 //连接服务
- 192.168.4.51:6351>config set appendonly yes //通过命令启用aof,默认no
- 192.168.4.51:6351> config rewrite //写进配置文件
- 192.168.4.51:6351> set v1 k1 //写几个数据
- OK
- 192.168.4.51:6351> set v2 k1
- OK
- 192.168.4.51:6351> set v3 k1
- OK
- 192.168.4.51:6351> set v4 k1
- OK
- 192.168.4.51:6351> set v45 k1
- OK
- 192.168.4.51:6351> set v46 k1
- OK
- 192.168.4.51:6351> set v7 k1
- OK
- 192.168.4.51:6351> set v8 k1
- OK
- 192.168.4.51:6351> set v9 k1
- OK
- 192.168.4.51:6351> set v10 k1
- OK
- 192.168.4.51:6351> save //调用存盘命令
- 192.168.4.51:6351> exit
- [root@redisA ~]# ls /var/lib/redis/6379/ //会出现appendonly.aof文件
- appendonly.aof
- [root@redisA ~ ]#
2)备份AOF文件
- [root@redisA ~]# cd /var/lib/redis/6379/
- [root@redisA 6379]# cp appendonly.aof /tmp/appendonly.aof
- [root@redisA 6379]# scp /tmp/appendonly.aof root@192.168.4.57:/root/ //传递备份文件给目标主机
3)删除数据(在57主机 默认数据误删除)
- [root@redis57 ~]# redis-cli -h 192.168.4.57 -p 6357 //连接服务
- 192.168.4.57:6357> flushall //清除数据
- OK
- 192.168.4.57:6357> keys * //查看数据
- (empty list or set)
- 192.168.4.57:6357> exit
- [root@redis57 ~ ]#
4) 使用AOF文件恢复数据
- [root@redis57 ~]# vim +673 /etc/redis/6379.conf
- appendonly yes //启用AOF
- :wq
- [root@redis57 ~]#
- [root@redis57 ~]# /etc/init.d/redis_6379 stop //停止服务
- Stopping ...
- Waiting for Redis to shutdown ...
- Redis stopped
- [root@redis57 ~]#
- [root@redis57 ~]# /etc/init.d/redis_6379 start //启动服务
- 要求如下:
Starting Redis server...- [root@redis57 ~]#
- [root@redis57 ~]# rm -rf /var/lib/redis/6379/* //删除没有数据的文件
- [root@redis57 ~]# cp /root/appendolny.aof /var/lib/redis/6379/ //拷贝文件
- [root@redis57 ~]# /etc/init.d/redis_6379 start //启动服务
- Starting Redis server...
- [root@redis57 ~]# redis-cli -h 192.168.4.57 -p 6357 //连接服务
- 192.168.4.57:6357> keys * //查看数据
- 1) "v9"
- 2) "v5"
- 3) "v8"
- 4) "v2"
- 5) "v1"
- 6) "v4"
- 7) "v10"
- 8) "v6"
- 9) "v7"
- 10) "v3"
- 192.168.4.57:6357>
2.日志重写
随着数据的增多,日志的大小会不断增大,我们需要重写日志缩小日志体积,这样读取日志和存日志的速度会变快
以下是Redis配置文件中的两项,分别表示的意思是,最小重写大小为64mb,最小也就是首次达到这个大小就做一次重写,以不同的方式存储数据,缩小日志体积.第二条配置的意思是重写后在达到当前最小值的100%时,再做重写
auto-aof-rewrite-min-size 64mb
auto-aof-rewrite-percentage 100
3.修复aof文件
如果你的服务器意外宕机造成你丢失了数据文件,你可以通过修复aof来重置数据
redie-check-aof --fix appendonly.aof