数据持久化

为什么需要持久化,持久化是什么

redis 是基于内存的所以速度快,没有与磁盘交互。但是缺点就是断电或宕机数据就没了,这是不可接受的

持久化就是把内存的数据也存在磁盘上,用于 redis 重启后时恢复数据

Redis 支持两种方式实现数据持久化: RDB 和 AOF

RDB(Redis DataBase)

  1. 达到触发 RDB 时,把此刻的内存数据快照(全量数据)写入磁盘,文件名为 dump.rdb,默认和配置文件同级
  2. redis 重启时会把 dump.rdb 数据恢复到内存中
  3. 可以手动执行命令触发,也可以通过配置文件自动触发

自动触发

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 文件,报保证这个文件不会被覆盖(执行上面的命令)

手动触发

  1. Redis 提供了两个命令来触发 RDB,分别是 savebasave
  2. save 会阻塞 redis 其他命令,直到 dump.rdb 文件生成完成,当 redis 数据量很大时可能会阻塞很久,所以这种方式是不建议的
  3. basave 基本不会阻塞 redis 其他命令,会 fork 一个子进程来进行快照
    • 边对缓存进行修改,边生成 dump.rdb
    • fork 也会阻塞,但是阻塞时间会远远短于 save

AOF(Append only File)

RDB 数据不是百分百靠谱,当断电、kill-9 发生时,最后一次没来得及进行持久化的数据会丢失,AOF 基本数据不会丢失(也不能说百分百,可以做到最多丢失一条写操作命令)。AOF 具有以下特点:

  1. 以日志的形式记录每个写操作的命令。比如执行命令 set k1 v1,AOF 模式会把这条命令记录到日志文件中
  2. 恢复的时候把所有日志记录的命令全量执行一遍

实现原理:

  1. 当服务器执行完一条写操作时,把这个命令写入到一个 buffer 缓冲区
  2. 虽然有三种策略,但是都是 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

  1. RDB 是在某个时刻内存数据的快照全量写入文件;AOF 是命令追加方式
  2. RDB 采用 LZF 算法压缩,压缩后的文件体积远小于内存大小;AOF
  3. RDB 最多丢失最后一次没持久化的数据;AOF 最多可以做到只丢失一条数据
  4. RDB 恢复时速度比 AOF 快的多
  5. RDB 是二进制文件,没有可读性,AOF 记录的是命令,是可以看明白的

混合方式

RDB 和 AOF 可以共存,如果 RDB 和 AOF 共存,AOF 优先级高于 RDB

重启 Redis 实例时,如果有 AOF 文件,就把 AOF 文件的数据恢复到内存,如果没有 AOF 文件,就把 RDB 文件恢复到内存

posted @ 2023-06-28 17:55  CyrusHuang  阅读(3)  评论(0编辑  收藏  举报