redis 持久化——迹忆客-ag捕鱼王app官网
redis 持久化
redis有两种对数据进行持久化的方式:rdb(redis database)和 aof(append only file):
- rdb(redis database):对数据进行快照保存。在不同的时间点,将 redis 存储的数据生成快照并存储到磁盘等介质上;
- aof(append only file):对指令进行保存。将 redis 执行过的所有写指令记录下来,在下次 redis 重新启动时,只要把这些写指令从前到后再重复执行一遍,就可以实现数据恢复了。
其实 rdb 和 aof 两种方式也可以同时使用,在这种情况下,如果 redis 重启的话,则会优先采用 aof 方式来进行数据恢复,这是因为 aof 方式的数据恢复完整度更高。
如果你没有数据持久化的需求,也完全可以关闭 rdb 和 aof 方式,这样的话,redis 将变成一个纯内存数据库,就像 memcache 一样。
rdb
工作原理
- redis调用fork(),产生一个子进程,主进程不去进行任何的io操作,这样就保证了极高的性能;
- 子进程把数据写到一个临时的rdb文件;
- 当子进程写完新的rdb文件后,把旧的rdb文件替换掉。
优点
rdb文件是一个很简洁的单文件,它保存了某个时间点的redis数据,很适合用于做备份。你可以设定一个时间点对rdb文件进行归档,这样就能在需要的时候很轻易的把数据恢复到不同的版本。
基于上面所描述的特性,rdb很适合用于灾备。单文件很方便就能传输到远程的服务器上。
比起aof,在数据量比较大的情况下,rdb的启动速度更快。
缺点
虽然 rdb 有不少优点,但它的缺点也是不容忽视的。如果你对数据的完整性非常敏感,那么 rdb 方式就不太适合你,因为即使你每 5 分钟都持久化一次,当 redis 故障时,仍然会有近 5 分钟的数据丢失。所以,redis 还提供了另一种持久化方式,那就是 aof。
错误处理
默认情况下,如果redis在后台生成快照的时候失败,那么就会停止接收数据,目的是让用户能知道数据没有持久化成功。但是如果你有其他的方式可以监控到redis及其持久化的状态,那么可以把这个功能禁止掉。
stop-writes-on-bgsave-error yes
数据压缩
默认redis会采用lzf对数据进行压缩。如果你想节省点cpu的性能,你可以把压缩功能禁用掉,但是数据集就会比没压缩的时候要打。
rdbcompression yes
数据校验
从版本5的rdb的开始,一个crc64的校验码会放在文件的末尾。这样更能保证文件的完整性,但是在保存或者加载文件时会损失一定的性能(大概10%)。如果想追求更高的性能,可以把它禁用掉,这样文件在写入校验码时会用0替代,加载的时候看到0就会直接跳过校验。
rdbchecksum yes
手动生成快照
redis提供了两个命令用于手动生成快照 和
aof
快照并不是很可靠。如果你的电脑突然宕机了,或者电源断了,又或者不小心杀掉了进程,那么最新的数据就会丢失。而aof文件则提供了一种更为可靠的持久化方式。每当redis接受到会修改数据集的命令时,就会把命令追加到aof文件里,当你重启redis时,aof里的命令会被重新执行一次,重建数据。
下图是aof的一个大概的流程
我们通过配置 redis.conf 中的 appendonly yes 就可以打开 aof 功能。
appendonly yes
如果有写操作(如 set 等),redis 就会被追加到 aof 文件的末尾。
优点
比rdb可靠。你可以制定不同的fsync策略:不进行fsync、每秒fsync一次和每次查询进行fsync。默认是每秒fsync一次。这意味着你最多丢失一秒钟的数据。
aof日志文件是一个纯追加的文件。就算是遇到突然停电的情况,也不会出现日志的定位或者损坏问题。甚至如果因为某些原因(例如磁盘满了)命令只写了一半到日志文件里,我们也可以用redis-check-aof这个工具很简单的进行修复。
当aof文件太大时,redis会自动在后台进行重写。重写很安全,因为重写是在一个新的文件上进行,同时redis会继续往旧的文件追加数据。新文件上会写入能重建当前数据集的最小操作命令的集合。当新文件重写完,redis会把新旧文件进行切换,然后开始把数据写到新文件上。
aof把操作命令以简单易懂的格式一条接一条的保存在文件里,很容易导出来用于恢复数据。例如我们不小心用flushall命令把所有数据刷掉了,只要文件没有被重写,我们可以把服务停掉,把最后那条命令删掉,然后重启服务,这样就能把被刷掉的数据恢复回来。
缺点
在相同的数据集下,aof文件的大小一般会比rdb文件大。
在某些fsync策略下,aof的速度会比rdb慢。通常fsync设置为每秒一次就能获得比较高的性能,而在禁止fsync的情况下速度可以达到rdb的水平。
在过去曾经发现一些很罕见的bug导致使用aof重建的数据跟原数据不一致的问题。
aof 重写
aof 重写的内部运行原理,我们有必要了解一下。
在重写即将开始之际,redis 会创建(fork)一个“重写子进程”,这个子进程会首先读取现有的 aof 文件,并将其包含的指令进行分析压缩并写入到一个临时文件中。
与此同时,主工作进程会将新接收到的写指令一边累积到内存缓冲区中,一边继续写入到原有的 aof 文件中,这样做是保证原有的 aof 文件的可用性,避免在重写过程中出现意外。
当“重写子进程”完成重写工作后,它会给父进程发一个信号,父进程收到信号后就会将内存中缓存的写指令追加到新 aof 文件中。
当追加结束后,redis 就会用新 aof 文件来代替旧 aof 文件,之后再有新的写指令,就都会追加到新的 aof 文件中了。
如何选择rdb和aof
对于我们应该选择 rdb 还是 aof,官方的建议是两个同时使用。这样可以提供更可靠的持久化方案。