redis持久化
1 persistence原理
redis databse在指定的时间间隔内生成数据集的时间点快照。比如,磁盘刷入频率为5m,0.00分redis会把数据持久化成一个文件。0.05分,再次把新的数据持久化成一个新的文件,完成后,把0.00分的文件删掉。这样,就保证得到的都是完整的数据。但只要宕机,这5分钟之内的数据就没了。
append only file:只允许追加不允许修改。就是redis把所有的写操作记录到appendonly.aof的末尾,当redis启动时把里面的操作再执行一遍。它的恢复效率比RDB低,但是安全性更高。
Redis 还可以在后台对 AOF 文件进行重写(rewrite),使得 AOF 文件的体积不会超出保存数据集状态所需的实际大小。
官方建议两种方法一起用,恢复时,优先使用数据完整的aof。
如果不使用持久化,就和memcache一样,纯内存数据库。
2 RDB快照
save和bgsave命令
save命令会生成rdb文件,但是会阻塞服务器进程,使redis不相应任何请求。bgsave会fock一个子进程去完成rdb操作,父进程会继续相应请求。
磁盘保存策略:
# save <seconds> <changes> # # Will save the DB if both the given number of seconds and the given # number of write operations against the DB occurred. # # In the example below the behaviour will be to save: # after 900 sec (15 min) if at least 1 key changed # after 300 sec (5 min) if at least 10 keys changed # after 60 sec if at least 10000 keys changed # # Note: you can disable saving completely by commenting out all "save" lines. # # It is also possible to remove all the previously configured save # points by adding a save directive with a single empty string argument # like in the following example: # # save "" save 900 1 save 300 10 save 60 10000
磁盘保存地址和文件名(地址原为"./" ,在此我改为/redisbak)
# The filename where to dump the DB dbfilename dump.rdb # The working directory. # # The DB will be written inside this directory, with the filename specified # above using the 'dbfilename' configuration directive. # # The Append Only File will also be created inside this directory. # # Note that you must specify a directory here, not a file name. dir /redisbak
触发实验:
当我连续有5次写入操作,就满足了save 900 1的条件,redis就会在/redisbak里生成dump.rdb文件,size为146b。
[root@redis1-20 ~]# ll /redisbak/dump.rdb -rw-r--r--. 1 root root 146 Mar 16 09:50 /redisbak/dump.rdb
当我再次有10次写入操作,就满足了save 300 10的条件,查看dump文件size。
触发的命令为bgsave,属于后台执行,不会阻塞服务器进程。
[root@redis1-20 ~]# ll /redisbak/dump.rdb -rw-r--r--. 1 root root 216 Mar 16 09:59 /redisbak/dump.rdb
这时重启redis,redis会自动加载rdb文件,会发现数据已经被恢复。
另外,当服务被关闭时,也会触发:
85869:M 20 Mar 14:00:54.219 * Saving the final RDB snapshot before exiting. 85869:M 20 Mar 14:00:54.286 * DB saved on disk
3 rdb文件分析
清空db并刷入rdb快照
127.0.0.1:6379> FLUSHALL OK 127.0.0.1:6379> save OK
分析dump文件。od为dump出八进制(octal)格式文件。 -c为format type为char。
redis为识别字符,redis用这个字符来识别这个文件是否为rdb文件。0006为版本号。下面的8个字符为完整性校验。由于为空文件,没有db数据。
[root@centos7 ~]# od -c /redisbak/dump.rdb 0000000 R E D I S 0 0 0 6 377 334 263 C 360 Z 334 0000020 362 V 0000022
4 rdb持久化性能消耗
在一个正常量级的redis应用中,总会频繁的触发持久化操作,这时就是有一个子进程在运行,一般持续1m后进程消失。
它们对系统性能的消耗是很厉害的,消耗和主进程相同大小的内存,和100%的单核cpu。
所以,在设计redis服务器时,必须考虑性能富余。不然,必然导致持久化操作拖累主进程正常运行。