Redis持久化--RDB+AOF

1、Redis两种持久化方式

  • RDB
    • 执行机制:快照,直接将databases中的key-value的二进制形式存储在了rdb文件中
    • 优点:性能较高(因为是快照,且执行频率比aof低,而且rdb文件中直接存储的是key-values的二进制形式,对于恢复数据也快)
    • 缺点:在save配置条件之间若发生宕机,此间的数据会丢失
  • AOF
    • 执行机制:将对数据的每一条修改命令追加到aof文件
    • 优点:数据不容易丢失
    • 缺点:性能较低(每一条修改操作都要追加到aof文件,执行频率较RDB要高,而且aof文件中存储的是命令,对于恢复数据来讲需要逐行执行命令,所以恢复慢)

2、RDB

实际中使用的配置(在redis.conf)

#发生以下三种的任何一种都会将数据库的缓存内容写入到rdb文件中去(写入的方式是bgsave)
#若将下述的三条命令都注释掉,则禁止使用rdb
save 900 1      #900s后至少有一个key发生了变化
save 300 10      #300s后至少有10个key发生了变化
save 60 10000    #60s后至少有10000个key发生了变化

#当后台RDB进程导出快照(一部分的key-value)到rdb文件这个过程出错时(即最后一次的后台保存失败时),
#redis主进程是否还接受向数据库写数据
#该种方式会让用户知道在数据持久化到硬盘时出错了(相当于一种监控);
#如果安装了很好的redis持久化监控,可设置为"no"
stop-writes-on-bgsave-error yes

#使用LZF压缩字符串,然后写到rdb文件中去
#如果希望RDB进程节省一点CPU时间,设置为no,但是可能最后的rdb文件会很大
rdbcompression yes

#在redis重启后,从rdb文件向内存写数据之前,是否先检测该rdb文件是否损坏(根据rdb文件中的校验和check_sum)
rdbchecksum yes

#设置rdb文件名
dbfilename dump.rdb

#设置rdb文件的存储目录
dir ./

说明

  • 具体每一项配置的详细说明看注释

注意

  • 对于save命令而言,配置了该命令,后台是以bgsave来执行的
    • bgsave:Redis主进程进行数据读写操作,RDB子进程进行数据的持久化操作,在进行持久化操作时,不阻塞主进程的读写操作
  • 以上三条save命令只要发生任一条,bgsave命令都会发生,这就有两个问题,假设60s内有10000个key发生了改变(写入、删除、更新),那么是否会立即进行持久化呢?在这次持久化之后,假设又过了240s,而在此期间没有任何的key的改变操作,此时是否要发生一次持久化(因为满足300s发生了10个key的改变,这里是改变了10000个key)?
    • 不会立即进行持久化:redis默认每隔100ms使用serverCron函数检查一次save配置的条件是否满足,满足则进行bgsave,这样的话,如果在100ms内,我已经满足了bgsave的条件,那么我真正执行bgsave的时候也要等到serverCron执行过来的时候
    • 不会再发生持久化:redis有两个参数dirty(记录上一次bgsave之后的key的修改数,上边的在240s内例子就是0)和lastsave(上一次成功执行bgsave命令的时间),配置中的每一个save配置的修改数指的就是dirty,而每一个时间段就是以lastsave为起点计算的。
  • 注释掉所有的save命令,RDB将不起作用
  • rdbcompression yes:配置成这样是不是每一个字符串在存储到rdb文件中时,都要进行一次压缩操作?
    • 不是:设置为yes之后,只有当字符串的长度大于等于21个字节时,才会进行压缩
  • rdbchecksum yes:这个校验和存储在哪里?为什么通过比对校验和可以判断文件是否损坏?
    • 校验和(check_sum)存储在RDB文件的最后八个字节中(详细的RDB文件结构,查看《Redis这基于实现》"第10章 RDB持久化"),简单的RDB文件结构如下:
      • RDB文件开头的前五个字节"REDIS"是判断一个文件是不是RDB文件的标准(类似于class文件中的"魔数")
      • 接下来的4个字节:RDB文件版本号(db_version)
      • databases(注意是复数):这里存放各个库redisDb中存储的key-value信息(是整个数据持久化和恢复的核心)
      • EOF(1个字节):RDB文件正文的结束
      • check_sum(8个字节):检验和,该值是根据前边四部分值算出来的,在持久化的时候将该值算出来并写入rdb文件的末尾;在根据rdb文件恢复数据的时候,再根据rdb文件中的前边四部分值计算出一个校验和,然后与当前rdb文件中的check_sum(即后八个字节)的内容进行比对,如果一样,说明没损坏,如果不一样,说明前四部分有数据损坏(即该文件损坏)
  • 在Redis服务器启动时,redis会自动检测是否有rdb文件(前提是没有aof的时候),如果有,则根据rdb文件恢复数据,此时在恢复数据完成之前,会阻塞客户端对redis的读写操作

3、AOF

实际中使用的配置(在redis.conf)

# 是否打开aof日志功能(appendonly yes)
appendonly no

# aof文件的存放路径与文件名称
# appendfilename appendonly.aof

#每一个命令,都立即同步到aof文件中去(很安全,但是速度慢,因为每一个命令都会进行一次磁盘操作)
# appendfsync always
#每秒将数据写一次到aof文件
appendfsync everysec
#将写入工作交给操作系统,由操作系统来判断缓冲区大小,统一写到aof文件(速度快,但是同步频率低,容易丢数据) 
# appendfsync no

# 在RDB持久化数据的时候,此时的aof操作是否停止,若为yes则停止
# 在停止的这段时间内,执行的命令会写入内存队列,等RDB持久化完成后,统一将这些命令写入aof文件
# 该参数的配置是考虑到RDB持久化执行的频率低,但是执行的时间长,而AOF执行的频率高,执行的时间短,
# 若同时执行两个子进程(RDB子进程、AOF子进程)效率会低(两个子进程都是磁盘读写)
# 但是若改为yes可能造成的后果是,由于RDB持久化执行时间长,在这段时间内有很多命令写入了内存队列,
# 最后导致队列放不下,这样AOF写入到AOF文件中的命令可能就少了很多
# 在恢复数据的时候,根据aof文件恢复就会丢很多数据
# 所以,选择no就好
no-appendfsync-on-rewrite no

# AOF重写:把内存中的数据逆化成命令,然后将这些命令重新写入aof文件
# 重写的目的:假设在我们在内存中对同一个key进行了100次操作,最后该key的value是100,
# 那么在aof中就会存在100条命令日志,这样的话,有两个缺点:
# 1)AOF文件过大,占据硬盘空间 2)根据AOF文件恢复数据极慢(需要执行100条命令)
# 如果我们将内存中的该key逆化成"set key 100",然后写入aof文件,
# 那么aof文件的大小会大幅度减少,而且根据aof文件恢复数据很快(只需要执行1条命令)
# 注意:下边两个约束都要满足的条件下,才会发生aof重写;
# 假设没有第二个,那么在aof的前期,只要稍微添加一些数据,就发生aof重写
# 当aof的增长的百分比是原来的100%(即是原来大小的2倍,例如原来是100m,下一次重写是当aof文件是200m的时候),AOF重写
auto-aof-rewrite-percentage 100  
auto-aof-rewrite-min-size 64mb   #AOF重写仅发生在当aof文件大于64m时

说明:

  • 具体每一项配置的详细说明看注释

注意:

  • 每一个客户端命令在执行时都会直接将命令写入AOF缓冲区
    • appendfsync always:每一个命令进入缓冲区后,都会立即再从缓冲区追加到AOF文件中
    • appendfsync everysec:每一秒后将缓冲区中的所有命令追加到AOF文件中
    • appendfsync no:每一个命令进入缓冲区后,由操作系统来判断什么时候(主要是缓冲区快满的时候)将缓冲区中的所有命令追加到AOF文件中
  • aof重写需要满足配置文件中的两个条件
  • aof重写采用后台子进程执行
    • aof的重写会进行大量的写入操作,如果用单线程来做这个事儿,就会长时间阻塞主进程(redis是单线程),这个时候客户端的读写就会失效
    • 采用aof后台重写进程造成的问题:
      • 如果在后台进程重写期间,有新的命令对数据库进行了读写,新的aof文件就与数据库的存储内容不同了。(注意:在后台进程重写期间,对数据库的读写操作还会进入aof缓冲区,还是会执行aof文件的命令写入,但需要注意的是,虽然这个期间所有的命令还是写入aof文件了,但是这个aof文件会被重写后的新的aof文件所替换,新的aof文件可没有这些命令,那么如果在下次重写发生之前发生宕机,采用aof恢复数据库的时候,那就丢失了很多命令了)
      • 解决方案:设置一个aof重写缓冲区,仅仅用于在后台进程重写期间,将发生的数据库读写命令写入到重写缓冲区中(当然,此时的服务器进程除了将发生的数据库读写命令写入到重写缓冲区中,还会写入到aof缓冲区,来保证正常的aof操作),之后当重写子进程完成重写后,向服务器主进程发送一个信号,此时服务器主进程将aof重写缓冲区中的命令追加到新的aof文件中去,用新的aof文件替换掉旧的aof文件。
    • 注意:
      • 在后台进程重写期间,将发生的数据库读写命令写入到重写缓冲区中时,为什么还要将这些命令写入到aof缓冲区(因为这些命令会写入旧的aof文件)?

        • 如果能百分之百保证在最后的主进程用新的aof文件替换了旧的aof文件(就是在这之前不宕机),那么写入到aof缓冲区没用(因为会被覆盖),但是如果在这之前宕机,那么我们的aof文件还是旧的aof文件,这时候命令写入到aof缓冲区就可以保证该aof文件尽可能多的保存命令,将来用于恢复数据库最多丢失的也就是1s的数据。(appendfsync everysec)
      • 在"服务器主进程将aof重写缓冲区中的命令追加到新的aof文件中去"这段操作期间,如果有新的客户端读写命令,都将被阻塞(因为是主进程在做上述操作)。这也是整个aof重写过程中唯一被阻塞的部分。

总结:

  • 如果既配置了RDB,又配置了AOF,则在进行数据持久化的时候,都会进行,但是在根据文件恢复数据的时候,以AOF文件为准,RDB文件作废
    • 需要注意:数据的恢复是阻塞操作(此间所到来的任何客户端读写请求都失效)
  • bgsave和bgrewriteaof(后台aof重写)这两个命令不可以同时发生
    • 如果bgsave在执行,此间到来的bgrewriteaof在bgsave执行之后,再执行
    • 如果bgrewriteaof在执行,此间到来的bgsave丢弃
  • RDB和AOF可以同时配置,但是最后还原数据库的时候是以aof文件来还原的

原文:https://www.cnblogs.com/java-zhao/p/5205768.html

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

推荐阅读更多精彩内容