目录

Life in Flow

知不知,尚矣;不知知,病矣。
不知不知,殆矣。

X

Redis持久化策略

RDB 持久化原理

配置文件路径 VIM /test/redis-4.0.6/redis.conf

# 时间策略,表示900s内如果有1条是写入命令,就触发产生一次快照,可以理解为就进行一次备份
# 实际生产环境每个时段的读写请求肯定不是均衡的,为此redis提供一种根据key单位时间操作次数来触发一次备份到磁盘,我们可以自由定制什么情况下触发备份,此功能起到平衡性能与数据安全的作用
save 900 1
save 300 10  #表示300s内有10条写入,就产生快照
save 60 10000

# redis servercron 类似于linux的crontab,默认每隔100毫秒执行一次
:检测300s内有没有10条写入,如果有就备份

# 文件名称
dbfilename dump.rdb

# 如果持久化出错,主进程是否停止写入
stop-writes-on-bgsave-error yes

# 是否压缩
rdbcompression yes

# 导入时是否检查
(重启redis,导入rdb文件)
rdbchecksum yes

# 文件保存路径
dir /test/redis-4.0.6

在 Redis 中 RDB 持久化的触发分为两种:自己手动触发与 Redis 定时触发

  • 手动触发
* save:会阻塞当前Redis服务器,直到持久化完成,线上应该禁止使用。
* bgsave:该触发方式会fork一个子进程,由子进程负责持久化过程,因此阻塞只会发生在fork子进程的时候。
  • 自动触发
* 根据我们的 `save m n` 配置规则自动触发
* 从节点全量复制时,主节点发送rdb文件给从节点完成复制操作,主节点会触发 `bgsave`
* 执行 `debug reload` 时
* 执行 `shutdown`时,如果没有开启aof,也会触发
  • 禁用 RDB
* 只需要在save的最后一行写上:save ""

AOF 持久化原理

 AOF 持久化配置 VIM /test/redis-4.0.6/redis.conf

# 是否开启aof
appendonly yes

# 文件名称
appendfilename "appendonly.aof"

# 同步方式
appendfsync everysec

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

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

# 加载aof时如果有错如何处理
aof-load-truncated yes # yes表示如果aof尾部文件出问题,写log记录并继续执行。no表示提示写入等待修复后写入

# 文件重写策略
aof-rewrite-incremental-fsync yes
  • ppendfsync 同步模式有三种模式,一般情况下都采用 everysec 配置,在数据和安全里面做平衡性选择,最多损失 1s 的数据
* always:把每个写命令都立即同步到aof,很慢,但是很安全
* everysec:每秒同步一次,是折中方案
* no:redis不处理交给OS来处理,非常快,但是也最不安全

AOF 的整个流程大体来看可以分为两步

  • 一步是命令的实时写入(如果是  appendfsync everysec  配置,会有 1s 损耗)
* 命令写入=》追加到aof_buf =》通过时间事件调用flushAppendOnlyFile函数同步到aof磁盘
* 实时写入磁盘会带来非常高的磁盘IO,影响整体性能
  • 第二步是对 aof 文件的重写。

AOF 持久化的效率和安全性分析

  • always:每个时间事件循环都将 AOF_BUF 缓冲区的所有内容写入到 AOF 文件,并且同步 AOF 文件,这是最安全的方式,但磁盘操作和阻塞延迟,是 IO 开支较大。
  • everysec:每秒同步一次,性能和安全都比较中庸的方式,也是 Redis 推荐的方式。如果遇到物理服务器故障,有可能导致最近一秒内 aof 记录丢失(可能为部分丢失)
  • no:Redis 并不直接调用文件同步,而是交给操作系统来处理,操作系统可以根据 buffer 填充情况/通道空闲时间等择机触发同步;这是一种普通的文件操作方式。性能较好,在物理服务器故障时,数据丢失量会因 OS 配置有关。处于 no 模式下的 flushAppendOnlyFile 调用无须执行同步操作

RDB、AOF 对比与选择

 一般来说,如果想达到足以媲美 PostgreSQL 的数据安全性, 你应该同时使用两种持久化功能。如果你非常关心你的数据,但仍然可以承受数分钟以内的数据丢失, 那么你可以只使用 RDB 持久化。有很多用户都只使用 AOF 持久化, 但我们并不推荐这种方式: 因为定时生成 RDB 快照(snapshot)非常便于进行数据库备份, 并且 RDB 恢复数据集的速度也要比 AOF 恢复的速度要快。

Redis 提供了不同的持久性选项

  • RDB 持久性以指定的时间间隔执行数据集的时间点快照。
  • AOF 持久性记录服务器接收的每个写入操作,将在服务器启动时再次播放,重建原始数据集。使用与 Redis 协议本身相同的格式以仅追加方式记录命令。当 Redis 太大时,Redis 能够重写日志。

RDB 的优缺点

  • 优点
* RDB最大限度地提高了Redis的性能,父进程不需要参与磁盘I/O
* 与AOF相比,RDB允许使用大数据集更快地重启
  • 缺点
* 如果需要在Redis停止工作时(例如断电后)将数据丢失的可能性降至最低,则RDB并不好,因为RDB同步数据的频率要远远低于AOF。(基于时间点的,所以会导致一定时间范围内的数据丢失)
* RDB经常需要fork()才能使用子进程持久存储在磁盘上。如果数据集很大,Fork()可能会非常耗时。

AOF 的优缺点

  • 优点
* 数据更加安全
* 当Redis AOF文件太大时,Redis能够在后台自动重写AOF ## INCRE 1 执行10万 = INCREBY10万执行一次
* AOF以易于理解和解析的格式一个接一个地包含所有操作的日志 # flushdb类似于rm -rf /*
  • 缺点
* AOF文件通常比同一数据集的等效RDB文件大
* 根据确切的fsync策略,AOF可能比RDB慢

Redis 持久化故障恢复过程
Redis持久化故障恢复过程

Redis 4.0 混合持久化
 重启 Redis 时,我们很少使用 rdb 来恢复内存状态,因为会丢失大量数据。我们通常使用 AOF 日志重放,但是重放 AOF 日志性能相对 rdb 来说要慢很多,这样在 Redis 实例很大的情况下,启动需要花费很长的时间。
Redis 4.0 混合持久化
 Redis 4.0 为了解决这个问题,带来了一个新的持久化选项——混合持久化。将 rdb 文件的内容和增量的 AOF 日志文件存在一起。这里的 AOF 日志不再是全量的日志,而是自持久化开始到持久化结束的这段时间发生的增量 AOF 日志,通常这部分 AOF 日志很小。
 于是在 Redis 重启的时候,可以先加载 rdb 的内容,然后再重放增量 AOF 日志就可以完全替代之前的 AOF 全量文件重放,重启效率因此大幅得到提升。

RDB 持久化与 AOF 持久化同步使用

  • 如果 Redis 中的数据并不是特别敏感或者可以通过其它方式重写生成数据,可以关闭持久化,如果丢失数据可以通过其它途径补回(比如:双写、写入 MySQL)。
  • 自己制定策略定期检查 Redis 的情况,然后可以手动触发备份、重写数据;
  • 采用集群和主从同步

Redis 过期 Key 清除策略

 Redis 服务器实际使用的是惰性删除和定期删除两种策略:通过配合使用这两种删除策略,服务器可以很好地在合理使用 CPU 时间和避免浪费内存空间之间取得平衡。

惰性删除
 当一些客户端尝试访问它时,key 会被发现并主动的过期,放任键过期不管,但是每次从键空间中获取键时,都检查取得的键是否过期,如果过期的话,就删除该键。

  • 特点:CPU 友好,但如果一个 key 不再使用,那么它会一直存在于内存中,造成内存浪费。

定时删除
 设置键的过期时间的同时,创建一个定时器(timer),让定时器在键的过期时间来临时,立即执行对键的删除操作。

  • 特点:为每个 key 创建一个定时器,定时任务过多,服务冗余。

定期删除(既节省了空间,CPU 相对友好)
 隔一段时间,程序就对数据库进行一次检查,删除里面的过期键,至于要删除多少过期键,以及要检查多少个数据库,则由算法决定。 即设置一个定时任务,比如 10 分钟删除一次过期的 key;间隔小则占用 CPU,间隔大则浪费内存。

  • 特点:一个定时器,每次删除一批过期的 key。

作者:Soulboy