redis 持久化

Posted 黄光跃

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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/
# 如果持久化出错,主进程是否停止写入
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 启动时使用哪个呢?(两个文件的最终数据肯定是一样的)

redis学习系列——redis持久化

1、写操作的流程

2、RDB快照-redis的第一个持久化策略

第一种是以快照的形式持久化到本地磁盘(RDB文件)。

持久化策略是:

1.配置(save N M)在N秒内,redis至少发生M次修改,则redis持久化快照到本地磁盘。

  • after 900 sec (15 min) if at least 1 key changed

2.手动持久化:手动save或bgsave快照。

  • 工作原理:当redis进行持久化时,redis会fork出一个子进程,然后在子进程中循环所有的数据,将数据写入一个临时RDB文件中;当子进程完成写操作时,会将原来的RDB替换掉。

RDB持久化常用配置项

dbfilename dump.rdb
dir ./
save <seconds> <changes>

不足:一旦数据库出现问题(如直接关闭服务器),那我们的RDB文件中保存的数据并不是全新的,从上次RDB文件生成到Redis停机这段时间的数据全部丢掉了。 对于可以忍受的业务,推荐使用RDB方式进行持久化,因为开启RDB的代价并不高。但是对于对数据安全性要求极高的应用,Redis引入了:AOF日志。

3、AOF日志

AOF日志,全称append only file,是一个追加写入的日志文件,是可识别的纯文本,内容就是一个个的redis标准命令。

AOF重写:AOF rewrite
Redis AOF持久化常用配置项
appendonly yes
appendfilename appendonly.aof

appendfsync everysec 三种不同的刷新模式
appendfsync always
appendfsync no

no-appendfsync-on-rewrite no

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
RDB和AOF持久化的区别

RDB特性:

fork一个进程,遍历Hashtable,利用copy-on-write,把整个db dump保存下来。
save,shutdown,slave之前crash,则中间的操作无法恢复。

AOF特性:

把写操作指令,持续的写入一个类似日志文件。
粒度较小,crash后,只有crash前没有来得及做日志的操作无法恢复。

二者区别:

AOF是持续用日志记录写操作,crash后利用日志恢复;
RDB是平时写操作时不触发写,只有达到写操作节点或手动提交save命令或关闭命令时,才会触发备份操作。

以上是关于redis 持久化的主要内容,如果未能解决你的问题,请参考以下文章

Redis高级(持久化--redis主从架构--redis哨兵模式--redis分片集群)

Redis持久化

redis 之redis持久化rdb与aof

redis学习系列——redis持久化

Redis学习-4-2 Redis持久化

redis 的持久化策略有几种