redis持久化关键词:RDB、AOF
1. RDB (Redis DataBase)
1.1 什么是RDB
在指定时间间隔内将内存中的数据集快照写入磁盘的dump.rdb文件中,也就是行会话Snapshot快照,他恢复时是将内存快照文件直接读取到内存里面。
1.2 工作原理
redis 会单独创建(fock)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,再将这个临时文件替换上次持久化的文件。
整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能。
如果需要进行大规模的数据恢复,且对于数据恢复的完整性不是非常敏感,那么RDB方式要比AOF方式更加的高效。RDB的缺点是最后一次持久化的数据可能丢失。
1.3 为什么要 fock 一份进程
Fork 的作用就是复制一个与当前进程一样的进程。新进程的所有数据(变量、环境变量、程序计数器等)数值都和原来的进程一样,是原进程的子进程。
隐患: 如果原进程占用了很多系统资源,fock的话就会占用成倍的系统资源。
1.4 配置RDB持久化
命令: save 秒钟 写操作次数
################################ SNAPSHOTTING ################################
# Save the DB on disk:
# save <seconds> <changes>
#
# Will save the DB if both the given number of seconds and the given
# number of write operations against the DB occurred.
# In the example below the behaviour will be to save:
# after 900 sec (15 min) if at least 1 key changed -> 15 分钟以内 一个key内 就存成一个 dump.rdb
# after 300 sec (5 min) if at least 10 keys changed -> 5 分钟以内有10个key以上被改变就存成 dump.rdb
# after 60 sec if at least 10000 keys changed -> 1 分钟内改变了 10000次
# 如果想禁用RDB持久化策略,只要不设置任何SAVE指令,或者给save设置成空字符串也可以。
save 900 1
save 300 10
save 60 10000
# 出错了的话就停止,如果是no的话表示不在乎数据的一致性或者有其他手段发现和控制
stop-writes-on-bgsave-error yes
# 对于磁盘中的快照,设置是否进行压缩存储,如果是的话会采用 LZF 算法进行压缩。
rdbcompression yes
# 存储快照之后设置redis是否使用 CRC64 算法进行数据校验。
rdbchecksum yes
# 快照文件的名称
dbfilename dump.rdb
# dump文件的目录
dir ./
当执行FLUSHALL 的时候会把内存中的k-v清空,如果此时立刻SHUTDOWN掉Redis 的话,会把此时内存的清空进行 dump。dump.rdb文件就会是空的。
如果想要快速的保存一个写操作到 dump.rdb中可以使用 save / bgsave 命令。
- save:save 时只管保存,其他的任务阻塞。
- bgsave: 后台异步备份。
127.0.0.1:6379> set name zjl
OK
127.0.0.1:6379> save
OK
127.0.0.1:6379> set name zlk
OK
127.0.0.1:6379> bgsave
Background saving started
1.5 如何恢复数据
将备份文件(dump.rdb)文件移动到 redis的安装目录启动服务即可,config get dir 获取目录。
1.6 RDB的优劣
- 优势
- 是和大规模的数据恢复
- 对数据的完整性一致性要求不高
- 劣势
- 在一定间隔时间做一次备份,如果意外挂了的话,就会丢失最后一次快照后的数据。
- Fock进程,内存中的数据被克隆了一份,会消耗系统资源。
1.7 如何停止RDB备份
# redis.conf 文件中save修改成
save ""
# 客户端命令行
redis-cli config set save ""
2. AOF (Append Only File)
2.1 什么是 AOF
以日志的形式记录每一个写操作,将Redis执行过的所有写指令记录下来(读操作不记录)(appendonly.aof文件),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之,redis重启的话根据日志文件的内容将写指令从前到后执行一次以完成数据恢复的工作。
2.2 配置
# 默认是 no 关闭状态的
appendonly yes
# The name of the append only file (default: "appendonly.aof")
appendfilename "appendonly.aof"
# 可配置一下方式
# always : 同步持久化 每次发生数据变化会被立即记录到磁盘,性能可能差点,但是数据完整性高
# everysec : 出厂默认推荐,异步操作,每秒记录 如果一秒内宕机,有数据会丢失
# no : 关闭
appendfsync everysec
# 重写的时候 是否可以用 appendsync,默认用no,保证数据的安全性
no-appendfsync-on-rewrite no
# 触发重写的默认配置是当AOF文件大小是上次rewrite后大小的一倍
auto-aof-rewrite-percentage 100
# 触发重写的默认配置且文件大于64M的时候触发。生产的时候一般是几个G以上
auto-aof-rewrite-min-size 64mb
2.3 AOF 和 RDB 共存的时候优先选谁
优先选择AOF,可以修改appendonly.aof 文件,添加些错误的命令,启动redis的时候启动报错,说明先加载的是appendonly.aof文件。
2.4 修复AOF文件
如果redis出现IO异常或者网络问题导致 appendonly.aof 出现问题,需要恢复才能启动
redis-check-aof --fix appendonly.aof
2.5 Rewrite 问题
2.5.1 Rewrite问题是什么
AOF 采用文件追加方式进行维护,文件会越来越大,为了避免出现这样的问题,新增了重写机制,当AOF文件大小超过设定的阈值的时候,Redis就会启动AOF的文件压缩,只保留可以会出数据的最小指令集,可以使用bgrewriteaof
2.5.2 重写原理
AOF文件持续增长而过大时,会fock出一个进程来将文件进行重写(先写临时文件最后在rename),遍历新进程的内存数据,每条记录有一条set语句。重写AOF的操作,并没有读取旧的AOF文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的AOF文件,这点和快照类似。
2.5.3 触发机制
Redis 会记录上一次重写时的AOF文件大小,默认配置是当AOF文件大小是上次rewrite后大小的一倍且文件大于64M的时候触发。
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
2.5.4 AOF的优劣势
- 优势
- 可以灵活配置同步时间:appendfsync
- 劣势
- 相同数据集的数据来说,AOF文件大小远大于 RDB ,恢复速度慢于 RDB。
- AOF 运行效率慢于RDB,每秒同步策略较好,不同步的效率和RDB相同。
3. 总结
-
RDB 方式能够在指定时间范围内对数据进行快照默认存储到 dump.rdb 文件中。
-
AOF 持久化方式默认每秒对服务器的写操作进行记录,当服务器重启的时候会重新执行这些命令来恢复数据,AOF命令以Redis协议追加保存每次的写操作到appendonly.aof 文件末尾。
-
AOF的重写使得AOF文件体积不至于过大。
-
Redis只做缓存的话可以不使用任何持久化方案。
-
支持同时开启两种持久化方案,默认先采用AOF方式恢复数据。
-
如果不用AOF,仅靠 Master-Slave-Replication 实现高可用性也可以。能省略一大笔IO操作,减少rewrite时带来的系统波动。代价是Master / Slave 同时挂掉,会丢失十几分钟的数据,启动脚本也要比较两个Master / Slave 中的RDB 文件,载入比较新的那个。