本文所引用的源码全部来自Redis2.8.2版本。
Redis的配置文件为redis.conf, 对配置文件的解析代码见config.c
原创文章转载请注明,本文来自http://blog.csdn.net/acceptedxukai/article/details/18135219
AOF实现机制简介
AOF 即Append Only File,实现机制:Redis将数据库做个快照,遍历所有数据库,将数据库中的数据还原为跟客户端发送来的指令的协议格式的字符串,然后Redis新建一个临时文件将这些快照数据保存,待快照程序结束后将临时文件名修改为正常的aof文件名,原有的文件则自动丢弃,由于在快照进行的过程中可能存在新增的命令修改了数据库中的数据,则在快照程序结束后需要将新修改的数据追加到aof文件中,后续的从客户端过来的命令都会不断根据不同的安全级别写到磁盘里面去。这样就支持了实时的持久化,只是可能会有短时间内的数据丢失,对一般系统还是可以容忍的。
配置文件redis.conf中有关AOF参数配置解释
appendonly
含义:Redis Server是否开启AOF持久化机制
在config.c函数loadServerConfigFromString解析代码为
if (!strcasecmp(argv[0],"appendonly") && argc == 2) {
int yes;
if ((yes = yesnotoi(argv[1])) == -1) {
err = "argument must be 'yes' or 'no'"; goto loaderr;
}
server.aof_state = yes REDIS_AOF_ON : REDIS_AOF_OFF;
}
appendfsync
含义:Redis将OS数据缓冲区中数据刷新到磁盘的策略
# appendfsync always 只要有新添加的数据就fsync
appendfsync everysec 支持延迟fsync
# appendfsync no 不需要fsync
config.c中解析代码
if (!strcasecmp(argv[0],"appendfsync") && argc == 2) {//AOF fsync策略
if (!strcasecmp(argv[1],"no")) {
server.aof_fsync = AOF_FSYNC_NO;
} else if (!strcasecmp(argv[1],"always")) {
server.aof_fsync = AOF_FSYNC_ALWAYS;
} else if (!strcasecmp(argv[1],"everysec")) {
server.aof_fsync = AOF_FSYNC_EVERYSEC;
} else {
err = "argument must be 'no', 'always' or 'everysec'";
goto loaderr;
}
}
no-appendfsync-on-rewrite
含义:当rewrite AOF子进程或RDB子进程正在执行时,Server是否支持fsync,即当新修改的数据写入AOF文件后,是否将数据刷新到硬盘
config.c中解析代码
if (!strcasecmp(argv[0],"no-appendfsync-on-rewrite") && argc == 2) {
if ((server.aof_no_fsync_on_rewrite= yesnotoi(argv[1])) == -1) {
err = "argument must be 'yes' or 'no'"; goto loaderr;
}
}
server.aof_no_fsync_on_rewrite控制该机制的实现代码在aof.c的flushAppendOnlyFile函数中,具体代码为
//如果不支持fsync,或者aof rdb子进程正在运行,那么直接返回, //但是数据已经写到aof文件中,只是没有刷新到硬盘 if (server.aof_no_fsync_on_rewrite && (server.aof_child_pid != -1 || server.rdb_child_pid != -1)) return;
appendfilename
含义:AOF的文件名
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
这两个配置就暂不解释,见下面redisServer结构体中中有关AOF参数的注释
redisServer数据结构中有关AOF的参数
struct redisServer {
…………
/* AOF persistence */
int aof_state; /* REDIS_AOF_(ON|OFF|WAIT_REWRITE) */
int aof_fsync; /* Kind of fsync() policy */
char *aof_filename; /* Name of the AOF file */
int aof_no_fsync_on_rewrite; /* Don't fsync if a rewrite is in prog. */
int aof_rewrite_perc; /* Rewrite AOF if % growth is > M and... */
off_t aof_rewrite_min_size; /* the AOF file is at least N bytes. */ aof文件最小字节数
off_t aof_rewrite_base_size; /* AOF size on latest startup or rewrite. */ 上一次aof文件的大小
off_t aof_current_size; /* AOF current size. */ 当前aof文件的大小
int aof_rewrite_scheduled; /* Rewrite once BGSAVE terminates. */
pid_t aof_child_pid; /* PID if rewriting process */ 子进程的pid
list *aof_rewrite_buf_blocks; /* Hold changes during an AOF rewrite. */
sds aof_buf; /* AOF buffer, written before entering the event loop */
int aof_fd; /* File descriptor of currently selected AOF file */ aof文件描述符
int aof_selected_db; /* Currently selected DB in AOF */
time_t aof_flush_postponed_start; /* UNIX time of postponed AOF flush */
time_t aof_last_fsync; /* UNIX time of last fsync() */
time_t aof_rewrite_time_last; /* Time used by last AOF rewrite run. */
time_t aof_r