redis之AOF文件加载过程
redis支持2种持久化功能,分别是RDB持久化和AOF(AppendOnlyFile)持久化。
今天总结下redis加载AOF文件过程,以及加载AOF过程中遇到的问题。
由于AOF文件里面包含了重建redis数据库状态所需要的所有命令,因此在redis启动过程中需要加载一次AOF文件(前提是redis配置文件中使用的是aof文件),这样就可以还原之前的redis所有状态了。
redis在启动时加载AOF过程如下intmain(intargc,charargv){。。。如果服务器不是运行在SENTINEL模式,那么执行以下代码if(!server。sentinelmode){sentinel和集群只能二选1ThingsnotneededwhenrunninginSentinelmode。redisLog(REDISWARNING,Serverstarted,RedisversionREDISVERSION);ifdeflinuxlinuxOvercommitMemoryWarning();endif从AOF文件或者RDB文件中载入数据loadDataFromDisk();判断是否启动集群if(server。clusterenabled){在该函数前会先载入cluster配置nodes。conf,见initServerclusterInit;if(verifyClusterConfigWithData()REDISERR){redisLog(REDISWARNING,YoucanthavekeysinaDBdifferentthanDB0wheninClustermode。Exiting。);exit(1);}}打印TCP端口if(server。ipfdcount0)redisLog(REDISNOTICE,Theserverisnowreadytoacceptconnectionsonportd,server。port);打印本地套接字端口if(server。sofd0)redisLog(REDISNOTICE,Theserverisnowreadytoacceptconnectionsats,server。unixsocket);}else{sentinel和集群只能二选1sentinelIsRunning();}Warningtheuseraboutsuspiciousmaxmemorysetting。检查不正常的maxmemory配置if(server。maxmemory0server。maxmemory10241024){redisLog(REDISWARNING,WARNING:Youspecifiedamaxmemoryvaluethatislessthan1MB(currentvalueisllubytes)。Areyousurethisiswhatyoureallywant?,server。maxmemory);}运行事件处理器,一直到服务器关闭为止aeSetBeforeSleepProc(server。el,beforeSleep);aeMain(server。el);服务器关闭,停止事件循环aeDeleteEventLoop(server。el);return0;}
从上面代码得知,redis在loadDataFromDisk()中加载AOF文件。voidloadDataFromDisk(void){loadDataFromDisk和rdbSave对应加载写入记录开始时间longlongstartustime();AOF持久化是否已打开if(server。aofstateREDISAOFON){尝试载入AOF文件if(loadAppendOnlyFile(server。aoffilename)REDISOK)打印载入信息,并计算载入耗时长度redisLog(REDISNOTICE,DBloadedfromappendonlyfile:。3fseconds,(float)(ustime()start)1000000);AOF持久化未打开}else{尝试载入RDB文件if(rdbLoad(server。rdbfilename)REDISOK){打印载入信息,并计算载入耗时长度redisLog(REDISNOTICE,DBloadedfromdisk:。3fseconds,(float)(ustime()start)1000000);}elseif(errno!ENOENT){redisLog(REDISWARNING,FatalerrorloadingtheDB:s。Exiting。,strerror(errno));exit(1);}}}
若开启使用的是AOF持久化,则调用loadAppendOnlyFile进行加载AOF文件。intloadAppendOnlyFile(charfilename){伪客户端structredisClientfakeClient;打开AOF文件FILEfpfopen(filename,r);、structredisstatsb;intoldaofstateserver。aofstate;longloops0;检查文件的正确性if(fpredisfstat(fileno(fp),sb)!1sb。stsize0){server。aofcurrentsize0;fclose(fp);returnREDISERR;}检查文件是否正常打开if(fpNULL){redisLog(REDISWARNING,Fatalerror:cantopentheappendlogfileforreading:s,strerror(errno));exit(1);}TemporarilydisableAOF,topreventEXECfromfeedingaMULTItothesamefilewereabouttoread。暂时性地关闭AOF,防止在执行MULTI时,EXEC命令被传播到正在打开的AOF文件中。server。aofstateREDISAOFOFF;创建一个伪客户端fakeClientcreateFakeClient();设置服务器的状态为:正在载入startLoading(fp);startLoading定义于rdb。cwhile(1){intargc,j;unsignedlonglen;robjargv;charbuf〔128〕;sdsargsds;structredisCommandcmd;Servetheclientsfromtimetotime间隔性地处理客户端发送来的请求因为服务器正处于载入状态,所以能正常执行的只有PUBSUB等模块if(!(loops1000)){loadingProgress(ftello(fp));processEventsWhileBlocked();}读入文件内容到缓存if(fgets(buf,sizeof(buf),fp)NULL){if(feof(fp))break;文件已经读完,跳出elsegotoreaderr;}确认协议格式,比如3rif(buf〔0〕!)gotofmterr;取出命令参数,比如3r中的3argcatoi(buf1);至少要有一个参数(被调用的命令)if(argc1)gotofmterr;从文本中创建字符串对象:包括命令,以及命令参数例如3rSETr3rKEYr5rVALUEr将创建三个包含以下内容的字符串对象:SET、KEY、VALUEargvzmalloc(sizeof(robj)argc);for(j0;jargc;j){if(fgets(buf,sizeof(buf),fp)NULL)gotoreaderr;if(buf〔0〕!39;)gotofmterr;读取参数值的长度lenstrtol(buf1,NULL,10);读取参数值argsdssdsnewlen(NULL,len);if(lenfread(argsds,len,1,fp)0)gotofmterr;为参数创建对象argv〔j〕createObject(REDISSTRING,argsds);if(fread(buf,2,1,fp)0)gotofmterr;discardCRLF}Commandlookup查找命令cmdlookupCommand(argv〔0〕ptr);if(!cmd){redisLog(REDISWARNING,Unknowncommandsreadingtheappendonlyfile,(char)argv〔0〕ptr);exit(1);}Runthecommandinthecontextofafakeclient调用伪客户端,执行命令fakeClientargcargc;fakeClientargvargv;cmdproc(fakeClient);ThefakeclientshouldnothaveareplyredisAssert(fakeClientbufpos0listLength(fakeClientreply)0);ThefakeclientshouldnevergetblockedredisAssert((fakeClientflagsREDISBLOCKED)0);Cleanup。Commandcodemayhavechangedargvargcsoweusetheargvargcoftheclientinsteadofthelocalvariables。清理命令和命令参数对象for(j0;jfakeClientargc;j)decrRefCount(fakeClientargv〔j〕);zfree(fakeClientargv);}ThispointcanonlybereachedwhenEOFisreachedwithouterrors。IftheclientisinthemiddleofaMULTIEXEC,logerrorandquit。如果能执行到这里,说明AOF文件的全部内容都可以正确地读取,但是,还要检查AOF是否包含未正确结束的事务if(fakeClientflagsREDISMULTI)gotoreaderr;fclose(fp);释放伪客户端freeFakeClient(fakeClient);复原AOF状态server。aofstateoldaofstate;停止载入stopLoading();更新服务器状态中,AOF文件的当前大小aofUpdateCurrentSize();记录前一次重写时的大小server。aofrewritebasesizeserver。aofcurrentsize;returnREDISOK;读入错误readerr:非预期的末尾,可能是AOF文件在写入的中途遭遇了停机if(feof(fp)){redisLog(REDISWARNING,Unexpectedendoffilereadingtheappendonlyfile);文件内容出错}else{redisLog(REDISWARNING,Unrecoverableerrorreadingtheappendonlyfile:s,strerror(errno));}exit(1);内容格式错误fmterr:redisLog(REDISWARNING,Badfileformatreadingtheappendonlyfile:makeabackupofyourAOFfile,thenuse。redischeckaoffixfilename);exit(1);}
由于AOF文件中保存的都是用户可见的一条条命令,因此loadAppendOnlyFile通过创建一个伪客户端读取AOF文件获取一条条命令来恢复执行。
redis读取AOF文件并还原数据库的状态过程如下:
以上就是服务器根据读入AOF文件进行还原数据库状态的原理。
从上面的介绍可以知道加载AOF文件是redis启动过程中的步骤,当业务线程启动连接redis获取或者保存数据时,若redis正在加载数据,则有可能获取不到数据:127。0。0。1:6379geta(error)LOADINGRedisisloadingthedatasetinmemory
原因是当加载过程中,有些客户端发来的命令是不执行的,直接返回上述结果。只有命令带有l(小写的L)标志的才会执行,比如info命令等。
那么怎么判断AOF文件是否加载完成呢?
刚才说到加载时可以执行info命令,redisinfo命令以一种易于理解和阅读的格式,返回关于Redis服务器的各种信息和统计数值。该统计信息中有Persistence参数,该参数中记录着RDB和AOF的相关信息,其中有个loading字段标志这数据是否正在加载,当正在加载时为1,加载完为0,因此可以根据该字段来判断数据是否加载完毕。127。0。0。1:6379infoPersistencePersistenceloading:11表示正在加载数据。。。127。0。0。1:6379infoPersistencePersistenceloading:00表示数据加载完毕。。。
因此业务线程可以根据info命令获取loading进行判断数据是否加载完毕。publicbooleanisLoading(){try{Stringinfo(String)redisTemplate。getRequiredConnectionFactory()。getConnection()。info(Persistence)。get(loading);if(0。equalsIgnoreCase(info)){returntrue;}}catch(Exceptione){error(Failedtogetloadingstatus:{},e。getMessage());}returnfalse;}
小山眉的画法小山眉画法技巧图解眉毛的形状种类有很多,不同的眉形画出来给人的感觉都很不样,眉毛是很关键的一个存在,很多人应该都听说过小山眉,小山眉在古代非常流行,那么我们一起来学学小山眉的画法,小山眉画法技巧……
复古传奇萌新玩家如何在复古传奇游戏中打金?hello大家早啊,风靡全国的传奇游戏已经有20多年的历史,一直深受欢迎。有的玩家仅仅是想打发下班后的一些空闲时间,有的玩家是想在游戏中找朋友,而一些高端玩家就想在游戏中打金赚……
哑光眼影适合什么人单眼皮和内双首选眼影按照妆效和质地来分,分为哑光眼影和珠光眼影,哑光在美妆界和时尚圈都是高级的代名词,因为它很低调,且不会有闪粉的感觉,十分有质感,下面5号网小编带大家来看一下哑光眼影适合什么……
篮网客战负开拓者,杜兰特半场20分北京时间2022年1月11日,篮网远赴波特兰挑战开拓者,本场比赛双方均有主将缺席,篮网队哈登和阿尔德里奇休战,开拓者利拉德因受到腹沟股伤势可能赛季报销,麦科勒姆也缺缺席比赛。……
2018可乐美甲最新款式今年夏天最流行的可乐美甲最近的天气真的是一天比一天热,出门在外的时候,总是幻想着自己可以带上一个能移动的空调才好呢,好不容易挨到回家的时候,打开冰箱一瓶冰镇可乐入肚,才觉得自己是活着的,可你知道吗,可……
蜜丝佛陀粉饼一共有几款蜜丝佛陀粉饼哪个好很多MM都说夏天不想化妆,因为流汗脸上就出现一道黄一道白,挤个交通工具却弄花了精致的妆容。因为花妆破坏了一天的好心情,说多了心都lay了。所以需要一款好用的粉饼防止脱妆,蜜丝佛……
恭喜哈登!恭喜格林!火箭公布交易态度,费尔蒂塔不信任195后北京时间12月29日,NBA常规赛已经开启第六十六天左右,其中达拉斯独行侠管理层内部对于扣篮王扎克拉文非常感兴趣,想让他来辅佐卢卡东契奇冲击总冠军,乔尔恩比德表示,对手比他们的……
脸大化什么妆比较好脸大适合吸睛的欧美妆容脸大妹子五官比较扁平,所以化妆时要化那种很吸人眼球的妆容,来盖住寡淡无奇的脸部,而欧美妆是最合适的了,欧美妆比较浓,能让一个平凡的亚洲大脸星人大放异彩。脸大化什么妆比较好……
婉约妆容怎么画让你散发古典韵味的化妆教程今天要分享的妆容多了一些古典的韵味呢,很有温婉女性的风采,这是一款很清淡的眼妆,眼妆不重,强调了一下眼部的轮廓就能让双眼变得非常的有神,想知道怎么是怎么化的就继续往下看吧。……
马来西亚公开赛开打凡尘组合迎来新赛季首战资料图:贾一凡(左)与搭档陈清晨(右)。图新华网红网时刻新闻1月11日讯(记者周雨墨)1月10日至15日,马来西亚羽毛球公开赛将在吉隆坡进行,作为世界羽联巡回赛超级100……
威刚发布旗下首款USB4接口的SSD移动硬盘IT之家1月6日消息,威刚发布了旗下首款搭载USB4接口的SSD移动硬盘SE920。图源techpowerup,下同该移动硬盘采用了40GbpsUSB4接口,内部采……
场均21分13板,年薪仅213万!浓眉收获黄金搭档,哈姆宣布新年新气象,新年新希望!NBA迈入2023年的新征程以来,联盟仅有4支球队保持全胜,他们分别是尼克斯、森林狼、灰熊和湖人!如果说尼克斯森林狼灰熊队的异军突起在情理之中,那么湖人……
我国上市金融机构数字化转型研究当前,数字经济发展浪潮蓬勃兴起,加快推进数字化转型已成为广大金融机构顺应数字经济发展趋势、提升自身竞争力、提高服务实体经济和人民生活能力的关键手段。我国上市金融机构在技术、资金……
哪些口红颜色显老18岁驾驭不住的口红色号有一些口红颜色,是青春无敌的18岁都驾驭不了的。下面5号网小编带大家来看一下哪些口红颜色显老?18岁驾驭不住的口红色号。哪些口红颜色显老很多小女生在种草口红颜色的时候,都……
总资产达10万亿的集团,中国平安名字带中国,大股东却是外资在很多人的印象里,金融行业是十分赚钱的,而银行则是金融行业的主要组成部分。就我国的四大国有银行来说,他们每一年的营收都可以超过万亿。令人比较震惊的是,在中国企业500强的……
斯诺克英国公开赛中国外战1胜3负,赵心童颜丙涛携19人进正赛北京时间9月27日凌晨六点,斯诺克英国公开赛,延期至正赛阶段的赛会前十六号种子的资格赛全部决出胜负。中国军团的六位球员出战延期资格赛,表现中庸,种子球员赵心童德比战胜白朗……
腮红是定妆前还是定妆后打?很多人分不清腮红应该是什么时候使用,其实化妆顺序不对对妆容是有一定的影响的,这个一定要注意了。下面介绍腮红是定妆前还是定妆后打?腮红是定妆前还是定妆后打腮红即使用在散粉之……
关于生命的起源我们千百次的问?我是谁?我们从哪里来?我们到哪里去?这是人类的终极之问。是人类对自身存在的拷问,更是人类科学和思想的破茧成蝶,晋升之问。目前,世界有两大答案。人是自然进化的产……
罗布人村寨因塔河而兴旺8月3日,游客在尉犁县罗布人村寨景区游览。王雪摄天山网讯(记者任江报道)站在尉犁县罗布人村寨景区的吊桥上,脚下便是塔里木河,一侧是景区民宿、民俗展示点,另一侧是起伏的沙丘……
CNN评为中国最美!这座1800年的避世小城,才是江南最后的在浙江有一座避世小城,一到夏天就美成了诗,像是苏杭和大理的结合体。陶渊明诗句中的采菊东篱下,悠然见南山,在这成为现实。无数影视剧都美到来这里取景,倪妮、刘诗诗、杨丞琳、张……
新都,全国百强号外!号外11月18日《光明日报》刊发了《2022年中国中小城市高质量发展指数研究成果》新都区榜上有名全国综合实力百强区全国投资潜力百……
洋河2022年中报分析改革红利的释放与富余资金的隐患8月26日,洋河股份发布2022年中报。2022年上半年,公司实现营业收入189。08亿(vs去年同期155。43亿),同比增长21。65;实现归母净利为69亿(vs去年……
倩碧魔妆点点棒色号倩碧魔妆点点棒试色倩碧的魔妆点点棒可是一款热销产品呢,它既可以是遮瑕笔也可以是粉底。今天5号网小编就要为大家介绍一下,倩碧魔妆点点棒色号有哪些?倩碧魔妆点点棒试色怎么样?倩碧魔妆点点棒介绍……
泰国nani唇釉好用吗配方是有缺陷的前段时间也不知道为啥感觉不管在哪里都能看到点泰国彩妆推荐,差不多都号称大牌的平价替代,出于好奇心我就去搜了搜,发现现在泰国大大小小的彩妆品牌还真不少,下面5号网小编带大家来看一……