Redis之持久化数据

为什么要持久化

 redis 的数据全部在内存中,如果突然宕机,数据就会全部丢失,因此需要持久化来保证 Redis 的数据不会因为故障而丢失,redis 重启的时候可以重新加载持久化文件来恢复数据;

Redis 持久化相关的配置

在配置文件中配置

###### aof ######
# redis.cnf
appendonly no
appendfilename "appendonly.aof"

# aof策略选择:
# appendfsync always
appendfsync everysec # 默认情况下是这个
# appendfsync no

# auto-aof-rewrite-percentage 为 0 则关闭 aof 复写
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
# yes 如果 aof 数据不完整,尽量读取最多的格式正确的数据;
# no 如果 aof 数据不完整 报错,可以通过 redis-check-aof 来修复 aof 文件;
aof-load-truncated yes
# 开启混合持久化
aof-use-rdb-preamble yes


###### rdb ######
# 关闭rdb
save ""

# save 3600 1
# save 300 100
# save 60 10000

持久化方式与分析

aof

append only file
 aof 日志存储的是 Redis 服务器的顺序指令序列,aof 日志只记录对内存修改的指令记录;持久化保存的是协议数据;
Redis之持久化数据

恢复

 通过重放(replay)aof 日志中指令序列来恢复 Redis 当前实例的内存数据结构的状态

配置

set key val
# 开启 
aofappendonly yes
# 关闭 aof复写
auto-aof-rewrite-percentage 0
# 关闭 混合持久化
aof-use-rdb-preamble no
# 关闭 rdbsave 使用aof时必须关闭rdb
save ""
# 设置aof文件名
appendfilename "appendonly.aof"

策略

# 1. 每条命令刷盘 redis 事务才具备持久性
# appendfsync always
# 2. 每秒刷盘
appendfsync everysec
# 3. 交由系统刷盘
# appendfsync no

缺点

 随着时间越长,aof 日志会越来越长,如果 redis 重启,重放整个 aof 日志会非常耗时,导致redis 长时间无法对外提供服务;

aof 复写

 aof 持久化策略会持久化所有修改命令;里面的很多命令其实可以合并或者删除;如:

# 无意义的入队列和出队列,可以不做
lpush list a
lpop list

 aof rewrite 在 aof 的基础上,满足一定策略则 fork 进程,根据当前内存状态,转换成一系列的 redis 命令,序列化成一个新的 aof 日志文件中,序列化完毕后再将操作期间发生的增量 aof 日志追加到新的 aof 日志文件中国你,追加完毕后替换旧的 aof 日志文件;以此达到对 aof 日志瘦身的目的;
 fork进程有两种方式,一种是命令(bgrewriteaof),一种是配置文件。
注意:aof rewrite 开启的前提是开启 aof;
Redis之持久化数据
命令方式:

lpush list mark
lpush list king
lpush list darren
bgrewriteaof
# 此时会将上面三个命令进行合并成为一个命令
# 合并策略:会先检测键所包含的元素数量,如果超过 64 个会使用多个命令来记录键的值;

hset hash mark 10001
hset hash darren 10002
hset hash king 10003
hdel hash mark
bgrewriteaof
# 此时aof中不会出现mark,设置mark跟删除mark变得像从来没操作过

配置方式:

# 开启 aof
appendonly yes
# 开启 aof复写
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
# 关闭 混合持久化
aof-use-rdb-preamble no
# 关闭 rdb
save ""

策略

# 1. redis 会记录上次aof复写时的size,如果之后累计超过了原来的size,则会发生aof复写;
auto-aof-rewrite-percentage 100
# 2. 为了避免策略1中,小数据量时产生多次发生aof复写,策略2在满足策略1的前提下需要超过 64mb才会发生aof复写;
auto-aof-rewrite-min-size 64mb

缺点

 aof复写在 aof 基础上实现了瘦身,但是 aof 复写的数据量仍然很大;加载会非常慢

rdb

 基于 aof 或 aof 复写文件大的缺点,rdb 是一种快照持久化;它通过 fork 主进程,在子进程中将内存当中的数据键值对按照存储方式持久化到 rdb 文件中;rdb 存储的是经过压缩的二进制数据;
Redis之持久化数据

配置

# 关闭 aof 同时也关闭了 aof复写
appendonly no
# 关闭 aof复写
auto-aof-rewrite-percentage 0
# 关闭 混合持久化
aof-use-rdb-preamble no
# 开启 rdb 也就是注释 save ""
# save ""
# save 3600 1
# save 300 100
# save 60 10000

策略

# redis 默认策略如下:
# 注意:写了多个 save 策略,只需要满足一个则开启rdb持久化
# 3600 秒内有以1次修改
save 3600 1
# 300 秒内有100次修改
save 300 100
# 60 秒内有10000次修改
save 60 10000

缺点

 若采用 rdb 持久化,一旦 redis 宕机,redis将丢失一段时间的数据;
 RDB 需要经常 fork 子进程来保存数据集到硬盘上,当数据集比较大的时候,fork 的过程是非常耗时的,可能会导致 Redis 在一些毫秒级内不能响应客户端的请求。如果数据集巨大并且 CPU 性能不是很好的情况下,这种情况会持续1秒,AOF 也需要 fork,但是你可以调节重写日志文件的频率来提高数据集的耐久度。

混合持久化

 从上面知道,rdb 文件小且加载快但丢失多,aof 文件大且加载慢但丢失少;混合持久化是吸取rdb 和 aof 两者优点的一种持久化方案;aof 复写的时候实际持久化的内容是 rdb,等持久化后,持久化期间修改的数据以 aof 的形式附加到文件的尾部;
 混合持久化实际上是在 aof rewrite 基础上进行优化;所以需要先开启 aof rewrite;
Redis之持久化数据

配置

# 开启 aof
appendonly yes
# 开启 aof复写
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
# 开启 混合持久化
aof-use-rdb-preamble yes
# 关闭 rdb
save ""
# save 3600 1
# save 300 100
# save 60 10000

应用

  1. MySQL 缓存方案中,redis 不开启持久化,redis 只存储热点数据,数据的依据来源于MySQL;若某些数据经常访问需要开启持久化,此时可以选择 rdb 持久化方案,也就是允许丢失一段时间数据;
  2. 对数据可靠性要求高,在机器性能,内存也安全 (fork 写时复制 最差的情况下 96G)的情况下,可以让 redis 同时开启 aof 和 rdb,注意此时不是混合持久化;redis 重启优先从 aof 加载数据,理论上 aof 包含更多最新数据;如果只开启一种,那么使用混合持久化;
  3. 在允许丢失的情况下,亦可采用主redis不持久化(96G 90G),从redis进行持久化;
  4. 伪装从数据库;

数据安全策略

问题:拷贝持久化文件是否安全?
 是安全的,持久化 文件一旦被创建, 就不会进行任何修改。 当服务器要创建一个新的持久化文件时, 它先将文件的内容保存在一个临时文件里面, 当临时文件写入完毕时, 程序才使用rename(2) 原子地用临时文件替换原来的持久化文件

数据安全要考虑两个问题:

  1. 节点宕机(redis 是内存数据库,宕机数据会丢失)
  2. 磁盘故障

 创建一个定期任务(cron job), 每小时将一个 RDB 文件备份到一个文件夹, 并且每天将一个RDB 文件备份到另一个文件夹。
 确保快照的备份都带有相应的日期和时间信息, 每次执行定期任务脚本时, 使用 find 命令来删除过期的快照: 比如说, 你可以保留最近 48 小时内的每小时快照, 还可以保留最近一两个月的每日快照。
 至少每天一次, 将 RDB 备份到你的数据中心之外, 或者至少是备份到你运行 Redis 服务器的物理机器之外

上一篇:固定在顶部的导航


下一篇:redis数据安全机制