说一说Redis的持久化机制

Redis的持久化机制,主要有2种持久化方式,即RDB持久化和AOF持久化。

问题一:为何需要进行持久化?

        Redis作为内存数据库,其数据都被存储在内存中。也就是说Redis的服务器进程over或者运行载有Redis服务进程的JVM挂掉,其Redis服务器中的数据就会丢失。

         为了避免这种情况发生造成的数据丢失,Redis提供了持久化机制,即将存在内存中的数据保存到磁盘中(这里和ES的默认设置有部分类似,可以对照参考),用以在上述情况发生导致数据可能丢失时,快速恢复之前的数据。

问题二:什么是RDB持久化?

RDB持久化是在某个时间点上,将Redis中的数据通过快照的方式保存到一个后缀为.rdb的RDB文件中。也由于RDB持久化是快照方式保存的性质,所以也被称为快照持久化。

通过RDB持久化所生成的文件(.rdb)其实是一个经过压缩的二进制文件,该文件可以被还原成生成RDB文件时Redis中的数据(可以理解为原路返回)。

快照持久化的原理:

创建:

1.save命令

在redis运行中,可以通过发送save命令来拍摄快照。save命令是阻塞命令,也就是当服务器接收了一条save命令之后就会开始拍摄快照,在此期间不会再去处理其他的请求,其他请求会被挂起直到快照持久化备份结束才执行被刮起的其他请求。

直接在当前进程执行

2.bgsave命令

bgsave命令也是立即拍摄快照,这优于save命令,bgsave并不是一条阻塞命令,而是派生出(fork)一个子线程,然后这个子线程负责备份操作。而父进程继续处理客户端的请求,这样就不会造成阻塞了。

在当前进程创建子线程

说到这里敲一下小黑板:

因为BGSAVE命令可以在不阻塞服务器进程的情况下执行,所以推荐使用BGSAVE命令。我们可以手动执行该命令,但还是推荐设置一下Redis服务器配置文件的save选项,让服务器每隔一段时间自动执行一次BGSAVE命令。那么可以通过save选项设置多个保存条件,只要其中一个满足条件,服务器就会执行BGSAVE命令。

SNAPSHOTTING快照

上图中,默认的配置条件表示的含义是:只要满足三者之一,BGSAVE命令就会被执行,

服务器在900s之内,对数据库进行了至少1次修改;

服务器在300s之内,对数据库进行了至少10次修改;

服务器在60s之内,对数据库进行了至少10000次修改;

也就是说,在数据操作越频繁的情况下,越需要及时的进行快照持久化操作,以确保数据的安全。

Redis载入RDB文件:

并没有专用命令,而是在Redis服务器启动时自动执行,且Redis启动时是否会载入RDB文件还取决于服务器是否启用了AOF持久化功能,具体的前值判断如下:

1.只有在AOF持久化功能处于关闭状态时,服务器才会使用默认的RDB文件来还原数据。

2.如果服务器开启了AOF持久化(默认情况下AOF是关闭的),那么服务器会优先使用AOF文件来还原数据。

3种服务器状态:

1.save命令导致的Redis服务器阻塞状态,此处不再赘述;

2.bgsave命令,Redis服务器不会被阻塞,可以继续处理客户端发来的请求;

3.在载入RDB文件期间,会一直处于阻塞,知道RDB文件载入成功。

优缺点:

优点:

1.RDB文件是一个很简洁的单文件,它保存了某个时间点的Redis数据,很适合用于做备份。你可以设定一个时间点对RDB文件进行归档,这样就能在需要的时候很轻易的把数据恢复到不同的版本。

2.RDB很适合用于灾备处理。单文件很方便就能传输到远程的服务器上。

3.RDB的性能好,进行持久化时,主进程会派生一个子进程出来,然后把持久化的工作交给子进程,自己不会有相关的I/O操作。

4.比起AOF,在数据量比较大的情况下,RDB的启动速度更快。

缺点:

1.RDB容易造成数据的丢失。假设每5分钟保存一次快照,如果Redis因为某些原因不能正常工作,那么从上次产生快照到Redis出现问题这段时间的数据就会丢失。

2.RDB使用fork()产生子进程进行数据的持久化,如果数据比较大的话可能就会花费点时间,造成Redis停止服务几毫秒。如果数据量很大且CPU性能不是很好的时候,停止服务的时间甚至会到1s。

禁用快照持久化:

1.在redis.conf配置文件中注释掉所有的save配置;

2.在最后一条save配置追加    save" "    命令。


三、什么是AOF持久化?

概述:

AOF持久化是通过保存Redis服务器所执行的“写”命令来记录数据库数据的,如下图:

默认情况下,AOF持久化功能是关闭的,如果想要打开AOF,可以修改“appendonly no”为“sppendonly yes”,如图:

图片采自网络

(假设Redis中还未存储任何数据,我们执行了写命令,则Redis服务器会生成1个名为“appendonly.aof”文件,该文件打开后,里边会出现刚才执行的所有写命令。)

实现AOF:

当AOF持久化功能处于打开状态时,Redis服务器在执行完写命令之后,会将被执行的写命令追加到AOF缓冲区的末尾,Redis服务器会根据配置文件中的appendfsync选项的值来决定何时将AOF缓冲区中的内容写入和同步到AOF文件里边。(appendfsync选项有以下3个值:①always---always是最安全的,即丢失数据最少,即使出现故障停机,数据库也会只丢失一个循环中所产生的命令数据;但always效率最慢,因为在每个事件循环都要将AOF缓冲区中的所有内容写到AOF文件,并且同步AOF文件。②everysec---everysec即使出现故障停机,只会丢失一秒的命令数据;且everysec足够快因为它每隔一秒就要在子线程中对AOF文件进行同步。③no---如果故障停机,数据库会丢失上一次同步AOF文件之后的所有写命令数据,至于何时对AOF文件进行同步,则由操作系统决定,所以具有不确定性,no模式和everysec效率相当。)

综上所述,我们推荐使用everysec选项,正巧appendfsync选项的默认值也是everysec,因为货比三家之后,其即安全又高效。

载入AOF:

AOF文件包含了重建数据库所需的所有写命令,所以Redis只需要重新读取并执行一次AOF文件里边保存的写命令,就可以高度还原之前的数据。步骤如下:

1.创建一个不带网络连接的伪客户端;

2.从AOF文件中提取一条写命令;

3.使用为客户端执行2中提取的写命令;

4.循环执行2、3两步骤,直至AOF文件中的所有写命令被执行完毕。

正如之前所述,如果Redis服务器开启了AOF持久化,那么会优先使用AOF(启动时载入AOF文件)而非RDB。

AOF重写:

物极必反,因为AOF持久化是通过不停追加写命令执行的数据库记录数据,所以Redis运行时间越久,AOF文件内容越多,体积增大,会出现:

1.磁盘空间被占用过多,可能会对Redis服务器甚至整个计算机造成影响;

2.AOF文件体积越大,所需要的还原数据的时间就越久。

为了避免上述情况出现,Redis提供了AOF文件重写功能,即Redis服务器会创建一个新的AOF文件来代替现有的AOF文件,新旧AOF二者保存数据相同(此处与HashMap的扩容原理部分思想相似,HashMap是通过重新生成一个数组以存放更多数据,即小桶换大桶,有兴趣可访问https://blog.csdn.net/gaobai_Siri/article/details/104412819查看HashMap扩容原理),但是新的AOF文件会省去很多浪费空间的冗余命令,所以新AOF文件体积也会大幅缩小。

重写原理:

AOF文件重写并不需要对现有的AOF文件进行任何操作,而是从现有的Redis服务器中获取当前的数据库数据来实现。如果Redis服务器中存储的键值对足够多,AOF文件重写生成的新AOF文件就会减少很多的冗余命令,进而大大减小体积。(也就是说,AOF重写就是先从数据库中读取键现在的值,然后用一条写命令去记录键值对,替换之前记录这个键值对的所有写命令。)

但是,由于AOF文件重写会进行大量的文件写入操作,所以线程将被长时间阻塞,服务器将无法处理客户端发送过来的命令请求。为了避免该情况发生,Redis将AOF文件重写功能放到子进程执行:

1.子进程对AOF文件重写期间,服务器进程(父进程)可以继续处理命令请求,

2.子进程带有服务器进程的数据副本,使用子进程而不是线程,可以在避免使用锁的情况下,保证数据安全。

AOF后台重写步骤:

1.服务器进程创建子进程,子进程开始AOF文件重写;

2.创建子进程的同时,父进程执行的所有写命令,要同时写入AOF缓冲区和AOF重写缓冲区(此处是为了避免新旧AOF文件保存的数据库数据不一致);

3.子进程完成AOF文件重写,向父进程发送信号,父进程收到之后,会将AOF重写缓冲区的所有内容写入新AOF文件,并对新的AOF文件进行改名,原地覆盖现有的AOF文件,完成去旧迎新。

除了手动执行BGREWRITEAOF命令外,Redis还提供了2个配置项用来自动执行该命令。

auto-aof-rewrite-percentage 100   //当AOF文件的体积比上一次重写后的体积大了至少一倍(100%)时;

auto-aof-rewrite-min-size-64mb   //当AOF文件的体积大于64MB时;

Redis将自动执行BGREWRITEAOF命令。


说到此处,如果要对比说明RDB和AOF持久化的区别,应该分别从实现方法、文件体积、数据安全性、优先级谈起。

1.RDB是保存数据结果,AOF保存创建数据库(写命令)过程;

2.所以RDB相对于AOF来说AOF存在体积越来越大的困扰,但是通过重写AOF文件可解决;

3.AOF持久化的安全性要比RDB高,不仅因为在机器故障时,RDB可能丢失上一次RDB持久化后写入的数据,还因为AOF最多丢失1s的写入数据(默认使用everysec的情况)。

4.优先级取决于是否开启了AOF持久化,若已开启,则AOF优先,若未开启,只能是使用Redis默认的RDB文件来还原数据。


(版权侵删)

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

推荐阅读更多精彩内容

  • 一、Redis高可用概述 在介绍Redis高可用之前,先说明一下在Redis的语境中高可用的含义。 我们知道,在w...
    空语阅读 1,596评论 0 2
  • 企业级redis集群架构的特点 海量数据 高并发 高可用 要达到高可用,持久化是不可减少的,持久化主要是做灾难恢复...
    lucode阅读 2,200评论 0 7
  • 一、Redis持久化概述 持久化的功能:Redis是内存数据库,数据都是存储在内存中,为了避免进程退出导致数据的永...
    心似南风阅读 923评论 0 1
  • かぜ(風邪)感冒風邪を引(ひ)きます。 ねつ(熱)发烧,体温(还有“热度”的意思)熱があります。(倾向于表示状态)...
    lhhhq阅读 1,066评论 0 1
  • 我靠着监狱的墙 而你是贴在墙上的小姑娘 如果人生是一段时间 那么对于我,这最少的一半 应该付给精神 如果精神是一个...
    彭先生10阅读 134评论 0 3