我们知道Redis 本身就支持pub/sub 模式,设计消息系统也会变得简单,可以作为ActiveMQ、RocketMQ 的替代方案。
今天要介绍的是关于Redis 的持久化方面的内容。
在Redis 出现之前,比较流行的是缓存方案是 memcache ,相比于后者是纯内存键值系统来说,Redis 增加了原生的dump 到持久化设备(磁盘)上的能力,具体来说:就是支持以某种机制将内存中的数据镜像到磁盘上,可以当作是 memcache + memcachedb。
Redis 主要是有两种持久化的方式:快照(RDB文件)和追加式文件(AOF文件)
- RDB 持久化是在一个特定的时间间隔生成一份数据快照
- AOF (Append Only File)持久化是记录Redis 服务收到的每一个写请求
一、RDB
RDB 是Redis 默认的持久化方式,就是快照(snapshotting)存储,按照一定的策略周期性的将数据保存到磁盘。
################################ SNAPSHOTTING ################################
这里的策略可以在redis.conf 中进行配置:
save 900 1 #900 秒后至少1个key有变动
save 300 10 #300 秒后至少10个key有变动
save 60 10000 #60 秒后至少10000个key有变动
备份后会产生对应的备份文件dump.rdb ,存放的目录也是可配置:
dir /var/redis/data
配置后的Redis 是如何在运行时生成快照的呢? 这里Redis 借助了fork 命令的 copy on write 机制,在生产快照时,将当前进程fork 出一个子进程,然后在子进程中循环所有的数据,将数据写成 RDB 文件。
此外,Redis Client 也可以手动的使用save 或者 bgsave 命令通知redis 做一次快照的持久化。不过这种情况下,save操作是在主线程中保存快照,由于redis 是用一个主线程来处理所有client 请求,这种方式会阻塞所有的client 请求,所以一般不要这么操作。
优点:
- RDB文件是一个很简洁的单文件,它保存了某个时间点的Redis数据,很适合用于做备份。你可以设定一个时间点对RDB文件进行归档,这样就能在需要的时候很轻易的把数据恢复到不同的版本。
- RDB很适合用于灾备。单文件很方便就能传输到远程的服务器上。
- RDB的性能很好,需要进行持久化时,主进程会fork一个子进程出来,然后把持久化的工作交给子进程,自己不会有相关的I/O操作。
- 比起AOF,在数据量比较大的情况下,RDB的启动速度更快。
缺点:
- RDB容易造成数据的丢失。假设每5分钟保存一次快照,如果Redis因为某些原因不能正常工作,那么从上次产生快照到Redis出现问题这段时间的数据就会丢失了。
- RDB使用fork 产生子进程进行数据的持久化,如果数据比较大的话可能就会花费点时间,造成Redis停止服务几毫秒。如果数据量很大且CPU性能不是很好的时候,停止服务的时间甚至会到1秒。
二、AOF
在上面的缺点第一点中有提到,快照并不是很可靠。如果突发意外,服务器突然崩了,那上一个快照点到当前的数据就会全部丢失。AOF 则是一种更为可靠的持久化方式。
在redis.conf 文件中可以配置
############################## APPEND ONLY MODE ###############################
将appendonly 设为yes 默认为no
appendonly yes
默认文件名是appendonly.aof
也可以配置Redis 调用fsync 的频率。主要有三种方式:
- 每当有新命令追加到AOF的时候调用fsync。速度最慢,但是最安全。
- 每秒fsync一次。速度快(2.4版本跟快照方式速度差不多),安全性不错(最多丢失1秒的数据)。
- 从不fsync,交由系统去处理。这个方式速度最快,但是安全性没有保证。
推荐使用每秒fsync一次的方式(默认的方式),因为它速度快,安全性也不错。相关配置如下:
# appendfsync always
appendfsync everysec
# appendfsync no
优点:
- 比RDB可靠。你可以制定不同的fsync策略:不进行fsync、每秒fsync一次和每次查询进行fsync。默认是每秒fsync一次。这意味着你最多丢失一秒钟的数据。
- AOF日志文件是一个纯追加的文件。就算服务器突然崩了,也不会出现日志的定位或者损坏问题。甚至如果因为某些原因(例如磁盘满了)命令只写了一半到日志文件里,我们也可以用 redis-check-aof 这个工具很简单的进行修复。
- 当AOF文件太大时,Redis会自动在后台进行重写。重写很安全,因为重写是在一个新的文件上进行,同时Redis会继续往旧的文件追加数据。新文件上会写入能重建当前数据集的最小操作命令的集合。当新文件重写完,Redis会把新旧文件进行切换,然后开始把数据写到新文件上。
- AOF把操作命令以简单易懂的格式一条接一条的保存在文件里,很容易导出来用于恢复数据。例如我们不小心用flushall 命令把所有数据刷掉了,只要文件没有被重写,我们可以把服务停掉,把最后那条命令删掉,然后重启服务,这样就能把被刷掉的数据恢复回来。
缺点:
- 在相同的数据集下,AOF文件的大小一般会比RDB文件大。
- 在某些fsync策略下,AOF的速度会比RDB慢。通常fsync设置为每秒一次就能获得比较高的性能,而在禁止fsync的情况下速度可以达到RDB的水平。