Redis:数据持久化

  redis作为一个高性能的key-value数据库,很大程度依赖于其基于内存的数据操作。正因其数据存放在内存中,若遇到服务异常退出、宕机等情况,无法将其数据进行恢复。好在redis为我们提供了数据持久化方案,以解决上述问题。

  redis在4.0版本之前提供两种数据持久化方案,分别是RDB(全量)和AOF(增量),4.0之后提供了RDB-AOF混合持久化方案,充分利用了AOF和RDB各自优势。本文将就这三种方案从使用到底层原理进行介绍。

1. RDB

  RDB是一种全量持久化方案,启用RDB后,redis会在程序满足用户配置的规则时,将内存中的数据全量写入文件系统,已达到持久化的目的。

1.1 RDB配置

  redis持久化一般通过配置文件来进行配置,默认情况下(redis5.0.8),redis将内存数据保存到dump.rdb的二进制文件中,并且当每900秒且1次写操作,或每300秒10次写操作,或每60秒10000次写操作均会触发RDB持久化。我可以通过修改配置文件来修改上述持久化规则。

#持久化存储文件
dbfilename dump.rdb
#每900秒且1次写操作
save 900 1
#每300秒10次写操作
save 300 10
#每60秒10000次写操作
save 60 10000

  同个配置文件中可以通过多条save命令来达到满足指定条件中任一规则时,触发持久化。即当存在多个save命令,他们为“或”的关系。若不想开启RDB持久化,只需要将所有的save保存策略注释掉即可。

1.2 手动生成RDB快照

  除了通过配置文件配置redis自动生成RDB快照之外,我们还可以通过客户端运行save或bgsave命令,来手动让redis生成RDB快照文件。每次命令执行后redis会将所有内存数据生成一个RDB格式文件,并覆盖原有的RDB快照文件。
  save是同步命令,bgsave是异步命令,bgsave会从redis主进程fork出一个子进程,专门用来生成RDB快照文件。save与bgsave对比如下:

命令 save bgsave
IO类型 同步 异步
是否阻塞redis其它命令
复杂度 O(n) O(n)
优点 不会消耗额外内存 不阻塞客户端命令
缺点 阻塞客户端命令 需要fork子进程

注意:通过1.1节配置文件来自动生成RDB文件的方式,redis使用的是bgsave的方式。

2. AOF

  AOF(append only file)类似于Mysql的binlog,是一种增量持久化方案。AOF方案下,redis会将用户操作的指令(只记录写命令)记录到AOF文件。

2.1 AOF配置

  默认情况下,redis不会开启AOF持久化方案,我们可以通过在配置文件中添加以下配置开启AOF:

#启用AOF持久化
appendonly yes
#配置AOF存储路径
appendfilename "appendonly.aof"

  AOF有三种规则可供选择,分别为always、everysec、no,用来设置redis将命令写入AOF文件的时机。

#有新命令立即追加到 AOF 文件,速度慢,但数据安全性最高
appendfsync always
#每秒同步一次命令到文件中,速度较快(和使用 RDB 持久化差不多),在故障发生时最多只会丢失 1 秒钟的数据
appendfsync everysec
#从不fsync,由操作系统自动调度刷磁盘,速度最快,但安全性最低。
appendfsync no

  推荐在对数据安全性要求不高的场景下,使用everysec的fsync策略,这种策略可以同时兼顾性能和安全性。

2.2 AOF原理

  如本节开头介绍,redis会在新的写命令被执行时记录该命令,并按照用户配置的策略将命令以RESP格式(redis客户端与服务端通信协议格式)写入文件系统。整个过程大致如下图所示:


redis AOF持久化过程
2.2.1 RESP

  RESP协议以 “*数字”标记为开头,表明指令共有多少段。每一段又以“$数字”标记开头,表明该段的内容长度,另外每个标记和内容均以过行符作为分隔。如下为执行“set everlin 1”命令的AOF文件内容:

*3
$3
set
$7
everlin
$1
1
2.2.1 AOF重写

  随着时间推移,AOF中记录的指令会越来越多,文件占用空间越来越大,当系统重启去加载AOF时,也会变得越慢。为了解决这一问题,redis提供了AOF重写的功能。AOF重写的理论依据是,我们会对某个key进行多次写操作,而我们很容易找到一个命令,对这个key执行后的结果,与前边多次操作的结果一致。
例如执行以下命令:

incr everlin
incr everlin
incr everlin

  在没有进行AOF重写时,AOF文件中的内容如下:

*2
$4
incr
$7
everlin
*2
$4
incr
$7
everlin
*2
$4
incr
$7
everlin

  在redis进行AOF重写后,AOF文件内容变为:

*3
$3
set
$7
everlin
$1
4

  需要注意,重写AOF文件的操作,redis并不是读取旧的AOF文件后进行成功学,而是将整个内存中的数据库内容用命令的方式重写了一个新的AOF文件,这点和快照有点类似。此外,在redis4.0之后,若开启了混合持久化方案,那么AOF重写的数据将不再以RESP格式写入,而是以RDB二进制格式写入AOF文件中。
AOF重写也需要配置策略才能触发,如下两个配置可以控制AOF自动重写频率

#AOF文件至少要达到64M才进行重写
auto-aof-rewrite-min-size 64mb
#AOF文件自上一次重写后文件大小增长了100%,再次触发重写
auto-aof-rewrite-percentage 100

  我们还可以通过在客户端使用bgrewriteaof命令,来对AOF进行手动重写。redis通过fork一个子进程进行AOF重写,因此,AOF重写不会对redis正常命令处理产生太大影响。

3. RDB VS AOF

  通过1、2节的介绍,我们整理出RDB与AOF持久化方案的对比如下:

特点 RDB AOF
文件体积
性能影响 由同步策略决定(参见2.1)
数据安全 容易丢数据 由同步策略决定(参见2.1)
恢复速度
3.1 同时开启RDB和AOF

  当同时开启RDB持久化和AOF持久化时,两种方案都会被redis启用。但当redis重启时,若同时存在RDB文件及AOF文件,redis会优先选择AOF文件进行数据恢复。因为AOF方案能保证数据更接近与上次redis停止时的数据。

4. 混合持久化方案

  前一节我们对比了RDB和AOF各自的优缺点,RDB占用存储空间小,恢复速度快,AOF数据安全性更高,那有没有方法可以发挥两者的优势,取长补短呢。答案是有的,redis4.0之后提供了混合持久化方案,该方案基本与AOF方案一致,不同点在于,当AOF重写时,以RDB格式对AOF进行重写。此时AOF的文件结构如下:


混合持久化方案下AOF文件结构

  混合持久化方案提供了一种简单粗暴的方式,取长补短,既保留了RDB文件体积小,恢复速度快的优势,又解决了RDB持久化容易丢失数据的问题。我们可以在配置文件中使用以下配置,启用混合持久化:

aof-use-rdb-preamble yes

5. 小结

  本文分别介绍了RDB,AOF,混合持久化3种持久化方案:RDB文件体积小,恢复速度快,但容易丢失数据;AOF可根据fsync策略提供不同的数据安全等级,可以做到数据不丢失,但其恢复速度慢,redis提供了AOF重写来压缩其文件体积,提高恢复速度;混合持久化结合了RDB和AOF的优势,在AOF重写时以RDB格式将数据置于AOF文件开头,大大提高了AOF的恢复速度,同时也保留了其数据安全性高的优势。建议在需要进行持久化的场景下,选用混合持久化方案。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容