Redis(5):Redis持久化配置和数据恢复实验

        在上一篇文章中对Redis的两种持久化方式进行了介绍,还介绍了各自的优缺点以及如何选择,这篇文章就介绍一下redis的持久化应该怎么配置,数据恢复应该怎么操作。

1.RDB配置和数据恢复流程

(1).RDB的配置

        首先找到redis的配置文件,我的redis装在了centos上,配置文件的目录为:/etc/redis/6379.conf,打开它找到snapshotting。


rdb配置redis

        可以在snapshotting下配置多个save,这个save其实就是检查点,redis可以配置多个检查点,每到一个检查点,就会去check一下,是否有指定的key数量发生了变更,如果有,就生成一个新的dump.rdb文件。当然,我们也可以通过手动调用save或者bgsave命令,同步或异步执行rdb快照生成。

save 900 1:表示每隔900秒如果有1个key发生变化就会生成一个新的rdb文件

save 300 10:表示每隔300秒如果有10个key发生变化就会生成一个新的rdb文件

save 60 10000:表示每隔60秒如果有10000个key发生变化就会生成一个新的rdb文件

        save 5 1 是我们为了实验方便设置的一个检查点

(2).RDB持久化机制的工作流程

(a).redis根据配置自己尝试去生成rdb快照文件

(b).fork一个子进程出来

(c).子进程尝试将数据dump到临时的rdb快照文件中

(d).完成rdb快照文件的生成之后,就替换之前的旧的快照文件

同时只有一个dump.rdb,每次生成一个新的快照,都会覆盖之前的老快照。

(3).rdb数据恢复实验

        首先我们打开redis-cli存储一些数据(ps:此时我们还没有在redis.conf中添加save 5 1):


        现在我们把一些数据都已经放在了redis里面,然后我们shut down redis,并且重启redis:


        那么现在就有点奇怪了,我们还没有添加检查点 save 5 1,为什么数据还是在redis中?其实在我们shutdown redis-cli的时候就已经自动生成了一次快照文件了,所以上述操作是安全操作!(那你说个屁!);

        好的,我们接下来就不shutdown 而是直接kill -9 来粗暴杀死redis的进程并且删除掉/var/run 下面redis_6379.pid,模拟redis的故障场景:

        这时就发现我们刚刚添加的三个值都拿不到了。

        然后我们自己手动设置一个检查点:save 5 1到redis的配置文件中。然后再次将刚刚三个值保存到redis中,然后等待五秒,重复上面杀死redis进程的操作,然后在重启redis,现在我们就发现之前的值没有因为redis被杀死而丢失。


        好的,以上就是我们使用RDB进行数据恢复的实验,save 5 1这个检查点记得注释掉或者删除,我们没有必要这么频繁的去生成快照。

2.AOF配置和数据恢复流程

(1).AOF的配置

        我们在redis的配置文件中搜索appendonly就可以找到aof的相关配置了。

        其实redis默认的持久化方式时rdb,rdb是默认打开的,我们要使用aof的话就需要单独打开。


aof配置

        在生产中,aof一般都是要打开的,除非你觉得丢失几分钟的数据无大碍。

        设置 appendonly yes 后就打开了aof,打开aof之后,redis每接受到一条命令都会先写入到日志文件中,当然不会直接写到aof文件中,他会先写入到ox cache中,然后每隔一段时间调用操作系统的fsync操作,将os cache中的数据同步到磁盘上的aof文件中。

        而且,当rdb和aof同时开启的时候,redis也会优先aof来进行数据恢复,因为aof的数据相对来说比rdb完整。

aof有三种策略供君选择:

appendfsync always: 

        每次写入一条数据,立即将这个数据对应的写日志fsync到磁盘上去,性能非常非常差,吞吐量很低; 如果说你要求redis里的数据一条都不丢,那就选择此策略。

appendfsync everysec:

        每秒将os cache中的数据fsync到磁盘,这个最常用的,生产环境一般都这么配置,性能很高,QPS还是可以上万的。

appendfsync no:

       redis 仅仅负责将数据写入os cache就不管了,然后os自己会时不时根据自己的策略将数据刷入磁盘,人为不可控。

(2).aof数据恢复实验

        首先我们打开aof的开关,启用aof,然后向redis中添加数据,然后找到aof文件(我的持久化文件放在:/var/redis/6379),aof中按顺序存放指令,如果你知道aof的规则的话是可以读懂的,也就是说,aof文件是可读的。

aof文件内容

        我使用的策略是everysec,也就是每秒调用一次fsync,redis先将数据写入os cache中,一秒后才调用fsync操作将数据写入磁盘中,数据没有写入磁盘的话是不安全的,也就是说,everysec还是有可能丢失一秒的数据。

        我们将redis的进程杀死,看看数据恢复成功了没:

aof数据恢复

        数据成功的被恢复了,redis进程启动的时候,直接就会从appendonly.aof中加载所有的日志,把内存中的数据恢复回来。

(3).aof的rewrite机制

redis中的数据其实有限的,很多数据可能会自动过期,可能会被用户删除,可能会被redis用缓存清除的算法清理掉。redis中的数据会不断淘汰掉旧的,就一部分常用的数据会被自动保留在redis内存中。所以可能很多之前的已经被清理掉的数据,对应的写日志还停留在AOF中,AOF日志文件就一个,会不断的膨胀,变得很大很大。所以AOF会自动在后台每隔一定时间做rewrite操作,比如日志里已经存放了针对100w数据的写日志了; redis内存只剩下10万; 基于内存中当前的10万数据构建一套最新的日志,到AOF中; 覆盖之前的老日志; 确保AOF日志文件不会过大,保持跟redis内存数据量一致。

首先,我们先去配置文件中搜索一下rewrite,可以看看相关的说明。

rewrite配置

        rewrite的策略我们使用默认的就好,有兴趣的读者可以去研究一下redis的rewrite策略,我在这里就讲一下上图对应的两个参数,这两个参数相对来说比较重要。这两个参数怎么解释呢?比如说上一次AOF rewrite之后,是128mb。然后就会接着128mb继续写AOF的日志,如果发现增长的比例,超过了之前的100%,256mb,就可能会去触发一次rewrite但是此时还要去跟min-size,64mb去比较,256mb > 64mb,才会去触发rewrite。

(4).aof rewrite过程详解

(a).redis fork一个子进程

(b).子进程基于当前内存中的数据,构建日志,开始往一个新的临时的AOF文件中写入日志

(c).redis主进程,接收到client新的写操作之后,在内存中写入日志,同时新的日志也继续写入旧的AOF文件

(d).子进程写完新的日志文件之后,redis主进程将内存中的新日志再次追加到新的AOF文件中

(e).用新的日志文件替换掉旧的日志文件


aofrewrite流程

(5).aof文件破损修复

        当redis在append数据到aof文件中的时候,服务器宕机了,那么就可能造成aof文件的损坏,redis提供了相关的工具来修复破损的aof文件。使用redis-check-aof --fix命令来修复破损的AOF文件。

        我们来做一个小实验,我们把备份的aof文件copy出来一份,然后更改它,是他破损,然后使用redis的修复工具来修复它。

        首先将aof文件copy出来

copy aof文件

我们编辑这个文件,然后更改这个文件:


更改后的文件

然后使用redis的修复工具修复这个文件:


修复之后的文件

redis修复工具就会把最后那行多余的指令删除掉。

3.RDB和AOF同时工作

        因为redis的持久化操作是非常消耗性能的,那么当他们俩发生冲突的时候会怎么办?

(1)如果RDB在执行snapshotting操作,那么redis不会执行AOF rewrite; 如果redis再执行AOF rewrite,那么就不会执行RDB snapshotting

(2)如果RDB在执行snapshotting,此时用户执行BGREWRITEAOF命令,那么等RDB快照生成之后,才会去执行AOF rewrite

(3)同时有RDB snapshot文件和AOF日志文件,那么redis重启的时候,会优先使用AOF进行数据恢复,因为其中的日志更完整

(4)在有rdb的dump和aof的appendonly的同时,rdb里也有部分数据,aof里也有部分数据,这个时候其实会发现,rdb的数据不会恢复到内存中

大家也可做个小实验,将aof中的数据删除一条(这条数据已经持久化到rdb中),然后用redis的修复工具进行修复,在用这个文件替换aof文件,重启redis,最后会发现rdb中的数据不会被恢复到内存中。

redis的数据恢复完全是依赖于底层的磁盘的持久化的,如果rdb和aof上都没有数据,那就真的没了。

4.在实际项目的使用中,我们应该如何配置和使用呢?

(1).配置策略

        在企业级的项目中,我们使用rdb的默认配置也无大碍,即:

save 900 1

save 300 10

save 60 10000

        唯一可能要调整的就是 save 60 10000 这个检查点,因为rdb的生成还是比较耗费资源的,如果说低峰期数据量很小,那么也没太大必要。但是如果你要保证RDB最多丢一分钟的数据,那么剩下的就是你自己根据实际情况去配置,到底是一分钟-10000生成rdb,还是说设置成1分钟-1000生成rdb。

    aof的话这里推荐把他打开,调用fsync的策略推荐使用everysec,然后根据你项目的实际情况去设置以下两个属性:

auto-aof-rewrite-percentage 100 这个属性改的必要也不是特别的大

auto-aof-rewrite-min-size 64mb 这个根据你的数据量来定

(2).数据备份方案

RDB的话是非常适合做冷备的,每次RDB生成完成之后就不会再修改了,备份的方案可以这样:

(a).写crontab定时调度脚本去做数据备份

(b).每小时都copy一份rdb的备份,到一个目录中去,仅仅保留最近48小时的备份

(c).每天都保留一份当日的rdb的备份,到一个目录中去,仅仅保留最近1个月的备份

(d).每次copy备份的时候,都把太旧的备份给删了

(e).每天晚上将当前服务器上所有的数据备份,发送一份到远程的云服务上去


每小时copy一次备份,删除48小时前的数据

crontab -e

0 * * * * sh /usr/local/redis/copy/redis_rdb_copy_hourly.sh

redis_rdb_copy_hourly.sh

```

#!/bin/sh

cur_date=`date +%Y%m%d%k`

rm -rf /usr/local/redis/snapshotting/$cur_date

mkdir /usr/local/redis/snapshotting/$cur_date

cp /var/redis/6379/dump.rdb /usr/local/redis/snapshotting/$cur_date

del_date=`date -d -48hour +%Y%m%d%k`

rm -rf /usr/local/redis/snapshotting/$del_date

```

每天copy一次备份

crontab -e

0 0 * * * sh /usr/local/redis/copy/redis_rdb_copy_daily.sh

redis_rdb_copy_daily.sh

```

#!/bin/sh

cur_date=`date +%Y%m%d`

rm -rf /usr/local/redis/snapshotting/$cur_date

mkdir /usr/local/redis/snapshotting/$cur_date

cp /var/redis/6379/dump.rdb /usr/local/redis/snapshotting/$cur_date

del_date=`date -d -1month +%Y%m%d`

rm -rf /usr/local/redis/snapshotting/$del_date

```

每天一次将所有数据上传一次到远程的云服务器上去

(3).数据恢复方案

(a).如果是redis进程挂掉,那么重启redis进程即可,直接基于AOF日志文件恢复数据。

(b).如果是redis进程所在机器挂掉,那么重启机器后,尝试重启redis进程,尝试直接基于AOF日志文件进行数据恢复。AOF没有破损,也是可以直接基于AOF恢复的,如果AOF文件出现了破损,则用redis的修复工具修复之后在进行恢复。

(c).如果redis当前最新的AOF和RDB文件出现了丢失/损坏,那么可以尝试基于该机器上当前的某个最新的RDB数据副本进行数据恢复。

(d).如果当前机器上的所有RDB文件全部损坏,那么从远程的云服务上拉取最新的RDB快照回来恢复数据。

(e).如果是发现有重大的数据错误,比如某个小时上线的程序一下子将数据全部污染了,数据全错了,那么可以选择某个更早的时间点,对数据进行恢复。

(4).基于RDB冷备恢复数据

        基于rdb冷备其实是有一些小坑的,这里拿出来记录一下,如果你同时打开RDB和AOF,如果你使用的是AOF的冷备去恢复数据,那么很简单,将redis的aof文件替换成你的冷备然后重启redis就行了。

        但是要是你使用的是RDB的冷备,你首先要把redis现有的aof文件删掉,然后把rdb文件替换成你的冷备,但是由于你开着aof,所以在aof启动的时候会直接生成一份空的aof文件,而你的RDB冷备会被无视掉,过了一段时间可能会被重写掉。你可能会想,那我们把AOF关掉不就行了吗?我们把AOF关掉,重启redis,确实,RDB的数据会被恢复到redis中,现在数据回来了,但是AOF不能关掉,所以你再次修改配置文件打开AOF重启redis,这时你发现辛辛苦苦恢复的数据又没了,其实还是因为打开AOF重新生成了一份空的AOF文件,RDB里面就算有数据也不会恢复到redis当中。那么怎么解决呢?我们可以通过热修改redis属性的方式进行恢复,我们先把redis的AOF关掉,用RDB冷备恢复数据,在redis-cli 中使用 config set 指令来开启AOF,等RDB冷备的数据全被写入AOF后,再修改配置文件打开AOF,重启redis即可。以下是具体的流程:

(a).停止redis

(b).关闭aof

(c).拷贝rdb备份

(d).重启redis,确认数据恢复

(e).直接在命令行热修改redis配置,打开aof,redis就会将内存中的数据对应的日志,写入aof文件中

(f).此时aof和rdb两份数据文件的数据就同步了

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

推荐阅读更多精彩内容

  • 企业级redis集群架构的特点 海量数据 高并发 高可用 要达到高可用,持久化是不可减少的,持久化主要是做灾难恢复...
    lucode阅读 2,146评论 0 7
  • 一、Redis高可用概述 在介绍Redis高可用之前,先说明一下在Redis的语境中高可用的含义。 我们知道,在w...
    空语阅读 1,585评论 0 2
  • redis的 rdb 和 aof 持久化的区别 aof,rdb是两种 redis持久化的机制。用于crash后,r...
    可可西里的星星阅读 333评论 0 0
  • 李宗盛的《鬼迷心窍》,歌词写的真心不错转载欣赏。最喜欢其中“春风再美也比不上你的笑”,这种美,绝了!蓝色连接是自己...
    枫之然阅读 287评论 12 11
  • 【读书要玩味】 纯属个人感受,勿喜勿喷,小小的分享 1.《月亮和六便士》——毛姆 正如文章前言所道,毛姆的小说...
    一个黄油酱阅读 236评论 0 1