数据持久化
为什么需要持久化,持久化是什么
redis 是基于内存的所以速度快,没有与磁盘交互。但是缺点就是断电或宕机数据就没了,这是不可接受的
持久化就是把内存的数据也存在磁盘上,用于 redis 重启后时恢复数据
Redis 支持两种方式实现数据持久化: RDB 和 AOF
RDB(Redis DataBase)
- 达到触发 RDB 时,把此刻的内存数据快照(全量数据)写入磁盘,文件名为 dump.rdb,默认和配置文件同级
- redis 重启时会把 dump.rdb 数据恢复到内存中
- 可以手动执行命令触发,也可以通过配置文件自动触发
自动触发
redis6 及以前的版本默认的自动触发配置如下(配置文件 snapshotting 部分):
################################ 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 分钟内只要有 1 个 key 变化,就进行 dump
# after 300 sec (5 min) if at least 10 keys changed, 如果 5 分钟内达到 300 个 key 变化,就进行 dump
# after 60 sec if at least 10000 keys changed, 如果 1 分钟内达到 10000 个 key 变化,就进行 dump
#
# Note: you can disable saving completely by commenting out all "save" lines.
#
# It is also possible to remove all the previously configured save
# points by adding a save directive with a single empty string argument
# like in the following example:
#
# save "" 关闭持久化(只想把 redis 作为缓存,有没有数据都没关系适用)
save 900 1
save 300 10
save 60 10000
redis7 把三条命令合成一条了,默认的配置如下:
save 3600 1 300 100 60 10000
其他相关配置
# 文件名称
dbfilename dump.rdb
# 文件保存路径
dir /home/work/app/redis/data/
# 如果持久化出错,主进程是否停止写入(如果关闭持久化功能,这里要改为 no,不然会报错,亲身经历)
stop-writes-on-bgsave-error yes
# 是否压缩
rdbcompression yes
# 导入时是否检查
rdbchecksum yes
# 关闭 RDB(如果要开始,注释掉,默认是开启的)
save ""
注意点
- 执行 flushall、flushdb、shutdown 命令时也会生成一个 dump.rdb 文件
- 如果要恢复有数据的 dump.rdb 文件,报保证这个文件不会被覆盖(执行上面的命令)
手动触发
- Redis 提供了两个命令来触发 RDB,分别是
save
和basave
save
会阻塞 redis 其他命令,直到 dump.rdb 文件生成完成,当 redis 数据量很大时可能会阻塞很久,所以这种方式是不建议的basave
基本不会阻塞 redis 其他命令,会 fork 一个子进程来进行快照- 边对缓存进行修改,边生成 dump.rdb
- fork 也会阻塞,但是阻塞时间会远远短于
save
AOF(Append only File)
RDB 数据不是百分百靠谱,当断电、kill-9 发生时,最后一次没来得及进行持久化的数据会丢失,AOF 基本数据不会丢失(也不能说百分百,可以做到最多丢失一条写操作命令)。AOF 具有以下特点:
- 以日志的形式记录每个写操作的命令。比如执行命令
set k1 v1
,AOF 模式会把这条命令记录到日志文件中 - 恢复的时候把所有日志记录的命令全量执行一遍
实现原理:
- 当服务器执行完一条写操作时,把这个命令写入到一个 buffer 缓冲区
- 虽然有三种策略,但是都是 fork 一个子进程把 buffer 缓冲区的数据写入 aof 文件
always
:立马写入 aof 文件everysec
,每隔一秒把缓冲区中的内容写入 aof 文件no
:操作系统控制的写回
AOF 相关配置如下(在 APPEND ONLY MODEL 模块):
# AOF 持久化开关,默认是关闭的
appendonly no
# AOF持久化的文件名,默认是appendonly.aof
appendfilename "appendonly.aof"
# AOF文件的保存位置和RDB文件的位置相同,都是通过dir参数设置的
dir ./
# 同步策略,有三种:always、everysec、no
appendfsync everysec
# 重写 aof 文件时,是否暂停新的数据写入 aof(重写指的是重写 aof 文件,压缩 aof 空间,把 aof 文件变的小一点)
no-appendfsync-on-rewrite no
# 重写 aof 触发条件,这两个条件是并且关系,同时达到才触发重写
auto-aof-rewrite-percentage 100 # 本次重写前后的 aof 文件大小占比百分比,这里是当达到 100% 时
auto-aof-rewrite-min-size 64mb # 这里是 aof 文件大于 64m 时
# 加载 aof 出错如何处理,如果是 yes,尝试加载可用部分
aof-load-truncated yes
# 文件重写策略
aof-rewrite-incremental-fsync yes
RDB VS AOF
- RDB 是在某个时刻内存数据的快照全量写入文件;AOF 是命令追加方式
- RDB 采用 LZF 算法压缩,压缩后的文件体积远小于内存大小;AOF
- RDB 最多丢失最后一次没持久化的数据;AOF 最多可以做到只丢失一条数据
- RDB 恢复时速度比 AOF 快的多
- RDB 是二进制文件,没有可读性,AOF 记录的是命令,是可以看明白的
混合方式
RDB 和 AOF 可以共存,如果 RDB 和 AOF 共存,AOF 优先级高于 RDB
重启 Redis 实例时,如果有 AOF 文件,就把 AOF 文件的数据恢复到内存,如果没有 AOF 文件,就把 RDB 文件恢复到内存