Redis 有两种持久化的方式: 快照 (RDB文件) 和追加式文件 (AOF文件):redis
fork()
, 产生一个子进程.默认 Redis 会把快照文件存储为当前目录下一个名为 dump.rdb
的文件. 要修改文件的存储路径和名称, 能够经过修改配置文件 redis.conf
实现:安全
# RDB文件名,默认为dump.rdb。 dbfilename dump.rdb # 文件存放的目录,AOF文件一样存放在此目录下。默认为当前工做目录。 dir ./
你能够配置保存点, 使 Redis 若是在每 N 秒后数据发生了 M 次改变就保存快照文件. 例以下面这个保存点配置表示每 60 秒, 若是数据发生了 1000 次以上的变更, Redis就会自动保存快照文件:服务器
save 60 1000
保存点能够设置多个, Redis 的配置文件就默认设置了 3 个保存点:app
# 格式为:save <seconds> <changes> # 能够设置多个。 save 900 1 #900秒后至少1个key有变更 save 300 10 #300秒后至少10个key有变更 save 60 10000 #60秒后至少10000个key有变更
若是想禁用快照保存的功能, 能够经过注释掉全部 "save" 配置达到,或者在最后一条 "save" 配置后添加以下的配置:性能
save ""
默认状况下, 若是 Redis 在后台生成快照的时候失败, 那么就会中止接收数据, 目的是让用户能知道数据没有持久化成功.spa
可是若是你有其余的方式能够监控到 Redis 及其持久化的状态, 那么能够把这个功能禁止掉.3d
stop-writes-on-bgsave-error yes
默认 Redis 会采用 LZF
对数据进行压缩.code
若是你想节省点 CPU 的性能, 你能够把压缩功能禁用掉, 可是数据集就会比没压缩的时候要大.blog
rdbcompression yes
从版本 5 的 RDB 的开始, 一个 CRC64 的校验码会放在文件的末尾. 这样更能保证文件的完整性, 可是在保存或者加载文件时会损失必定的性能 (大概10%).生命周期
若是想追求更高的性能, 能够把它禁用掉, 这样文件在写入校验码时会用 0 替代, 加载的时候看到 0 就会直接跳过校验.
rdbchecksum yes
Redis 提供了两个命令用于手动生成快照.
BGSAVE
命令使用后台的方式保存 RDB 文件, 调用此命令后, 会马上返回OK
.
Redis 会产生一个子进程进行快照写入硬盘. 父进程继续处理命令请求.
SAVE
命令会使用同步的方式生成 RDB 快照文件, 这意味着在这个过程当中会阻塞全部其余客户端的请求.
所以不建议在生产环境使用这个命令.
重点
save 60 1000
, 那么从 Redis 最近一次建立快照以后开始算起. 当条件被知足时, 就会自动出发 BGSAVE
命令. 若是有多个 save
配置, 那么当任意一个被知足时, 都会出发一次 BGSAVE
命令.SHUTDOWN
命令, 来关闭服务时, 或者接收到标准 TERM
信号时, 会执行一次 SAVE
命令, 阻塞全部客户端, 而且执行完毕后会关闭 Redis 服务.这里注意的是 fork
操做会阻塞, 致使 Redis 读写性能降低. 咱们能够控制单个 Redis 实例的最大内存, 来尽量下降 Redis 在 fork
时的事件消耗. 以及上面提到的自动触发的频率减小 fork
次数, 或者使用手动触发, 根据本身的机制来完成持久化.
快照并非很可靠. 若是你的电脑忽然宕机了, 或者电源断了, 又或者不当心杀掉了进程, 那么最新的数据就会丢失.
而 AOF 文件则提供了一种更为可靠的持久化方式. 每当 Redis 接受到会修改数据集的命令时, 就会把命令追加到 AOF 文件里, 当你重启 Redis 时, AOF 里的命令会被从新执行一次, 重建数据.
把配置项 appendonly
设为 yes
:
appendonly yes
# 文件存放目录,与RDB共用。默认为当前工做目录。 dir ./ # 默认文件名为appendonly.aof appendfilename "appendonly.aof"
你能够配置 Redis 调用 fsync
的频率, 有三个选项:
fsync
. 速度最慢, 最安全.fsync
一次. 速度快 (2.4版本跟快照方式速度差很少), 安全性不错 (最多丢失 1 秒的数据).fsync
, 交由系统去处理. 这个方式速度最快, 可是安全性通常.推荐使用每秒 fsync 一次的方式 (默认的方式), 由于它速度快, 安全性也不错. 相关配置以下:
# appendfsync always appendfsync everysec # appendfsync no
对于增量追加到文件这一步主要的流程是: 命令写入=》追加到 aof_buf =》同步到aof磁盘. 那么这里为何要先写入 buf 在同步到磁盘呢? 若是实时写入磁盘会带来很是高的磁盘IO, 影响总体性能.
AOF 重写是为了减小 AOF 文件的大小, 随着写操做的不断增长, AOF 文件会愈来愈大. 例如你递增一个计数器 100 次, 那么最终结果就是数据集里的计数器的值为最终的递增结果, 可是 AOF 文件里却会把这 100 次操做完整的记录下来.
而事实上要恢复这个记录, 只须要 1 个命令就好了, 也就是说 AOF 文件里那 100 条命令其实能够精简为 1 条. 因此 Redis 支持这样一个功能: 在不中断服务的状况下在后台重建 AOF 文件.
对于上图有四个关键点补充一下:
经过上面的分析, 咱们都知道 RDB 的快照、AOF的重写都须要 fork
, 这是一个重量级操做, 会对 Redis 形成阻塞. 所以为了避免影响 Redis 主进程响应, 咱们须要尽量下降阻塞.
fork
的频率, 好比能够手动来触发 RDB 生成快照、与AOF重写;fork
耗时过长;fork
失败.在线上咱们到底该怎么作? 我提供一些本身的实践经验.