AOF 文件重写算法

为了解决AOF文件体积膨胀的问题,Redis提供了AOF文件重写功能,新生成一个AOF文件来替代现有的AOF文件,新旧两个文件所保存的数据库状态相同,但新文件不会包含任何冗余命令,所以新AOF文件的体积会比旧的文件小。

redis的重写aof算法非常的聪明。

直接读取key的值,获取最新的key当前的值,然后用一条命令就可以做为这个key的当前状态。

def aof_rewrite(new_aof_file_name):
    # 创建新的AOF文件
  	f = create_file(new_aof_file_name)
  
    # 遍历数据库
    for db in redisServer.db:
       # 忽略空数据库
       if db.is_empty(): continue
   
       # 显示指定数据库
       f.write_command("SELECT "+ db.id)  
   
       for key in db:
       	# 忽略已过期的key
       	if key.is_expired(): continue
         # 根据key的类型对key进行重新
         switch(key.type):
             case String:
               rewrite_string(key) #根据key获取到所有的value 然后拼成写入命令即可
             case List:
               rewrite_list(key)
             case Hash:
               rewrite_hash(key)
             case Set:
               rewrite_set(key)
             case SortedSet:
               rewrite_sorted_set(key)  
  	 if key.have_expire_time()
           rewrite_expire_time(key)
     #写入完毕,关闭文件
     f.close()

在实际中,重写程序在处理列表,哈希表,集合,有序集合这四种带有多个元素的键时,会先检查键所包含的元素数量,如果元素的数量超过了redis.h/REDIS_AOF_REWRITE_ITEMS_PER_CMD 常量的值,那么重写程序将使用多条命令来记录键的值,而不是单单一条命令。在redis 2.9 版本中这个常量的值为64。