Redis持久化
快照(默认)
将内存中的数据以快照的方式写入到二进制文件中,默认文件名是dump.rdb。
配置自动化做快照持久化(如redis在n秒内如果超过m个key被修改就自动做快照)
save 900 1 # 900秒内如果超过1个key被修改,则发起快照保存
save 300 10 # 300秒内如果超过10个key被修改,则发起快照保存
save 60 10000 # 60秒内如果超过10000个key被修改,则发起快照保存
快照保存过程
1、redis调用fork,产生父进程和子进程
2、父进程继续处理client的请求,子进程负责将内存的内容写入到临时文件。由于os写时复制机制(copy on write),父子进程共享相同的页面,当父进程处理请求时,os会为父进程要修改的页面创建副本,而不是写共享的页面。所以子进程地址空间内的数据是fork时刻的整个数据库的一个快照。
3、当子进程将快照写入临时文件完毕之后,用临时文件替换原来的快照文件,然后子进程退出。
client端可以使用save或者bgsave通知redis做一次快照持久化。
save由于是在主线程中保存快照,由于redis使用一个主线程来处理所有client请求,这种方式会阻塞client请求。
快照持久化的问题:
由于每次快照都是讲数据完整的写入磁盘一次,即将整个Redis中的所有数据都遍历一边到一个扩展名为RDB的数据文件中,并不是增量的只同步变更的数据。如果数据量大,而且写操作较多,必然会引起大量的磁盘IO操作,从而影响性能。
配置
save 900 1
save 300 10
save 60 10000
# The filename where to dump the DB
dbfilename dump_6379.rdb
# Note that you must specify a directory here, not a file name.
dir /opt/redis/
AOF(Append-Only File)
追加式的日志操作记录
防止redis意外宕机,丢失最后一次快照后的所有修改,如果应用要求不应该丢失任何修改的话,可以采用AOF持久化。
使用AOF持久化时,Redis将每个收到的写命令都通过write函数追加到文件中(默认是appendonly.aof)。当Redis重启的时候会通过重新执行文件中保存的写命令,以此来实现重建数据库中的内容。
由于OS会有缓存的机制,所以可以配置Redis通过强制调用fsync函数强制OS写入到磁盘的时机。方式如下:
启用AOF,appendonly yes
#appendfsync always // 保证最能完全的持久化
appendfsync everysec // 每秒钟写入磁盘一次,在性能和持久化中的这种方式
#appendfsync no // 完全依赖OS,性能最好,持久化保证
AOF持久化的问题:
持久化文件会变的越来越大,例如调用同一条命令做修改100次,那么前99次都是多余的,再恢复数据库时只需要最后一条。为了压缩AOF的持久化文件,Redis提供bgrewriteaof命令,使用与快照的方式类似的方法将内存中的数据以命令的形式保存到临时文件,最后在替换原来的文件。
1、Redis调用fork,生成父子进程
2、子进程根据内存中的数据库快照,往临时文件中写入重建数据库状态的额命令
3、父进程继续处理client请求,除了将写命令写入原来的AOF文件中(保证子进程重写失败),同时缓存收到的写命令。
4、当子进程完成快照内容写入临时文件后,子进程发信号告知父进程将缓存的写命令写入到临时文件。
5、父进程使用临时文件替换旧的AOF文件,并重命名。
注意事项:
重写AOF文件时,没有读取旧的AOF文件,而是将整个内存中的数据库内容用命令的方式重写一个新的AOF文件。(类似快照)