Redis源码剖析之持久化(3)

    创建一个不带网络连接的伪客户端,因为redis命令只能在客户端上下文中执行,而载入AOF文件所使用的命令直接来源AOF文件而不是网络连接,所以服务器使用了一个伪客户端来执行AOF文件保存的写命令,效果与客户端执行命令一样。

    从AOF文件中分析并读取一条写命令。

    使用伪客户端执行被读出的命令。

    重复上述步骤。

   3.AOF重写 

    因为AOF持久化是通过保存被执行的写命令来记录数据库状态的,所以随着服务器运行时间的流逝,AOF文件中的内容越来越多,文件的体积也会越来越大,如果不加以控制的话,过大的AOF文件可能对Redis服务器,甚至整个宿主计算机造成影响,并且AOF文件的体积越大,使用AOF文件来进行数据还原所需的时间就越多。

    如:
      >rpush list 'a' 'b'
      >rpush list 'c'
      >rpush list 'd'
      >rpush list 'e'

    上述光是记录list状态,AOF文件就要保存五条命令。为了解决上述问题,Redis提供了AOF文件重写功能。

    AOF文件重写并不需要对现有的AOF文件进行任何读取操作,而是根据现有的数据库状态,将其再次进行持久化操作,然后替换保存之前的文件。

    例如上述四条命令是文件记录的,将其还原到redis数据,那么保存在redis数据库中的是如下情景list-->['a','b','c','d','e'],现在我们要进行重写,则根据数据构造出命令:rpush list 'a' 'b' 'c' 'd' 'e'。这样我通过1条命令来代替上面的4条命令,从而大大节约了空间。这就是AOF文件重写功能。

    整个重写过程可用如下伪代码表示:

        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

# 写入Select命令,指定数据号码
                    f.write_command("SELECT" + db.id)

# 遍历数据库中的所有键
                    for key in db:
                        # 忽略已过期的键
                        if key.is_expired():continue

# 根据键的类型对键进行重写
                        if key.type == String:
                            rewrite_string(key)
                        elif key.type == List:
                            rewrite_list(key)
                        elif key.type == Hash:
                            rewrite_hash(key)
                        elif key.type == Set:
                            rewrite_set(key)
                        elif key.type == SortedSet:
                            rewrite_sorted_set(key)

# 如果键带有过期时间,那么过期时间也要被重写
                        if key.have_expire_time():
                            rewrite_expire_time(key)
                f.close()

def rewrite_string(key):
                # 使用GET命令获取字符串键的值
                value = GET(key)

# 使用SET命令重写字符串键
                f.write_command(SET,key,value)

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/0d33737369a96d387949bb8541a74607.html