一、 redis中有两种持久化方式,一种为RDB文件,另一种为AOF(append only file)文件,如果同时存在RDB文件和AOF文件,在redis启动的时候优先使用AOF文件进行加载
(1)RDB文件保存redis中每个数据库的每个键值对,对应格式为:
| REDIS | db_version | databases | EOF | check_sum |
其中第一部分为REDIS字符串,redis启动时可以快速的知道这是RDB文件。对于每个非空数据库,都有一套db_version和databases的数据,其中包含此非空数据库的所有键值对,EOF为所有非空数据库之后的结束符,最后一部分为校验和,此校验和对前四个部分所有内容进行校验。
在redis客户端,使用SAVE命令或者BGSAVE命令进行RDB文件的更新。
(2)AOF文件保存每次写数据库的写命令请求,使用redis的传输协议进行保存,类似如下所示:
*2\r\n$6\r\nSELECT\r\n$1\r\n0\r\n
*3\r\n$3\r\nSET\r\n$3\r\nmsg\r\n$5\r\nhello\r\n
每次redis启动加载时候,只需启动一个伪客户端,将AOF中所有的命令执行一遍即可恢复数据
二、 AOF文件重写
如果redis服务器一直接收数据库写命令,AOF一直追加命令,会造成AOF文件极大的情况,这是需要AOF文件重写
AOF文件重写即将原来较大的AOF文件整理成新的AOF文件,将一些冗余的命令合并到一起
例如,对于redis对原AOF文件进行的操作为:
RPUSH list "a"
RPUSH list "b"
RPUSH list "c"
RPUSH list "d"
经过AOF文件重写之后,新的AOF文件内包含的操作为:
RPUSH list "a" "b" "c" "d"
这样可以减少一些冗余的命令,极大减少AOF文件的大小
当进行AOF文件重写的时候,redis服务器启动一个子进程执行重写操作,之所以用子进程而不是用子线程是因为可以防止一些加锁操作
在AOF文件重写的过程中,如果有新的redis请求命令,将其缓存在一个AOF重写缓冲区中,在子进程完成AOF文件重写之后将AOF重写缓冲区内的内容追加到新的AOF文件后面,可以防止命令丢失。重写之后原子性的将旧的AOF文件替换成新的AOF文件,至此,AOF文件重写完成。
三、 在redis源码中:
1、redis将所有的数据库信息保存在redisServer.db中,其中redisServer.dbnum保存数据库的个数,默认值为16,可以使用配置文件进行更改
2、每个redis数据库中主要的结构有两个,一个为dict:存放所有的键值对,另一个为expire:存放所有带有过期时间的键
3、对于redis的过期键,有两种删除方式:惰性删除(即每次当键被访问的时候,检查其过期时间,如果已经过期,将其删除,否则获取其值),定时删除(每隔一段时间对键值进行检查,并将过期的键删除)
4、从服务器只接受主服务器的命令,如果从服务器的一个键值过期了,他自己不会处理,这时候如果来一个访问此键值的请求,按照通常情况返回其值。只有当主服务器向从服务器发送这个键值的del命令,从服务器才会将其删除。