设为首页 加入收藏

TOP

Redis数据持久化机制AOF原理分析一(三)
2014-11-24 08:09:17 来源: 作者: 【 】 浏览:12
Tags:Redis 数据 持久化 机制 AOF 原理 分析
ECT 命令来切换数据库 if (dictid != server.aof_selected_db) { char seldb[64]; snprintf(seldb,sizeof(seldb),"%d",dictid); buf = sdscatprintf(buf,"*2\r\n$6\r\nSELECT\r\n$%lu\r\n%s\r\n", (unsigned long)strlen(seldb),seldb); server.aof_selected_db = dictid; } // 将 EXPIRE / PEXPIRE / EXPIREAT 命令翻译为 PEXPIREAT 命令 if (cmd->proc == expireCommand || cmd->proc == pexpireCommand || cmd->proc == expireatCommand) { /* Translate EXPIRE/PEXPIRE/EXPIREAT into PEXPIREAT */ buf = catAppendOnlyExpireAtCommand(buf,cmd,argv[1],argv[2]); }// 将 SETEX / PSETEX 命令翻译为 SET 和 PEXPIREAT 组合命令 else if (cmd->proc == setexCommand || cmd->proc == psetexCommand) { /* Translate SETEX/PSETEX to SET and PEXPIREAT */ tmpargv[0] = createStringObject("SET",3); tmpargv[1] = argv[1]; tmpargv[2] = argv[3]; buf = catAppendOnlyGenericCommand(buf,3,tmpargv); decrRefCount(tmpargv[0]); buf = catAppendOnlyExpireAtCommand(buf,cmd,argv[1],argv[2]); } else {//其他的指令直接追加 /* All the other commands don't need translation or need the * same translation already operated in the command vector * for the replication itself. */ buf = catAppendOnlyGenericCommand(buf,argc,argv); } /* Append to the AOF buffer. This will be flushed on disk just before * of re-entering the event loop, so before the client will get a * positive reply about the operation performed. */ // 将 buf 追加到服务器的 aof_buf 末尾,在beforeSleep中写到AOF文件中,并且根据情况fsync刷新到硬盘 if (server.aof_state == REDIS_AOF_ON) server.aof_buf = sdscatlen(server.aof_buf,buf,sdslen(buf)); /* If a background append only file rewriting is in progress we want to * accumulate the differences between the child DB and the current one * in a buffer, so that when the child process will do its work we * can append the differences to the new append only file. */ //如果server.aof_child_pid不为1,那就说明有快照进程正在写数据到临时文件(已经开始rewrite), //那么必须先将这段时间接收到的指令更新的数据先暂时存储起来,等到快照进程完成任务后, //将这部分数据写入到AOF文件末尾,保证数据不丢失 //解释为什么需要aof_rewrite_buf_blocks,当server在进行rewrite时即读取所有数据库中的数据, //有些数据已经写到新的AOF文件,但是此时客户端执行指令又将该值修改了,因此造成了差异 if (server.aof_child_pid != -1) aofRewriteBufferAppend((unsigned char*)buf,sdslen(buf)); /*这里说一下server.aof_buf和server.aof_rewrite_buf_blocks的区别 aof_buf是正常情况下aof文件打开的时候,会不断将这份数据写入到AOF文件中。 aof_rewrite_buf_blocks 是如果用户主动触发了写AOF文件的命令时,比如 config set appendonly yes命令 那么redis会fork创建一个后台进程,也就是当时的数据快照,然后将数据写入到一个临时文件中去。 在此期间发送的命令,我们需要把它们记录起来,等后台进程完成AOF临时文件写后,serverCron定时任务 感知到这个退出动作,然后就会调用backgroundRewriteDoneHandler进而调用aofRewriteBufferWrite函数, 将aof_rewrite_buf_blocks上面的数据,也就是diff数据写入到临时AOF文件中,然后再unlink替换正常的AOF文件。 因此可以知道,aof_buf一般情况下比aof_rewrite_buf_blocks要少, 但开始的时候可能aof_buf包含一些后者不包含的前面部分数据。*/ sdsfree(buf); }
Server在每次事件循环之前会调用一次beforeSleep函数,下面看看这个函数做了什么工作?
/* This function gets called every time Redis is entering the
 * main loop of the event driven library, that is, before to sleep
 * for ready file descriptors. */
void beforeSleep(struct aeEventLoop *eventLoop) {
    REDIS_NOTUSED(eventLoop);
    listNode *ln;
    redisClient *c;

    /* Run a fast expire cycle (the called function will return
     * ASAP if a fast cycle is not needed). */
    if (server.active_expire_enabled && server.masterhost == NULL)
        activeExpireCycle(ACTIVE_EXPIRE_CYCLE_FAST);

    /* Try to process pending commands for clients that were just
首页 上一页 1 2 3 4 下一页 尾页 3/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇怎样恢复已经从回收站删除的文件 下一篇ORA-00942:表或视图不存在低级错..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·我的Linux内核学习笔 (2025-12-26 22:21:10)
·如何评价腾讯开源的 (2025-12-26 22:21:07)
·为什么TCP网络编程中 (2025-12-26 22:21:04)
·Python 数据分析与可 (2025-12-26 21:51:20)
·从零开始学Python之 (2025-12-26 21:51:17)