Redis是在内存中储存数据,服务器重启时,内存中的数据将丢失,为了保证数据安全,Redis提供将数据持久化到磁盘中。Redis提供两种数据持久化方式:RDB(Redis Database)和AOF(Append Only File)。
RDB是Redis默认的持久化方案。但触发Redis保存规则,Redis会将内存的数据保存到硬盘中,会在指定目录下生成一个xxx.rdb文件,服务重启会加载该文件来恢复数据。
配置
# 指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合 # save <seconds> <changes> # Redis默认配置文件中提供了三个条件:分别表示900秒(15分钟)内有1个更改,300秒(5分钟)内有10个更改以及60秒内有10000个更改。 # 如果不行使用RDB,设置 save "" ,关闭或去掉其他save设置。 save 900 1 save 300 10 save 60 10000 # 指定存储至本地数据库时是否压缩数据,默认为yes,Redis采用LZF压缩,如果为了节省CPU时间,可以关闭该选项,但会导致数据库文件变的巨大 rdbcompression yes # 指定本地数据库文件名,默认值为dump.rdb dbfilename dump.rdb # 指定本地数据库存放目录 dir /usr/local/redis/var/操作
[root@one /]# systemctl start redis-server.service # 启动redis服务 [root@one /]# redis-cli # 启动客户端 127.0.0.1:6379> MSET name Lewis age 27 # 批量设置 OK 127.0.0.1:6379> SHUTDOWN # 关闭客户端,SHUTDOWN会触发save操作,Redis会将内存数据保存本地,生成一个dump.rdb文件 not connected> QUIT # 退出 [root@one /]# cd /usr/local/redis/var/ # 文件目录 [root@one var]# ls dump.rdb redis.log [root@one var]# cp dump.rdb dump.rdb.bak # 备份数据dump.rdb [root@one var]# redis-cli 127.0.0.1:6379> keys * 1) "name" 2) "age" 127.0.0.1:6379> FLUSHALL # 清空所有数据库,FLUSHALL会触发save操作,Redis会将内存数据保存本地,生成一个dump.rdb文件 OK 127.0.0.1:6379> keys * # 内存已无数据 (empty list or set) 127.0.0.1:6379> QUIT [root@one var]# systemctl stop redis-server.service # 关闭服务端 [root@one var]# cp dump.rdb.bak dump.rdb # 恢复dump.rdb cp: overwrite ‘dump.rdb’? y [root@one var]# systemctl start redis-server.service # 重启Redis服务 [root@one var]# redis-cli # 打开客户端 127.0.0.1:6379> keys * # 查看恢复数据 1) "name" 2) "age" 127.0.0.1:6379>RDB修复
# 当服务器意外情况下可能数据保存不完整,可以通过自带修复工具进行修复 [root@one var]# redis-check-rdb dump.rdb以日志的方式记录每次写入命令,重启服务执行AOF文件中命令达到恢复数据的目的。
配置
# 开启AOF,默认no appendonly yes # AOF文件名 appendfilename "appendonly.aof" # 指定更新日志条件,共有3个可选值:no:不要同步,只让操作系统在需要的时候刷新数据(快);always:每次更新操作后手动调用fsync()将数据写到磁盘(慢,安全)everysec:表示每秒同步一次(折中,默认值) # appendfsync always appendfsync everysec # appendfsync no # AOF重写规则。文件大小比例增加100%,且大小增加至少64mb则执行文件重写策略;Redis会fork出一条新进程,读取内存中的数据,并重新写到一个临时文件中,最后替代元AOF文件;如果参数设置0,表示不进行AOF重写 auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb操作
[root@one ~]# systemctl restart redis-server.service [root@one ~]# redis-cli 127.0.0.1:6379> set name "小新" OK 127.0.0.1:6379> set age 5 OK 127.0.0.1:6379> QUIT [root@one ~]# cd /usr/local/redis/var/ [root@one var]# ll total 8 -rw-r--r-- 1 redis redis 87 Jul 18 18:37 appendonly.aof -rw-r--r-- 1 redis redis 1860 Jul 18 18:36 redis.log [root@one var]# cp appendonly.aof appendonly.aof.bak [root@one var]# redis-cli 127.0.0.1:6379> FLUSHALL OK 127.0.0.1:6379> keys * (empty list or set) 127.0.0.1:6379> QUIT [root@one var]# systemctl stop redis-server.service [root@one var]# cp appendonly.aof.bak appendonly.aof cp: overwrite ‘appendonly.aof’? y [root@one var]# systemctl start redis-server.service [root@one var]# redis-cli 127.0.0.1:6379> keys * 1) "age" 2) "name" 127.0.0.1:6379>AOF文件说明
[root@one var]# cat appendonly.aof *2 $6 SELECT $1 0 *3 $3 set $4 name $6 小新 *3 $3 set $3 age $1 5 *2 :该指令包含2个语句 $6 :该语句包含6个字节(一个汉字3个字节) 默认选择database 0原理
AOF功能启动之后,Redis会在数据目录创建AOF文件。AOF文件默认文件名是appendonly.aof,也可通过配置文件中appendfilename参数进行修改。同时,Redis还会将当前内存数据复制到AOF文件。、
每当Redis服务器收到一个会实际修改内存数据的写入命令时,Redis会将该命令追加AOF文件中。但事实上是操作系统维护一个缓冲区,Redis命令首先会被写入到这个缓冲区中。而缓冲区的数据必须被刷新到磁盘中才能被永久保存。这个过程需要Linux调用fsync()完成,这是一个阻塞调用,只有磁盘设备报告缓冲区中的数据写入完成才会返回。
在将命令追加AOF文件时,我们可以通过Redis的配置参数appendfsync来调整fsync()的频率。该参数提供三个选项:
always:对每个写入命令都调用fsync()。这个选项可以确保在发生意外(服务器奔溃或硬件故障等),只会丢失一条命令。但是,由于fsync()是一个阻塞调用,Redis性能会受到物理磁盘写入的限制。将appendfsync设置为always是不明智的,应为服务器性能会显著下降。everysec:每秒调用一次fsync(),在发生意外故障时,会丢失一秒的数据。建议采用此选项,已达到数据安全和性能一个这种。no:永远不调用fsync(),采用该选项时,将由操作系统决定何时将数据从缓冲区写入到磁盘。在大多数Linux系统中,这个频率是没30秒。当Redis服务器关闭时,fsync()会被显式调用,以确保写入缓冲区中的所有数据都会被刷新到磁盘中。
AOF修复
# 当服务器意外情况下可能数据保存不完整,可以通过自带修复工具进行修复 [root@one var]# redis-check-aof --fix appendonly.aofAOF重写
执行bgwriteaof命令,如果当前进程正在执行AOF重写,那么直接返回;如果有进程正在执行bgsave,那么等待bgsave执行完毕再执行AOF重写Redis主进程会fork一个子进程执行AOF重写AOF重写过程中,主进程收到写操作还会将命令写到aof_buf以及同步aof_buf中数据到AOF文件中;此外,主进程收到命令还会写入aof_rewrite_buf中由于AOF重写过程中原AOF还在陆续写入数据,所以AOF重写只会拿到fork子进程时AOF文件进行重写,并生成一个临时的AOF文件子进程完成AOF重写会向主进程发送消息,主进程会将aof_rewrite_buf数据写入新AOF文件,并将新AOF文件替换旧AOF文件
参考
《Redis 4.x Cookbook中文版》
《深入Redis的RDB和AOF两种持久化方式以及AOF重写机制的分析》