redis 持久化

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

redis 是基于内存的所以速度快,没有与磁盘交互。但是缺点就是断电或宕机数据就没了,这是不可接受的。持久化就是把内存的数据也存在磁盘上,用于 redis 重启后时恢复数据。两种方式 RDB 和 AOF

RDB

快照操作,持久化当前内存中的数据。分为手动触发和自动触发

手动触发

save 命令:同步方式,在持久化未完成前阻塞 redis 主进程(不用想了,直接 pass,相当于某个时间段内 redis 不可用了)

bgsave 命令:异步方式,执行 fork 操作开启一个子进程来持久化,这样就能一边继续提供服务(主进程),一边做持久化(子进程)。也会阻塞 redis,只不过时间非常短,只是 fork 的操作过程阻塞,fork 完成意味着子线程已经创建好了,就不会阻塞了

持久化过程

  1. 执行命令
    1. 如果是 save ,阻塞 redis 主进程
    2. 如果是 basave,阻塞 redis 主进程,fork 一个子进程,子进程创建成功后释放 redis 主进程
  2. 当前内存所有数据写入 rdb 文件(注意是替换文件,每次手动持久化后产生的 rdb 内容都是不一样的,持久化完成后替换文件)
  3. 持久化完成,通知 redis 主进程,做一些统计信息;如果是 save 命令触发的,释放 redis 主进程

自动触发

配置文件配好了规则自动触发 bgsave 来异步持久化,规则配置如下:

# 如果900秒内有1条Key信息发生变化,则进行快照
save 900 1
# 如果300秒内有10条Key信息发生变化,则进行快照
save 300 10
# 如果60秒内有10000条Key信息发生变化,则进行快照
save 60 10000

# 关闭RDB快照功能,redis 只作为缓存,不需要持久化功能时
save ""

其他相关配置:

# 文件名称
dbfilename dump.rdb
# 文件保存路径
dir /home/work/app/redis/data/
# 如果持久化出错,主进程是否停止写入(如果关闭持久化功能,这里要改为 no,不然会报错,亲身经历)
stop-writes-on-bgsave-error yes
# 是否压缩
rdbcompression yes
# 导入时是否检查
rdbchecksum yes

优缺点

  • 优点

    • RDB 文件是某个时间节点的快照,默认使用 LZF 算法进行压缩,压缩后的文件体积远远小于内存大小,适用于备份、全量复制等场景
    • Redis 加载 RDB 文件恢复数据要远远快于 AOF 方式
  • 缺点

    • RDB 方式实时性不够,无法做到秒级的持久化(频繁fork一个子进程性能消耗时比较大的)
    • 可能丢失最后一次持久化数据(持久化过程宕机)
    • RDB 文件是二进制的,没有可读性
    • 版本兼容RDB文件问题

AOF

针对 RDB 快照的缺点产生了 AOF,AOF 是追加 redis 命令的形势来持久化的。在 redis 修改数据后,写入 aof 日志文件(写后日志),像 mysql 是先写日志,再修改数据(写前日志)

写后日志的好处是会避免额外的开销,比如语法检查等;缺点就是写时宕机会数据丢失,命令比较多时会比较多的写入文件,压力会比较大

实现原理

  1. 命令追加,当服务器执行完一个命令时,先把这个命令写入到一个 buffer 缓冲区
  2. fork 一个子进程把缓冲区的命令追加写入 aof 文件,什么时候把缓冲区内容写入 aof ?有下面 3 中策略
    1. Always,同步写回:每个写命令执行完,立马同步地将日志写回磁盘
    2. Everysec,每秒写回:每个写命令执行完,只是先把日志写到AOF文件的内存缓冲区,每隔一秒把缓冲区中的内容写入磁盘
    3. No,操作系统控制的写回:每个写命令执行完,只是先把日志写到AOF文件的内存缓冲区,由操作系统决定何时将缓冲区内容写回磁盘

配置

# appendonly参数开启AOF持久化,默认是关闭的
appendonly no
# AOF持久化的文件名,默认是appendonly.aof
appendfilename "appendonly.aof"
# AOF文件的保存位置和RDB文件的位置相同,都是通过dir参数设置的
dir ./

# 同步策略
# appendfsync always
appendfsync everysec
# appendfsync no

# aof重写期间是否同步
no-appendfsync-on-rewrite no

# 重写触发配置
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

# 加载aof出错如何处理
aof-load-truncated yes

# 文件重写策略
aof-rewrite-incremental-fsync yes

混合方式

Redis 4.0 中提出了一个混合使用 AOF 日志和内存快照的方法。简单来说,内存快照以一定的频率执行,在两次快照之间,使用 AOF 日志记录这期间的所有命令操作。

两种方式的结合,原理还是上面说的,问题是两个持久化文件 (rdb 文件和 aof 文件),redis 启动时使用哪个呢?(两个文件的最终数据肯定是一样的)

posted @ 2023-07-10 15:52  CyrusHuang  阅读(92)  评论(0编辑  收藏  举报