Redis持久化之RDB & AOF

1. 为何须要持久化?

Redis的读写和响应速度为何如此之快?不一样于传统的关系型数据库,Redis的数据库是所有加载在实时内存中的,读写操做可以直接在内存中进行,省去了大量IO操做,所以性能很是优越。但一切依托于内存的服务都有个最大的软肋,那即是在设备出现故障(如断点)时,内存中全部的实时数据都将会丢失。为了解决这个问题,Redis中提供了两种持久化方案:RDB和AOF,其机制实际上都是设法将内存中的数据以文件的形式备份到磁盘上,从而解决断电等机器故障致使数据丢失的问题。redis

2. RDB (Redis DataBase)

实现机制:Redis会单首创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程结束后,再用这个临时文件替换上次持久化好的文件(dump.rdb)。整个过程当中,主进程不会进行任何IO操做的,这样就可以保证Redis主进程持续的高性能。在恢复数据时,重启后会Redis会自动加载工做目录下的dump.rdb文件恢复数据到内存算法

相关参数数据库

## 设置触发RDB dump的条件,在<seconds>时间至少发生了<changes>次数据的操做,则<seconds>时间到了就将数据写到磁盘中,为dump.rdb  Redis默认设置了三个条件,知足之一便可触发。移除全部条件或者设置 save 后加空字符串为禁用RDB功能
save <seconds> <changes>
save 900 1          ## for 低频写入    
save 300 10          ## for 中频写入
save 60 10000              ## for 高频写入

## 设置当RDB进程出现故障时,Redis是否中止写操做,默认为yes
stop-writes-on-bgsave-error yes

## 设置RDB时是否使用LZF压缩算法对dump.rdb文件进行压缩,默认yes
rdbcompression yes

## 设置是否对dump.rdb文件进行校验,默认CRC64校验算法,会消耗RDB进程的CPU资源的10%,默认开
rdbchecksum yes

## 设置输出文件名, 默认dump.rdb
dbfilename dump.rdb

## 设置dump.rdb文件输出路径,默认为当前启动工做目录
dir ./

优点安全

  • 不管是持久化过程仍是数据恢复过程,RDB的速度都很是快
  • 用户可以手动设置参数以控制持久化的频率,应用场景更加灵活
  • 适合大规模且对数据的完整性和一致性要求不高的数据恢复,

劣势app

  • RDB的持久化须要fork一条子线程,且子线程将会copy主线程全部数据,至关于设备的内存使用临时翻了一倍,在数据量特别大的状况下使用RDB可能有内存溢出风险
  • 最后一次持久化的数据可能丢失,所以对数据完整性比较敏感的业务不建议使用RDB进行持久化

PLUS:为何最后一次持久化的数据可能丢失?异步

RDB经过设置save <seconds> <changes>条件来触发dump,其机制为知足任一save条件后再该条件的<seconds>后进行刷写,但实际上可能最后一次dump时虽然达到修改次数<changes>要求,但在时间还未到达时redis进程停止,则这一阶段的数据就丢失了。 好比save 300 10这一条件,Redis在300s内的修改操做次数超过了10次,所以触发持久化条件,系统将会在300s到期后进行刷写,可是可能在到期前几秒,设备异常关机,那么这300s内产生的数据修改信息将会所有丢失

3. AOF(Append Only File)

实现机制:与RDB直接写原数据不一样,AOF记录的是Redis自启动期间全部的写操做,相似于日志,且写入的方式只容许在末尾追加,不容许修改以前写入的内容,默认保存为appendonly.aof文件。恢复数据时,Redis将AOF加载到内存并执行其中的每一条数据进行数据的恢复。性能

相关参数优化

## 启动开关  --  默认关闭
appendonly no 

## 文件名
appendfilename "appendonly.aof"

## 刷写频率
appendfsync always       ## 同步持久化,每当有数据变动就当即记录到磁盘,性能较差但数据完整性好
appendfsync everysec    ## 出厂默认配置,异步操做,每秒记录,若是一秒内宕机,则会有数据丢失
append no        ## 不设置刷写频率,当Redis本身触发刷写条件时才进行刷写

优点线程

  • 默认的刷写频率为每秒一次,所以可以最大程度地保证数据的完整性
  • AOF只是记录运行时的写操做,并不会复制全部主线程数据,所以发生内存溢出的风险较小

劣势日志

  • 只支持追加形式写入,所以造成的appendonly.aof文件会愈来愈大,会影响Redia恢复数据的性能
  • 恢复数据时须要Redis执行appendonly.aof记录的每条指令,恢复速度较慢
  • 实际上操做指令有很大的整合空间,好比10000条自增1语句能够归并为一条自增10000语句,AOF在这方面仍然有较大可优化空间

Rewrite机制:为解决appendonly.aof文件会愈来愈大的隐患,AOF设置了Rewrite机制,默认当appendonly.aof文件大小达到了上次Rewrite后appendonly.aof文件的大小时而且文件的大小超过64M,AOF将会启动Rewrite,fork出一条新进程建立一个临时文件,而后遍历整个数据库,将每一个key、value对以Redis命令的格式输出到临时文件。这一过程会将多个键值对集合起来用一条命令表达以减少最终文件的大小。在rewrite期间的写操做会保存在内存的rewrite buffer中,rewrite成功后这些操做也会append到临时文件中,rewrite完成后该临时文件便会代替appendonly.aof文件

## 触发Rewrite条件 -- and -- 

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

## 发生重写时是否支持appendfsync刷写? 默认为no,保证数据安全
no-appendfsync-on-rewrite no

4. 小结

使用场景

  • RDB适合数据流大、数据恢复快但对数据完整性依赖不高的业务,好比用户行为分析等
  • AOF则适合对数据完整性有很高限制的业务,好比银行金融类业务

共存性
官方虽然默认关闭AOF功能,但实质上RDB和AOF是能够共存的,当Redis同时开启了AOF和RDB持久化,Redis重启时会优先读取AOF文件进行数据恢复,由于AOF比RDB更能保证数据完整性。此外,因为Redis数据的恢复须要读取AOF文件或者RDB文件,所以,为了防止这两个文件出现损毁或者被恶意修改,Redis提供了两个修复脚本专门修复这两个文件

## 修复AOF文件
redis-check-aof  --fix appendonly.aof

## 修复RDB文件
redis-check-dump --fix dump.rdb

安全性拓展
实际生产时,不管是AOF仍是RDB,都须要将生成的appendonly.aof和dump.rdb文件进行异地备份,这样才能避免单机完全损坏形成的数据不可恢复问题