Skip to content

Latest commit

 

History

History
48 lines (30 loc) · 1.92 KB

redis-snapshot.md

File metadata and controls

48 lines (30 loc) · 1.92 KB

#持久化

Redis有全量(save/bgsave)持久化和增量(aof)的持久化命令。

##全量持久化, 快照

遍历里所有的 RedisDb ,读取每个 bucket 里链表的 key 和 value 并写入 dump.rdb 文件(rdb.c 405)。

save 命令直接调度 rdbSave 函数,这会阻塞主线程的工作,通常我们使用bgsave。

bgsave 命令调度 rdbSaveBackground 函数启动了一个子进程然后调度了rdbSave函数,子进程的退出状态由 serverCron的 backgroundSaveDoneHandler 来判断,这个在前面复制章节已经提及。

除了直接的save、bgsave命令之外,还有几个地方还调用到 rdbSaveBackground 和 rdbSave 函数。

  • shutdown:Redis 关闭调度的 prepareForShutdown 会做一次持久化工作,保证重启后数据依然存在,会调用 rdbSave。

  • flushallCommand:清空 Redis 数据后,如果不做立即执行一个 rdbSave,生成一个空的快照出现 crash 后,可能会载入含有老数据的快照。

    void flushallCommand(RedisClient *c) { touchWatchedKeysOnFlush(-1); server.dirty += emptyDb(); // 清空数据 addReply(c,shared.ok); if (server.bgsavechildpid != -1) { Kill(server.bgsavechildpid,SIGKILL); rdbRemoveTempFile(server.bgsavechildpid); } rdbSave(server.dbfilename); //没有数据的dump.db server.dirty++; }

  • sync:当master接收到slave发来的该命令的时候,会执行 rdbSaveBackground,这个以前也有提过。

###redis.conf 相关的参数

数据发生变化:在多少秒内出现了多少次变化则触发一次 bgsave,这个可以在 redis.conf 里配置。

for (j = 0; j < server.saveparamslen; j++) {
    struct saveparam *sp = server.saveparams+j;
    if (server.dirty >= sp->changes && now-server.lastsave > sp->seconds) {
        rdbSaveBackground(server.dbfilename);
        break;
  }
}