Redis的持久化
Redis的持久化方式有两种:快照(RDB)文件和追加文件(AOF文件) 两种方式。
RDB
基本原理
RDB这种方式的工作原理就是Redis会创建一个子进程,然后子进程把数据写到一个临时的RDB文件,当子进程写完RDB文件之后,它会将旧的RDB文件替换掉。
优点
- RDB文件很简洁,相比于后面AOF这种方式。你可以设置一个时间点对RDB文件进行归档,这样我们就能很轻易的实现将数据恢复到归档的时间点。
- RDB的性能也很好,在需要持久化时会创建一个子进程出来做持久化的工作不会影响主进程。
- 相比于AOF的方式,在数据量较大的情况下,RDB的启动速度相对于AOF会更快。
缺点
- RDB更容易丢数据。RDB通常设置的是每隔多久持久化一次,如果因为某些原因Redis挂了,那么在距离上一次持久化的这段时间内的数据将会丢失。
- 同样RDB格式因为Redis的版本不同,会存在版本兼容性的问题。有可能不同版本的Redis产生的RDB文件不兼容。
- 无法做到实时持久化。即使手动的触发,它还是需要创建子进程来处理,如果频繁执行效率上也不会太高。
相关配置
在Redis的配置文件中,我们可以查找SNAPSHOTTING节点下的相关内容找到RDB的配置信息。
保存点
你可以配置保存点,使Redis在多少秒内数据改变N次就保存快照文件。它的格式如下:
save 时间(秒) 改变次数
例如配置在30s内发生100次变动就保存快照文件。
save 30 100
同时我们可以配置多个保存策略,默认的配置文件示例中就配置了三个。如果我们想禁用快照保存策略该怎么做呢?有两种做法,第一种就是注释掉所有的保存策略,第二种就是在最后添加一条配置。配置信息如下:
save ""
错误处理
默认情况下,如果Redis持久化失败,那么就会停止接收数据,目的是为了让用户知道这个时候RDB持久化失败了。这个配置信息如下:
stop-writes-on-bgsave-error yes
如果想要禁用该功能,将该值设置成false即可。
数据压缩
默认情况下,Redis会采用LZF对数据进行压缩。不过该功能会消耗部分CPU性能,如果需要关闭该功能只需要将其设置成false即可。
rdbcompression yes
数据校验
在Redis5及以上的版本,Redis会在生成的RDB文件末尾增加一个CRC64校验码。可以通过这个校验码来检查文件是否完整,但是该配置会消耗CPU性能,如果想最求极致的性能可以将其关闭。
rdbchecksum yes
dump文件
RDB文件的文件名称和目录我们可以通过下面两个配置来设置:
# RDB文件名称
dbfilename dump.rdb
# RDB文件目录
dir ./
手动触发
默认情况下,Redis会按照我们配置的保存点来触发RDB持久化,如果我们想手动触发可以通过下面两种方式。
save
使用save命令会使用同步的方式生成RDB快照文件,这意味着在持久化的这个过程中会阻塞所有其他客户端的请求。因此在生成环境下不建议使用该命令。
bgsave
通过名称可以知道,该命令会在后台保存RDB文件,调用该命令后会立马返回OK信息。Redis会创建一个子进程来处理,然后恢复客户端的服务。
AOF
通过上面的方式我们知道了快照的方式并不是那么可靠,因为它存在快照真空期。如果我们的服务挂掉了或者Redis服务被kill掉了,而RDB文件上次持久化时间距离服务器挂了的这段时期的数据就丢失了。
相比于RDB这种方式,AOF提供了一种更加可靠的持久化方式。每当Redis接收到一个修改数据的命令时,它就会把命令通过追加写的方式写到AOF文件中。当你重启Redis时,AOF里面的命令重写执行一次,数据就恢复了。
优点
- 相比与RDB的方式更加可靠。默认情况下,可以设置每秒fsync一次,这意味着你最多丢失一秒的数据。
- AOF是通过追加写的方式写数据的。就算遇到突发情况也不会导致文件的定位和损坏问题。
- 因为AOF文件是通过追加写的方式记录的,当AOF文件太大时Redis会在后台进行重写。
- AOF把操作命令逐条写入到文件中,很容易恢复数据。例如我们把所有数据都flushall了,只要我们的AOF文件还没有被重写,那么我们可以删掉flushall命令,然后重启服务即可。
缺点
- 在相同的数据集下,AOF文件的大小一般会比RDB文件大。
- 在某些fsync策略下,AOF的速度会比RDB慢。通常设置成每秒一次能获得较高的性能。
相关配置
搜索Redis的配置文件中APPEND ONLY MODE节点的相关配置可以找到AOF的配置信息。
开启AOF
我们可以通过下面的配置开启或者关闭AOF功能,默认情况下该值为false.
appendonly yes
文件名称与目录
可以通过配置文件中的appendfilename设置AOF文件的名称,通过可以通过dir设置文件的目录。需要注意的是,dir该配置与RDB是共用的。
appendfilename "appendonly.aof"
可靠性
Redis调用fsync的频率有三个选项可以选择:
- appendfsync always 每当有新命令追加到AOF的时候调用fsync。速度最慢,但是最安全。
- appendfsync everysec 每秒调用一次fsync,安全性比较不错,最多丢失1s的数据,速度也快。
- appendfsync no 从不主动调用fsync,交由系统去处理。这个方式速度最快,但是安全性一般。
# appendfsync always
appendfsync everysec
# appendfsync no
日志重写
随着修改操作不断增多,AOF文件会越来越大。AOF会执行重写操作,例如我们将一个计数器持续不断的增加了1万次,而实际上我们可以把这一万次命令改成一次增加1万即可,这样命令就被精简成一条了。Redis提供了在后台重建AOF文件的功能,而重写的触发条件可以通过下面两个选项配置:
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
Redis会记住上次重写后的AOF文件大小,如果当前的AOF文件超过了上一次文件大小的百分比,那么就会触发重写。同时还要设置一个文件的最小值,防止很小的时候就已经超过了百分比而进行重写。
如果需要禁用重写功能,可以设置这个百分比为0禁用重写。
auto-aof-rewrite-percentage 0
no-appendfsync-on-rewrite
该配置的作用是在后台执行AOF重写时fsync设置为no。
当AOF的fsync配置为everysec或者always时,并且后台运行着RDB的save或者AOF的重写时,会消耗大量的磁盘性能。在某些linux配置下,aof同步到磁盘执行fsync将被阻塞很长时间。
目前并没有解决办法,为了减轻这个问题,可以将该配置设置成no防止在执行save或者aof重写时在主线程fsync。这意味着appendfsync为0,这很可能导致数据的丢失。如果你对延迟有问题,可以将该值设置成yes,如果你更需要保证数据的完整性应该将其设置成false。
no-appendfsync-on-rewrite no
aof-load-truncated
该配置的作用是当发生AOF文件末尾截断时,是加载文件还是报错退出。
aof-load-truncated yes
如果该值为yes时,文件将被加载,将会打印日志知用户。如果为no时,服务将拒绝启动。我们需要使用redis-check-aof工具修复AOF文件再重新启动。
RDB-AOF混合方式
在Redis的在4.0的版本增加了新的混合持久化方式。混合持久化方式同时结合了RDB和AOF的持久化方式将数据写入AOF文件中。这样做的好处是可以结合RDB和AOF的优点,快速加载数据同时避免丢失过多数据。默认情况下,如果开启AOF,该配置也默认开启。
aof-use-rdb-preamble yes
总结
对于RDB和AOF的持久化方式,它们都有自身的优缺点。我们更应该结合自己的业务实际情况选择合理的持久化方案,对于其中的配置作用,更多可以参照Redis中给出的示例配置文件注释和官网文档信息进行了解。