Redis持久化之路:RDB和AOF策略的选择与权衡

redis是一个内存数据库,当redis服务器重启,获取电脑重启,数据会丢失,我们可以将redis内存中的数据持久化保存到硬盘的文件中。

redis持久化的两种方式

1. RDB模式
1.1 RDB模式分析

这种方式就是将内存中数据以快照的方式写入到二进制文件中 ,所以这种方式也叫快照方式, 默认的文件名为dump.rdb。我们可以配置redis在n秒内如果超过m个key则修改就自动做快照。类似于MySQL中的定时备份,每隔一段时间执行一次。

RDB 持久化的触发分为手动触发和自动触发两种:

  • 手动触发
  • 自动触发

手动触发: save 命令和 bgsave 命令都可以生成 RDB 文件。

save 操作是在主进程中保存快照的, 由于 redis 是用一个主进程来处理所有客户端的请求, 这种方式会阻塞所有客户端请求。 所以不推荐使用。

而 bgsave 命令会创建一个子进程,由子进程来负责创建 RDB 文件,主线程继续处理请求。

bgsave 命令执行过程中,只有 fork 子进程时会阻塞服务器,而对于 save 命令,整个过程都会阻塞服务器。

自动触发: 最常见的情况是在配置文件中通过 save m n,指定当 m 秒内发生 n 次变化时,会触发 bgsave。

此种方式的优缺点:

优点

  • 每隔一段时间全量备份
  • 备份简单,可以直接传输文件到其它地方
  • 备份的过程中会fork一个新的线程来进行文件的存储

缺点

  • 发生故障时,会丢失上次备份到当前时间的数据
  • 每次都是全量备份,数据据量大的话,会引起大量的磁盘IO操作,可能会严重影响性能
  • fork的进程会和父进程一模一样,会导致内存随时膨胀两倍
1.2 RDB配置文件

RDB文件就是存放在dir目录下的,只有一个文件,每次更新都会做全量替换

在redis.conf中搜索dbfilename,可以设置RDB文件的名称

那么RDB多久保存一次

#   In the example below the behaviour will be to save:
#   after 900 sec (15 min) if at least 1 key changed
#   after 300 sec (5 min) if at least 10 keys changed
#   after 60 sec if at least 10000 keys changed
# 默认RDB时开启的,save就保存操作:自动触发bgsave命令
save 900 1
save 300 10
save 60 10000
# 设置RDB存放的目录
dir ./  #./代表的是随着配置文件的位置改变
# 设置RDB存放的名称
dbfilename dump.rdb
# yes:如果save过程中出错,则停止写入操作
# no:无论是否写入成功都不停止写入操作
stop-writes-on-bgsave-error yes
# 是否启用压缩
rdbcompression yes
# 是否开启数据校验,有一定的性能损耗
rdbchecksum yes

save m n 的实现原理: Redis 的 save m n,是通过 serverCron 函数、dirty 计数器和 lastsave 时间戳来实现的。

serverCron 是 Redis 服务器的周期性操作函数,默认每隔 100ms 执行一次;该函数对服务器的状态进行维护,其中一项工作就是检查 save m n 配置的条件是否满足,如果满足就执行 bgsave。

dirty 计数器是 Redis 服务器维持的一个状态,记录了上一次执行 bgsave/save 命令后,服务器状态进行了多少次修改(包括增删改);而当 save/bgsave 执行完成后,会将 dirty 重新置为 0。

例如,如果 Redis 执行了 set mykey helloworld,则 dirty 值会 +1;如果执行了 sadd myset v1 v2 v3,则 dirty 值会 +3;注意 dirty 记录的是服务器进行了多少次修改,而不是客户端执行了多少修改数据的命令。

lastsave 时间戳也是 Redis 服务器维持的一个状态,记录的是上一次成功执行 save/bgsave 的时间。

save m n 的原理如下:每隔 100ms,执行 serverCron 函数;在 serverCron 函数中,遍历 save m n 配置的保存条件,只要有一个条件满足,就进行 bgsave。

对于每一个 save m n 条件,只有下面两条同时满足时才算满足:

  • 当前时间-lastsave > m
  • dirty >= n
1.3 手动备份RDB

手动出发Redis的RDB持久化命令

  • save

    该命令会阻塞当前Redis服务器进行持久化

  • bgsave

    该命令会fork一个新进程进行数据的操作

1.4 使用RDB恢复数据

将dump.db拷贝到redis的安装目录dir下,redis会自动进行数据恢复

2. AOF模式
2.1 AOF的模式分析

append-only file(缩写aof)的方式(优点类似于oracle日志),所以也称为日志追加模式,由于快照方式是在一定时间间隔做一次,所以可能发生redis意外down的情况就会丢失最后一次快照后的所有修改的数据,aof比快照方式有更好的持久化性,是由于在使用aof时,redis会将每一个收到的写命令都通过write函数追加到命令中,当redis重新启动appendonly.aof不是立即写到磁盘上。这样的持久化还是有可能会丢失部分数据。

AOF特点

  • 以日志的形式记录用户的所有请求,读请求不会记录,只有写操作才会记录
  • 文件是以追加的方式来记录而不是修改的方式
  • redis的AOF恢复方式其实就是把所有追加的文件从开始到结束全部执行一遍

优势

  • AOF更加耐用,可以以秒为单位进行备份,如果发生问题只丢失最后一秒的数据
  • 以log的日志形式进行追加,如果磁盘满了,会执行redis-aof工具
  • 当日志文件数据量太大的时候redis会在后台重写AOF文件,重写的过程也是fork新的进程进行操作
  • AOF日志包含所有的写操作,会便于redis的解析恢复

劣势

  • 相同的数据,同一份对比,AOF一定比RDB大
  • 在同步情况下AOF的操作会比RDB慢
2.2 AOF配置文件
# AOF默认是关闭的,可用设置成yes
appendonly yes
# aof的文件名
appendfilename "appendonly.aof"
# no: 写入aof文件,不等待磁盘同步,完全依赖操作系统,性能最好,持久化没保存。
# everysec: 每秒钟强制写入磁盘一次,在性能和持久化方面做了很好的折中,推荐
# always:每次收到写命令就立即强制写入磁盘, 最慢的, 但是保证完全的持久化,数据最完整的,不推荐使用
appendfsync everysec
# 重写的时候是否要同步,yes是不同步,会导致数据不一致
# no同步阻塞,相当于重写过程中数据无法写入
no-appendfsync-on-rewrite no
# 重写机制:避免文件越来越大,自动优化文件大小,会fork一个新的进程去完成重写日志的操作
# 当AOF文件的大小比上次多了100%相当于两倍
# 文件大小达到了64mb
# 两个条件同时满足则触发重写
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

rdb: 快照形式,定期把内存中当前时刻的数据保存到磁盘。Redis默认持久化方案。
优点:
1.只有一份rdb文件,可随时备份
2. 比AOF文件小,加载效率高
3. 只提供fork子进程,不阻塞主进程,IO操作比较少
aof形式: append only file。把所有对redis数据库操作的命令,增删改操作的命令。保存到文件中。数据库恢复时把所有的命令执行一遍即可。
优点:
1.每次改动同步数据安全性好
2. append方式追加日志,不会对旧日志文件产生影响。

应用场景对比
  • 如果能接受一段时间的缓存丢失,就可以选择RDB
  • 如果对实时性要求比较好,就可以使用AOF
  • 如果将RDB和AOF一起使用,相当于RDB做冷备,AOF做热备

两者一起用需要注意的问题

  • 两个都是全量数据,redis到底用的哪一个
  • 在RDB和AOF两者同时开启时使用的是AOF
  • 如何在已经运行的Redis上开启AOF并不影响历史数据
# 首先在redis的命令行,动态开启AOF命令
config set appendonly yes
# 然后再到redis.conf里去打开配置
appendonly yes

参考《redis中文入门手册》

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值