一张图搞定redis持久化

redis持久化.png

一、Redis持久化概述

持久化的功能:Redis是内存数据库,数据都是存储在内存中,为了避免进程退出导致数据的永久丢失,需要定期将Redis中的数据以某种形式(数据或命令) 从内存保存到硬盘。 当下次Redis重启时,利用持久化文件实现数据恢复。除此之外,为了进行灾难备份,可以将持久化文件拷贝到一个远程位置。Redis持久化 分为RDB持久化和AOF持久化,前者将当前数据保存到硬盘,后者则是将每次执行的写命令保存到硬盘。

1.1 RDB

RDB是一种快照存储持久化方式,具体就是将Redis某一时刻的内存数据保存到硬盘的文件当中,默认保存的文件名为dump.rdb,而在Redis服务器启动时,会 重新加载dump.rdb文件的数据到内存当中恢复数据。 ,触发 RDB 持久化过程分为手动触发和自动触发。

1.2 触发机制

手动触发分别对应 save 和 bgsave 命令:

  • save 命令:阻塞当前 Redis 服务器,直到 RDB 过程完成为止,对于内存比较大的实例会造成长时间阻塞,线上环境不建议使用。
  • bgsave 命令:Redis 进程执行 fork 操作创建子进程,RDB 持久化过程由子进程负责,完成后自动结束。阻塞只发生在 fork 阶段,一般时间很短。
    显然 bgsave 命令是针对 save 阻塞问题做的优化。因此 Redis 内部所有的涉及 RDB 的操作都采用 bgsave 的方式

除了执行命令手动触发之外,Redis 内部还存在自动触发 RDB 的持久化机制,例如以下场景:

  1. 使用 save 相关配置,如“save m n”。表示 m 秒内数据集存在 n 次修改时,自动触发 bgsave。
  2. 如果从节点执行全量复制操作,主节点自动执行 bgsave 生成 RDB 文件并发送给从节点。
  3. 执行 debug reload 命令重新加载 Redis 时,也会自动触发 save 操作。
  4. 默认情况下执行 shutdown 命令时,如果没有开启 AOF 持久化功能则自动执行 bgsave。

1.3 流程说明

bgsave 是主流的触发 RDB 持久化方式,根据下图了解它的运作流程


bgsave流程说明.png

流程解析:

  1. 执行bgsave命令:Redis父进程判断当前是否存在正在执行的子进程,如RDB/AOF子进程,如果存在bgsave命令直接返回。
  2. 父进程执行fork操作创建子进程,fork操作过程中父进程会阻塞,通过info stats命令查看 latest_fork_usec 选项,可以获取最近一 个 fork 操作的耗时,单位为微秒。
  3. 父进程 fork 完成后,bgsave 命令返回“Background saving started”信息并不再阻塞父进程,可以继续响应其他命令。
  4. 子进程创建 RDB 文件,根据父进程内存生成临时快照文件,完成后对原有文件进行原子替换。执行 lastsave 命令可以获取最后一次生成 RDB 的时间,对应 info 统计的 rdb_last_save_time 选项。
  5. 进程发送信号给父进程表示完成,父进程更新统计信息,具体见 info Persistence 下的 rdb_* 相关选项。

1.4、服务器配置自动触发

除了通过客户端发送命令外,还有一种方式,就是在Redis配置文件中的save指定到达触发RDB持久化的条件,比如【多少秒内至少达到多少写操作】就 开启RDB数据同步。
例如我们可以在配置文件redis.conf指定如下的选项:

  • 900s内至少达到一条写命令 save 900 1
  • 300s内至少达至10条写命令 save 300 10
  • 60s内至少达到10000条写命令 save 60 10000

这种通过服务器配置文件触发RDB的方式,与bgsave命令类似,达到触发条件时,会forks一个子进程进行数据同步, 不过最好不要通过这方式来触发RDB持久 化,因为设置触发的时间太短,则容易频繁写入rdb文件,影响服务器性能, 时间设置太长则会造成数据丢失。

1.5、RDB文件的处理

  1. 保存:
    RDB 文件保存在 dir 配置指定的目录下,文件名通过 dbfilename 配置指定。可以通过执行 config set dir{newDir}config set dbfilename{newFileName}运行期动态执行,当下次运行时 RDB 文件会保存到新目录。
    当遇到坏盘或磁盘写满等情况时,可以通过 config set dir{newDir}在线修改文件路径到可用的磁盘路径,之后执行 bgsave 进行磁盘切换,同样适
    用于 AOF 持久化文件

1.6、RDB 方式的优缺点

  • RDB 是一个非常紧凑的文件,它保存了 Redis 在某个时间点上的数据集。 这种文件非常适合用于进行备份: 比如说,你可以在最近的 24小时内,每小时备份一次 RDB 文件,并且在每个月的每一天,也备份一个 RDB 文件。 这样的话,即使遇上问题,也可以随时将数据集还原到不同的版本。
  • RDB 可以最大化 Redis 的性能:父进程在保存 RDB 文件时唯一要做的就是 fork 出一个子进程,然后这个子进程就会处理接下来的所有保存工作,父进程无须执行任何磁盘 I/O 操作。
    3.RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快

1.7、 RDB 的缺点

  1. RDB 方式数据没办法做到实时持久化/秒级持久化
    如果服务器宕机的话,采用RDB的方式会造成某个时段内数据的丢失,比如我们设置10分钟同步一次或5分钟达到1000次写入就同步一次,那么如果还没达到触发条件服务器就死机了,那么这个时间段的数据会丢失。
  2. 使用bgsave命令在forks子进程时,如果数据量太大,forks的过程也会发生阻塞,另外,forks子进程会耗费内存。针对 RDB 不适合实时持久化的问题,Redis 提供了 AOF 持久化方式来解决。

二、AOF

AOF(append only file)持久化:与RDB存储某个时刻的快照不同,AOF持久化方式会记录客户端对服务器的每一次写操作命令到日志当中,并将这些写操作
以Redis协议追加保存到以后缀为aof文件末尾

2.1 使用AOF

  • 开启AOF功能需要设置配置:appendonly yes, 默认不开启。AOF文件名通过 appendfilename 配置设置,默认文件名是 appendonly.aof。保存路径同RDB持久化方式一致,通过dir配置指定。

2.2 配置说明

appendonly yes启用aof持久化方式
appendfsync always每次收到写命令就立即强制写入磁盘,最慢的大概只有几百的TPS,但是保证完全的持久化,不推荐使用
appendfsync everysec每秒中强制写入磁盘一次,在性能和持久化方面做了很好的折中,推荐
appendfsync no完全依赖os,性能最好,持久化没保证,Redis不会主动调用fsync去将AOF日志内容同步到磁盘,所以这一切就完全依赖于操作的系统调试了,对大多数Linux操作系统,是每30秒进行,几乎不使用。

2.3、工作流程说明

工作流程说明.png

流程如下:

  1. 所有的写入命令会追加到 aof_buf(缓冲区)中。
  2. AOF 缓冲区根据对应的策略向硬盘做同步操作。
  3. 随着 AOF 文件越来越大,需要定期对 AOF 文件进行重写,达到压缩的目的。
  4. 当 Redis 服务器重启时,可以加载 AOF 文件进行数据恢复。

2.3.1、重写机制说明

  • AOF将客户端的每一个写操作都追加到aof文件末尾,随着命令不断写入 AOF,文件会越来越大,为了解决这个问题,Redis 引入 AOF 重写机制压缩文 件体积。
  • AOF 文件重写是把 Redis 进程内的数据转化为写命令同步到新 AOF 文件的过程。
    比如: 多条写命令可以合并为一个,如:lpush list a、lpush list b、lpush list c 可以转化为:lpush list a b c。
  • AOF重写降低了文件占用空间,除此之外,另一个目的是:更小的AOF文件可以更快地被Redis加载。

2.4 触发机制

AOF 重写过程可以手动触发和自动触发:

  • 手动触发:直接调用bgrewriteaof命令。
  • 自动触发: 根据auto-aof-rewrite-min-size和auto-aof-rewrite-percentage参数确定自动触发时机。
  • auto-aof-rewrite-min-size:表示运行AOF重写时文件最小体积,默认为64MB。
  • auto-aof-rewrite-percentage:代表当前AOF文件空间(aof_current_size)和上一次重写后AOF文件空间(aof_base_size)的比值。
    示例:
    auto-aof-rewrite-percentage:100
    auto-aof-rewrite-min-size:64mb
  • 默认配置是当AOF文件大小是上次rewrite后大小的一倍且文本大于64MB时触发
    当初发AOF重写时,内部做了哪些事呢?下面介绍下它的运行流程。


    AOF重写流程.png
  1. 执行AOF重写请求。如果当前进程正在执行AOF重写,请求不执行并返回如下响应,ERR Background append only file rewriting already in progress
  2. 父进程执行fork创建子进程, 开销等于同于bgsave过程。

3.1 主进程fork操作完成后,继续响应其他命令,所有修改命令依然写入AOF缓冲区并根据appendfsync策略同步到硬盘,保证原有AOF机制的正确性。

3.2 由于 fork 操作运用写时复制技术,子进程只能共享 fork 操作时的内存数据。由于父进程依然响应命令,Redis 使用“AOF 重写缓冲区”保存这部 分新数据,防止新 AOF 文件生成期间丢失这部分数据。

  1. 子进程根据内存快照,按照命令合并规则写入到新的 AOF 文件。每次批量写入硬盘数据量由配置 aof-rewrite-incremental-fsync 控制,默认为 32MB,防止单 次刷盘数据过多造成硬盘阻塞
    4.1 新 AOF 文件写入完成后,子进程发送信号给父进程,父进程更新统计信息,具体见 info persistence 下的 aof_*相关统计。
    4.2 父进程把 AOF 重写缓冲区的数据写入到新的 AOF 文件。
    4.3 使用新 AOF 文件替换老文件,完成 AOF 重写。

2.5 AOF注意事项

1.AOF文件损坏
在写入aof日志文件时,如果redis服务器宕机,则aof日志文件会出格式错误,在重启Redis服务器时,Redis服务器会拒绝载入这个aof文件,可以通过命令修复aof并恢复数据。
redis-check-aof -fix file.aof

2.6、AOF的优缺点

2.6.1、AOF的优点

  1. AOF可以设置完全不同步、每秒同步、每次操作同步。因为aof时操作指令的追加,所以可以频繁的大量同步。
  2. AOF文件是一个值追加日志的文件,即使服务宕机未写入完整的命令,也可以通过redis-check-aof工具修复这些问题。
  3. 如果AOF文件过大,Redis会在后台自动地重写AOF文件。重写后会使AOF文件压缩到最小所需的指令集。
  4. AOF文件是有序保存数据库的所有写入操作,易读,易分析。即使如果不小心误操作数据库,也很容易找出错误指令,恢复到某个数据节点。例如不小心FLUSHALL,可以非常容易恢复到执行命令之前。

2.6.2、AOF的缺点

  1. 相同数据量下,AOF的文件通常体积会比RDB大,因为AOF时存指令的,而RDB时所有指令的结果快照。但AOF在日志重写后会压缩一些空间。
  2. 在大量写入和载入的时候,AOF的效率会比RDB低。因为大量写入,AOF会执行更多的保存命令,载入的时候也需要大量的执行命令来得到最后的结果。RDB对此更有优势。

2.7、重启加载的选择

AOF 和 RDB文件都可以用于服务器重启时的数据恢复


重启加载的选择.png

2.8、持久化的选择

  • 在实际生产环境中,根据数据量、应用对数据的安全要求、预算限制等不同情况,会有各种各样的持久化策略;如完全不使用任何持久化、使用RDB或
    AOF的一种,或同时开启RDB和AOF持久化等。此外,持久化的选择必须与Redis的主从策略一起考虑,因为主从复制与持久化同样具有数据备份的功能,
    而且主机master和从机slave可以独立的选择持久化方案。
  • 面分场景来讨论持久化策略的选择,下面的讨论也只是作为参考,实际方案可能更复杂更具多样性。
  1. 如果redis中的数据完全丢弃也没有关系(如Redis完全用作DB层数据的cache),那么无论是单机,还是主从架构,都可以不进行任何持久化。
  2. 在单机环境下(对于个人开发者,这种情况可能比较常见),如果可以接受十几分钟或更多的数据丢失,选择RDB对Redis的性能更加有利;如果只能接受秒级别的数据丢失,应该选择AOF。
  3. 但在大多数情况下,我们都会配置主从环境,slave的存在既可以实现数据的热备,也可以进行读写分离分担Redis读请求,以及在master宕掉后继续提供服务。
    在这种情况下的做法是:
  • master:完全关闭持久化(包括RDB和AOF),这样可以让master的性能达到最好;
  • slave:关闭RDB,开启AOF(如果对数据安全要求不高,开启RDB关闭AOF也可以),并定时对持久化文件进行备份(如备份到其他文件夹,并标记好备份的时间);然后关闭AOF的自动重写,然后添加定时任务,在每天Redis闲时(如凌晨12点)调用bgrewriteaof
  • 为什么开启了主从复制,可以实现数据的热备份,还需要设置持久化呢?
    因为在一些特殊情况下,主从复制仍然不足以保证数据的安全,例如:
    master和slave进程同时停止:考虑这样一种场景,如果master和slave在同一个机房,则一次停电事故就可能导致master和slave机器同时关机,Redis进程停止;如果没有持久化,则面临的是数据的完全丢失。
  • master误重启:考虑这样一种场景,master服务因为故障宕掉了,如果系统中有自动拉起机制(即检测到服务停止后重启该服务)将master自动重启,由于没有持久化文件,那么master重启后数据是空的,slave同步数据也变成了空的:
  • 如果master和slave都没有持久化,同样会面临数据的完全丢失。需要注意的是,即便是使用了哨兵进行自动的主从切换,也有可能在哨兵轮询到master之前,便被自动拉起机制重启了。因此,应尽量避免“自动拉起机制”和“不做持久化”同时出现。
  • 如果需要最大限度需要数据无损:
    建议master开启aof,slave开启aof,开启aof需要cpu和磁盘性能保障。开启aof建议fsync同步刷盘使用everysec,自定义脚本在应用空闲时定时
    bgrewrite
  1. 异地灾备:上述讨论的几种持久化策略,针对的都是一般的系统故障,如进程异常退出、宕机、断电等,这些故障不会损坏硬盘。但是对于一些可能导致硬盘损坏的灾难情况,如火灾地震,就需要进行异地灾备。
  • 例如对于单机的情形,可以定时将RDB文件或重写后的AOF文件,通过scp拷贝到远程机器,如阿里云;对于主从的情形,可以定时在master上执行bgsave,然后将RDB文件拷贝到远程机器,或者在slave上执行bgrewriteaof重写AOF文件后,将AOF文件拷贝到远程机器上。
  • 一般来说,由于RDB文件文件小、恢复快,因此灾难恢复常用RDB文件;异地备份的频率根据数据安全性的需要及其它条件来确定,但最好不要低于一天一次。

注意

  1. RDB虽然可以通过bgsave指令后台保存快照,但fork()子进程是有开销的,在内存数据集较大的情况下会占用很长的cpu时间,fork新进程时这个复制是需要时间的,在服务器结点上测试,35G的数据bgsave瞬间会阻塞200ms以上,一般建议Redis使用内存不超过20g。
  2. I/O消耗的问题
    线上是在Slave节点开启rdb持久化,磁盘性能一般,1.2g的rdb文件持久化一分钟一次,
    一次大概耗时30s左右,所以rdb的频率也不能太频繁,需要根据情况做好配置。
  3. AOF是追加写命令到aof文件的方式,优点是可以基本做到数据无损,缺点是文件增长较快,需要间歇性bgrewritebgrewrite也是一个既耗cpu又耗磁盘IO的操作,
    单cpu利用率最高可达100%,一般建议找几个空闲时段设置脚本来做bgrewrite

2.9、持久化配置方案

  1. 企业级的持久化的配置策略
  • save 60 10000:如果你希望尽可能确保说,RDB最多丢1分钟的数据,那么尽量就是每隔1分钟都生成一个快照,低峰期,数据量很少,也没必要10000->生成RDB,1000->RDB,这个根据你自己的应用和业务的数据量,你自己去决定
  • AOF一定要打开,fsync,everysec
  • auto-aof-rewrite-percentage 100: 就是当前AOF大小膨胀到超过上次100%,上次的两倍
  • auto-aof-rewrite-min-size 64mb: 根据你的数据量来定,16mb,32mb
  1. 数据备份方案
    RDB非常适合做冷备,每次生成之后,就不会再有修改了
    数据备份方案
    (1)写crontab定时调度脚本去做数据备份
    (2)每小时都copy一份rdb的备份,到一个目录中去,仅仅保留最近48小时的备份
    (3)每天都保留一份当日的rdb的备份,到一个目录中去,仅仅保留最近1个月的备份
    (4)每次copy备份的时候,都把太旧的备份给删了
    (5)每天晚上将当前服务器上所有的数据备份,发送一份到远程的云服务上去【crontab】
    2.8、AOF常用配置总结
  • appendonly no:是否开启AOF
  • appendfilename "appendonly.aof":AOF文件名
  • dir ./:RDB文件和AOF文件所在目录
  • appendfsync everysec:fsync持久化策略
  • no-appendfsync-on-rewrite no:AOF重写期间是否禁止fsync;如果开启该选项,可以减轻文件重写时CPU和硬盘的负载(尤其是硬盘),但是可能会丢失AOF重写期间的数据;需要在负载和安全性之间进行平衡
  • auto-aof-rewrite-percentage 100:文件重写触发条件之一
  • auto-aof-rewrite-min-size 64mb:文件重写触发提交之一
  • aof-load-truncated yes:如果AOF文件结尾损坏,Redis启动时是否仍载入AOF文件
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容