redis持久化:如何把内存数据写回磁盘
redis持久化有两种方式:RDB(Redis DataBase)和AOF(Append Only File)
RDB
RDB持久性是以指定的时间间隔执行数据集的时间点快照。类似于照片记录方式,就是把某一时刻的数据和状态以文件的形式写到磁盘上,也就是快照。这个快照文件称之为RDB文件(dump.rdb),其中RDB就是Redis DataBase缩写。
Redis的数据都在内存中,保存备份时它执行的是全量快照,也就是说,把内存中的所有数据都记录到内存上。RDB保存的文件叫做dump.rdb
RDB配置说明
- 自动触发:
- 首先配置redis7.conf配置文件:
# 1h内有1次修改 # * After 3600 seconds (an hour) if at least 1 change was performed # 5min内有100次修改 # * After 300 seconds (5 minutes) if at least 100 changes were performed # 1s内有10000次修改 # * After 60 seconds if at least 10000 changes were performed # # You can set these explicitly by uncommenting the following line. # # save 3600 1 300 100 60 10000 # 5s内有两次修改即可写回磁盘 save 5 2 # 修改dump.rdb存储路径(文件夹需要提前建立好) dir /myredis/dumpfiles # 修改备份文件名称 dbfilename dump6379.rdb
- 关于备份文件如何恢复问题:将备份文件(dump.rdb)移动到redis安装目录并启动服务即可。
- 手动触发
- save: 在主程序执行会阻塞当前redis服务器,直到持久化工作完成。执行save命令期间,redis不能处理其它命令,线上禁止使用。
- bgsave(默认): redis会使用bgsave对当前的内存中的额所有数据做快照,这个操作是子进程在后台完成的,这就允许主进程同时可以修改数据。使用lastsave命令获取最后一次成功执行快照的时间。
RDB优缺点
- 优点:
- RDB非常适合灾难恢复,它是可以远程传输到数据中心的压缩文件。
- DB最大限度的提高了redis的性能,子进程只需要完成IO持久化操作,而父进程永远不会执行IO操作。
- 与AOF相比,RDB允许大数据集更快的重启(RDB文件在内存中的加载速度要比AOF快得多)。
- 在副本上,RDB支持重启和故障转移后的部分重新同步。
- 缺点:
- RDB如果由于任何原因没有正确关闭的情况下停止工作,您应该做好丢失最新部分的数据准备。
- RDB需要经常fork()以使用子进程在磁盘上持久化,如果数据集很大,fork()可能会消耗很多系统资源,此外,在fork()的时候,内存中的数据被克隆了一份,大致2倍的膨胀性,这里需要考虑。
检查和修复RDB文件
如果RDB文件出现破损时,可以使用如下命令进行检查修复:
redis-check rdb /myredis/dumpfiles/dump6379.rdb
哪些情况会触发RDB操作
- 配置文件中默认的快照配置
- 手动触发save/bgsave命令。
- 执行flushall/flushdb命令,但dump.rdb里面是空的。
- 执行shutdown且没有设置开启AOF持久化。
- 主从复制时,主节点自动触发。
如何禁用快照(不想用redis持久化)
- 动态所有停止RDB保存规则的方法(本次生效):redis-cli config set save ""
- 快照禁用:在配置文件redis7.conf中修改(永久):save ""
RDB优化配置项
在redis7.conf配置文件中:
# YES:如果bgsave出现快照写入失败的时候立马停止写入;NO:如果快照写入失败,也能确保redis继续接受新的写请求。
stop-writes-on-basave-error yes(no)
# 对于存储到磁盘的快照,可以设置是否进行压缩存储,如果是的话,redis会采用LZF算法,如果你不想小号CPU来进行压缩的话,可以设置关闭此功能。
rdbcompression yes(no)
# 在存储快照后,可以让redis使用CRC64算法进行数据校验,但是会增加性能消耗。
rdbchecksum yes(no)
# 在没有持久性的情况下删除复制中使用的RDB文件启用。默认情况下是no,此选项是禁用的
rdb-del-sync-files no
AOF
以日志的形式记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不用记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据。换言之,redis重启的话就根据日志文件的内容将写指令从前到后执行一次完成数据的额恢复操作。
默认情况下,redis是没有开启AOF(Append only File)的。开启AOF功能需要在redis.conf配置文件中进行配置:appendonly yes,AOF保存的文件是appendonly.aof文件。
AOF持久化工作流程
- Client客户端作为命令的来源,会有多个源头以及源源不断的请求命令。
- 在这些命令到达redis server以后并不是立刻写入AOF文件中,而是将这些命令先缓存到AOF缓冲区中,当存在的命令数量到达一定量后再统一写回磁盘,避免频繁的IO操作。
- AOF缓冲区会根据AOF缓冲区同步文件的三种写回策略将命令写会磁盘的AOF文件中。
- 随着写入AOF内容的增加为避免文件膨胀,会根据规则进行命令的合并(又称AOF重写),从而起到AOF文件压缩的目的。
- 当redis server重启以后会从AOF文件载入数据。
AOF缓冲区三种写回策略
在redis.conf配置文件中配置写回策略:appendfsync everysec(默认)
- Always: 同步写回,每个写命令执行完立即同步地将日志写回磁盘(命令永不丢失但是IO开销较大)。
- Everysec: 每秒写回,每个写命令执行完,只是先把日志写到AOF缓冲区中,每隔1s把缓冲区的数据写回磁盘(兼顾两种的优点)。
- no: 操作系统控制的写回,每个命令执行完后,只是先把日志写到AOF内存缓冲区中,由操作系统决定何时将缓冲区的数据写回磁盘(IO开销最小,丢失数据可能性很大)。
AOF配置/启动/修复/恢复
AOF文件配置:
- 开启AOF:在redis.conf配置文件中打开:appendonly yes
- 使用默认的写回策略(每秒钟):在redis.conf配置文件中打开:appendfsync everysec
- aof文件保存路径:在redis.conf配置文件中打开:dir /myredis(自定义)
- aof文件名修改:在redis.conf配置文件中打开:appenddirname "myredis/appendonlydir/xxx.aof"
AOF正常恢复:
- 重启redis然后重加载,结果OK。
AOF异常恢复:
- 故意乱写正常的AOF文件,模拟网络闪断文件写error
- 重启redis之后就会进行AOF文件的载入,发现启动都不行。
- 异常修复命令:redis-check-aof --fix进行修复
- 重启OK
AOF优势和劣势
优点:
- 更好的持久,写入性能很好,因为写回策略是后台线程执行的。
- AOF日志不会出现寻道问题,也不会在断电时出现损坏,出于某种原因导致写回出错,可以使用redis-check-aof工具进行修复。
- 当AOF太大时,redis可以在后台自动重写AOF,重写是完全安全的。
缺点
- AOF文件相比于RDB文件更大,且恢复速度要慢于RDB。
- AOF运行效率慢于RDB。
AOF重写机制
AOF随着写入越来越大,当AOF文件的大小超过所设定的峰值时,Redis就会自动启用AOF文件内容压缩。只保留可以恢复数据的最小指令集或者可以手动使用命令bgrewriteaof来重新更新。
触发机制:
-
自动触发:在配置文件redis.conf中进行如下配置:
# 根据上次重写后的AOF大小,判断当前AOF文件大小是不是增长了1倍,就启动重写机制 auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb
-
手动触发:客户端手动想服务器发送bgrewriteaof命令。
AOF重写不仅降低了文件的占用空间,同时更小的AOF文件也可以更快的额被redis加载。
重写原理:
- 再重写开始前,redis会创建一个重写子进程,这个子进程会读取现有的AOF文件,并将其包含的指令进行分析压缩并写入到一个临时文件中。
- 与此同时,主进程会将接收到新的写指令一边积累到内存缓冲区中,一边继续写入到原有的AOF文件中,这样做是保证原有的AOF文件的可用性,避免再重写过程中出现意外。
- 当重写子进程完成重写工作后,它会给父进程发送一个信号,父进程收到信号后会将内存中缓存的写指令追加到新的AOF文件中。
- 当追加结束后,redis就会使用新的AOF文件来代替旧的AOF文件,之后再有新的写指令,就都会追加到新的AOF文件中。
- 重写AOF文件的操作,并没有读取旧的AOF文件,而是将整个内存的数据库内容用命令的方式重写了一个AOF文件,这个和快照有点类似。
AOF优化配置
配置文件APPEND ONLY MODE模块
- appendonly:是否开启aof
- appendfilename:文件名称
- appendfsync:同步方式
- no-appendfsync-no-rewrite:aof重写期间是否同步
- auto-aof-rewrite-percentage auto-aof-rewrite-min-size:重写触发配置,文件重写策略。
RDB-AOF混合持久化
RDB与AOF可以同时开启,但AOF优先于RDB。因此在redis重启时只会加载AOF文件,不会加载RDB文件,因为通常情况下AOF文件保存的数据集比RDB更完整
纯缓存模式
同时关闭RDB和AOF,只是单纯的做缓存用,不用持久化。
如何开启纯缓存模式
- 禁用RDB:save ""
- 禁用AOF:appendonly no