Redis持久化选项
Redis提供了两种持久化方法来将数据存储到硬盘里面。一种方法叫快照(snapshotting),它可以将存在某一时刻的所有数据都存储在硬盘里面。另外一种放叫只追加文件(append-only file AOF),它会在执行命令时将被执行的命令复制到硬盘里面。两种方法能同时使用,也可以单独使用
快照持久化
创建快照的方式
- 客户端通过向Redis发送BGSAVE命令来创建一个快照。redis会fork一个子进程,子进程负责将快照写入硬盘。
- 客户端还可以向Redis发送SAVE命令来创建快照,在创建快照完成之前不会响应其他命令(阻塞)。一般适用于没有足够内存执行BGSAVE命令,或者有时间等持久化完成再做下一步打算的情况下,才会适用这个命令。
- 设置save配置选项,例如 save 60 10000:从Redis最近一次创建快照开始算起,当60秒内有1W次写入 才会自动触发BGSAVE命令。如果用户配置了多个save配置选项,当任意选项被满足时,Redis就会触发一次BGSAVE命令。
- 当一个Redis服务器连接另外一个Redis服务器,并向对方发送SYNC命令时,如果主服务器没有在执行BGSAVE操作或者不是刚执行完BGSAVE操作时,那么主服务器就会执行BGSAVE命令
注意:在使用快照持久化时,如果系统发生崩溃时,会丢失最近快照备份之后的所有数据。因此快照只适用对丢失一部分数据的也不影响的程序,而不能接受丢失的可以选择AOF。
快照持久化场景
- 个人开发
在个人开发服务器上,主要考虑尽可能的降低持久化带来的资源消耗,如果再生产服务器上使用快照持久化大量数据的话,应该配置一个接近生产服务器的开发服务器,以免生成快照过于频繁或者稀少
- 对日志进行聚合计算
考虑能接受丢失多久的数据,比如save 3600 1 及一小时内的数据,同时用Redis记录日志处理的相关信息,在Redis崩溃恢复后,从最近一次日志处理记录继续计算
- 大数据
当Redis存储的数据量只有几个G时,使用快照没有问题,但是如果数据量一旦变大,执行BGSAVE而导致停顿时间更长,SAVE创建快照速度比BGSAVE更快,因为SAVE会阻塞访问。可以在晚上定时执行SAVE命令。不过对于丢失15分钟、1小时以及更长的时间数据不能接受的话,可以使用AOF持久化
AOF持久化
AOF持久化会将执行的写命令写入AOF文件的末尾,以此来记录数据变换。因此Redis只要从头到尾重新执行AOF文件包含的所有写命令就可以恢复AOF文件记录的数据集。通过appendonly yes配置选择来打开。
appendfsync 选项及同步频率
- always:每个Redis写命令都要同步写入硬盘。这样做会严重降低Redis的速度。
- everysec:每秒执行一次同步,显示地将多个写命令同步到硬盘。
- no:让操作系统来决定一个何时进行同步。
如果是always选项的话,系统崩溃时会将丢失数据减小到最好,不过这种同步策略需要大量的写入,所以说Redis处理命令的速度会受到硬盘性能的限制。最重要一点,如果是固态硬盘,会导致其使用寿命大幅缩减。
为了兼顾数据安全与写入性能,用户可以考虑使用everysec选项,Redis每秒同步一次AOF文件时的性能与不使用任何持久化性能时的性能相差无几,即使出现系统崩溃,用户最多丢失1秒的数据。当硬盘忙于写操作的时候,Redis还会优雅的放慢自己速度已适应硬盘的最大写入速度。
最后no 选项,系统崩溃会丢失不定量数据,如果用户硬盘处理写入操作速度不够快,那么缓冲区被等待写入硬盘数据填满时,Redis的写入操作将被阻塞,并且处理命令请求速度会变慢,一般不推荐使用 no。
虽然AOF持久化非常灵活,但是最主要的缺陷就是---- AOF文件的体积大小。
重写/压缩AOP文件
随着Redis不断运行,其AOF文件体积也会不断增长,在极端情况下AOF文件甚至可能用完硬盘所有可用空间。还有一个问题就是文件过大,Redis重启之后需要重新执行AOF文件,过大导致执行恢复时间慢。
为了解决AOF文件体积不断变大的问题,可用使用BGREWRITEAOF命令,这个命令会移除冗余的AOF文件命令,重写AOF文件,使AOF文件体积变小。其原理与BAGESAVE创建快照相似,都是创建一个子进程。
跟快照持久化一样,AOF持久化也可以自动执行BGREWRITEAOF,其命令为:
- auto-aof-rewrite-percentage :列如100
- auto-aof-rewrite-min-size :例如64MB
含义:当AOF文件大于64MB,并且AOF文件的体积比上一次重写后的体积大了 100%,那么Redis就会自动执行BGREWRITEAOF
64MB,并且AOF文件的体积比上一次重写后的体积大了 100%,那么Redis就会自动执行BGREWRITEAOF