Redis提供了两种不同的持久化方法来将数据存储到硬盘里面。一种方法叫快照(snapshotting),它可以将存在于某一时刻的所有数据都写入硬盘里面。另一种方法叫只追加文件(append-only file,AOF),它会在执行写命令的时候,将被执行的写命令复制到硬盘里面。这两种持久化方法既可以同时使用,也可以单独使用,具体要看我们的数据和应用来决定。
在Redis的配置文件中有两组不同的配置选项控制着Redis将数据写入硬盘的方式。下图展示了这些配置和示例配置值。
第一组配置基本的快照选项,像是存储的快照文件名,自动存储快照的频率,是否压缩快照,以及是否在创建失败时继续接受写入操作。
第二组配置AOF持久化,告诉Redis是否启用AOF持久化,将写入内容同步到硬盘的频率,在AOF压缩时能否执行同步操作。
dir ./表名了快照文件和AOF文件共同的存放路径。
1.快照持久化
Redis可以通过创建快照来获得存储在内存里面的数据在某个时间点上的副本。在创建快照之后,用户可以对快照进行备份,可以将快照复制到其他服务器从而创建具有相同数据的服务器副本,还可以将快照留在原地以便重启服务器时恢复数据。
根据配置快照将被写入dbfilename选项指定的文件里面,并存储在dir选项指定的路径上面。如果在新的快照文件创建完毕之前,Redis、系统或者硬盘这三者之一任意一个崩溃了,那么Redis将丢失最近一次创建快照之后写入的所有数据。
创建快照文件有以下几种办法:
- 任何Redis客户端可以通过调用
BGSAVE
命令创建一个快照。Redis将会创建一个子进程写入快照到硬盘,父进程继续响应其他Redis命令。 - Redis客户端同样可以调用
SAVE
命令创建一个快照,该命令将会导致Redis停止响应任何其他所有的命令,直到快照写入完成。这条命令并不常用,只有这几种情况可能会用,需要保存所有的数据到硬盘,并且允许等到快照完成,或者我们没有足够的内存执行BGSAVE
。 - 如果Redis配置了
save
行,比如save 60 10000
,表示自上次成功保存起,如果在60秒内已经发生10,000次写入,那么将会自动触发一个BGSAVE
操作。当多行save
被定义时,任何时间任意一行匹配到,都会触发一个BGSAVE
。 - 当Redis收到一个
SHUTDOWN
命令,或收到一个标准的TERM
信号时,Redis将会执行一个SAVE
,阻断任何客户端执行进一步的命令,然后关闭。 - 如果一个Redis服务器连接到另一个Redis服务器,并且发起
SYNC
命令开启主从同步,并且主服务器不是正在执行BGSAVE
操作或者不是刚刚执行完BGSAVE
操作,那么主Redis将会启动一个BGSAVE
操作。
如果只使用快照保存数据,如果发生崩溃,你将会丢失自上次快照以来所有的数据改变。如果我们能够妥善的处理快照持久化可能会带来的大量数据丢失,那么快照持久化是一个不错的选择,如果这种类型的丢失数据是不可接受的,那么我们可以使用AOF持久化来将内存里的数据尽快的保存到硬盘上。
2.AOF持久化
简单来说,AOF持久化会将被执行的写命令写到AOF文件的末尾,以此来记录数据发生的变化。因此,Redis只要从头到尾执行一次AOF文件包含的所有写命令,就可以恢复AOF文件所记录的数据集。AOF持久化通过设置 appendonly yes 配置选项来打开,而appendfsync配置选项则可以设置AOF文件的同步频率。
选项 | 同步频率 |
---|---|
always | 每次写命令都会导致redis将操作写入硬盘。这将导致Redis性能大幅下降 |
everysec | 每秒执行一次同步,显示的同步写命令到硬盘 |
no | 让操作系统来决定应该何时进行同步 |
如果我们使用appendfsync always的话,那么每个写命令都会被写入硬盘,从而将发生系统崩溃时出现的数据丢失减到最少。不过遗憾的是,因为这种同步策略需要对硬盘进行大量的写入,所以Redis的处理命令的速度回收到硬盘性能的影响。
如果我们使用appendfsync everysec的话,Redis会以每秒一次的频率对AOF文件进行同步。Redis每秒同步一次AOF文件时的性能和不使用任何持久化机制时的性能相差无几,而且出现系统崩溃时我们最多也只会丢失1秒钟写入的数据。当硬盘忙于执行写入操作的时候,Redis还会放慢自己的速度以适应硬盘的最大写入速度。
最后如果使用appendfsync no选项,这个选项不会对Redis的性能造成影响,但是当系统崩溃的时候将丢失不定量的数据,所以一般来说不推荐使用这种机制。
Append-only files很灵活,提供各种选项确保几乎所有级别问题可以处理。但是AOF也有不利的一面,那就是文件容量。因为Redis会不断地将写命令记录到AOF文件里面,所以随着Redis的不断运行,AOF文件的体积也会不断增长,另一方面,因为Redis在重启之后需要通过重新执行AOF文件记录的所有写命令来还原数据,如果AOF文件的体积非常大,那么还原操作的执行时间可能会非常长。
想解决AOF容量占用越来越高的问题,我们可以向Redis发送BGREWRITEAOF命令
,这会通过移除AOF文件中的冗余命令来重写AOF文件,使AOF文件的体积变得尽可能的小。 BGREWRITEAOF工作方式非常类似于快照BGSAVE: 执行一个子进程,然后在子进程执行重写AOF文件。因此,快照持久化因为创建子进程而导致的性能问题和内存占用问题,在AOF持久化中也同样存在。更糟糕的是,因为AOF文件的体积可能比快照文件的体积大好几倍,当时AOF重写时,删除一个非常大的AOF文件可能导致系统挂起好几秒。
使用快照时,我们可以使用save
配置选项启用自动使用BGSAVE写入快照。使用AOF持久化时,有两个配置选项自动启用BGREWRITEAOF的执行: auto-aof-rewrite-percentage
和auto-aof-rewrite-min-size
。举个例子,假设我们设置了auto-aof-rewrite-percentage 100
和auto-aof-rewrite-min-size 64mb
,并且启用了AOF持久化,那么当AOF文件的体积大于64MB,并且AOF文件的体积比上一次重写之后的体积大了至少一倍(100%)的时候,Redis将执行BGREWRITEAOF命令。如果我们的AOF重写太频繁,我们可以将auto-aof-rewrite-percentage提高到100以上,这种做法可以让Redis在AOF文件的体积变得更大的时候才执行重写操作,但是这也会让Redis在启动还原数据时花费更长的时间。
最后,无论是使用AOF持久化还是快照持久化,将Redis数据保存到硬盘上都是很有必要的。当我们同时开启AOF持久化和快照持久化的时候,Redis将使用AOF文件来恢复数据。
参考:
https://www.gitbook.com/book/abcfy2/redis-in-action-reading-notes/details
转载请注明出处。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Redis的持久化选项 - Python技术站