[redis]持久化
redis是在内存中存储数据的,所以当服务重启之后,所有的数据都将丢失。为了保证数据的安全,redis还提供了将数据持久化到磁盘的机制。共有两种持久化类型:RDB和AOF。RDB可以看做是某一个时间点上的快照,适合做数据的备份和灾难恢复;AOF则是写入操作的日志,在服务重启的时候进行重放。
使用RDB
调用config set,在一个正在运行的实例上启用RDB持久化
127.0.0.1:6379> CONFIG SET save "900 1" OK 127.0.0.1:6379> CONFIG SET save "900 1 300 10 60 10000" OK
也可以在配置文件中配置持久化参数:
ubuntu@slave1:~/redis-server/redis-4.0.1/redis-soft/bin$ cat redis.conf | grep save # save <seconds> <changes> # Will save the DB if both the given number of seconds and the given # In the example below the behaviour will be to save: # 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 # save "" save 900 1 save 300 10 save 60 10000 # (at least one save point) and the latest background save failed. stop-writes-on-bgsave-error yes # If you want to save some CPU in the saving child set it to 'no' but # algorithms (in order to save memory), so you can tune it for speed or # the configured save points). # saving process (a background save or AOF log background rewriting) is # Lists are also encoded in a special way to save a lot of space. # order to save a lot of space. This encoding is only used when the length and
可以使用redis-cli 把save参数设为空字符串:
ubuntu@slave1:~/redis-server/redis-4.0.1/redis-soft/bin$ ./redis-cli config set save "" OK
也可以注释掉配置文件中的持久化参数禁用RDB持久化。
# save <seconds> <changes> # Will save the DB if both the given number of seconds and the given # In the example below the behaviour will be to save: # 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 # save "" #save 900 1 #save 300 10 #save 60 10000 # (at least one save point) and the latest background save failed. stop-writes-on-bgsave-error yes # If you want to save some CPU in the saving child set it to 'no' but # algorithms (in order to save memory), so you can tune it for speed or # the configured save points). # saving process (a background save or AOF log background rewriting) is # Lists are also encoded in a special way to save a lot of space. # order to save a lot of space. This encoding is only used when the length and
查看是否开启了RDB持久化
127.0.0.1:6379> CONFIG GET save 1) "save" 2) "900 1 300 10 60 10000"
也可以在数据目录中查看是否有RDB文件
ubuntu@slave1:~/redis-server/redis-4.0.1/redis-soft/bin$ ls -l dump.rdb -rw-rw-r-- 1 ubuntu ubuntu 577 Apr 3 14:43 dump.rdb
如果想要立即持久化当前服务内存中的数据,可以使用save命令
127.0.0.1:6379> save OK
但是这个命令是阻塞的,当有大量数据需要持久化的时候,不适合直接使用save命令。而是非阻塞的 bgsave 。它在后台开启一个线程持久化当前数据,但是不影响服务接收新的指令。
127.0.0.1:6379> BGSAVE Background saving started
查看持久化相关指标和状态:
127.0.0.1:6379> INFO persistence # Persistence loading:0 rdb_changes_since_last_save:0 --自上次保存后的修改次数 rdb_bgsave_in_progress:0 -- 转储是否正在进行 rdb_last_save_time:1554686345 -- 最后一次保存的时间 rdb_last_bgsave_status:OK -- 最后一次保存的结果 rdb_last_bgsave_time_sec:1 -- 最后一次保存运行的时间 rdb_current_bgsave_time_sec:-1 -- 正在进行的bgsave运行时间 rdb_last_cow_size:6598656 -- 写时复制使用的内存
...-- aof 相关参数
更多细节:
stop-writes-on-bgsave-error yes
配置文件中的这个参数表示bgsave失败时redis服务将停止接收写入操作
rdbcompression yes
压缩转储文件的大小,但在LZF过程会消耗更多的CPU
rdbchecksum yes
在转储文件的末尾加上一个CRC64检验和,会在保存和加载快照文件时多消耗10%的cpu。
由save/bgsave生成的转储文件,可以使用Linux的crontab定期将RDB文件拷贝到本地其他目录或者HDFS中,供日后恢复使用。
还原RDB快照文件中的数据:将RDB文件复制到dir配置的位置,并保证当前用户的读写权限,使用shutdown nosave命令停止实例,将转储文件命名为dbfilename指定的名字。重启服务,就可以加载恢复数据了.
使用AOF
在命令行开启AOF,config set appendonly yes
在配置文件中配置AOF,appendonly yes
禁用AOF,config set appendonly no
在配置中禁用,appendonly no
查看AOF相关状态:
127.0.0.1:6379> INFO persistence # Persistence ... -- rdb相关参数
aof_enabled:0 -- 是否开启了aof aof_rewrite_in_progress:0 -- aof是否正在重写 aof_rewrite_scheduled:0 aof_last_rewrite_time_sec:-1 aof_current_rewrite_time_sec:-1 aof_last_bgrewrite_status:ok aof_last_write_status:ok aof_last_cow_size:0
在将命令追加到AOF文件时,我们可以配置redis相关参数 appendfsync 来调整fsync的频率,该参数共有三个选项:
always:对每个命令都同步。当灾难发生时只会丢失一个命令,但是性能明显下降。
everysec:每秒中同步一次,灾难发生时只会丢失一秒钟的数据。建议使用。
no:用永不同步。何时将数据刷新到aof文件由操作系统决定,Linux大概30秒。
当服务器关闭时,sync会被显示调用,以确保数据都从缓存区同步到磁盘aof文件中。
数据恢复时服务加载aof文件,重放写入命令即可。
更多细节:
压缩aof文件:去除掉aof文件中无效的键(过期或者删除了),只保留有效的键值,减少命令重放的时间和aof的文件大小。在命令行执行BGREWRITEAOF
aof文件修复:
ubuntu@slave1:~/redis-server/redis-4.0.1/redis-soft/bin$ ./redis-check-aof --fix appendonly.aof
redis aof 持久化方式怎么解决写时复制产生的新数据?
在redis aof持久化方式中,redis主进程会创建一个子进程来执行aof重写,这个子进程会创建一个新的AOF文件来存储重写的结果,以防止重写失败影响旧的aof文件。父进程则继续响应请求并将新的命令追加到旧的AOF文件中,但是子进程不能访问 最新写入的命令。redis解决的方案是在子进程创建之后,父进程将接受到的命令写入一个 aof_rewrite_buf_blocks缓冲区,当子进程重写完AOF文件后,向父进程发送一个信号,父进程将缓冲区的数据写到新aof文件,最后新的aof文件替换旧的aof文件。
更多细节:
除了手动执行BGREWRITEAOF触发AOF重写之外,还可以配置参数来自动触发:
auto-aof-rewrite-min-size 64mb :aof文件大小超过此值的时候,触发重写。
auto-aof-rewrite-percentage 100:最后一次重写操作的文件大小的增长度超过该值的时候触发重写,默认100。0表示禁用aof自动重写。
AOF和RDB 的结合使用:
在命令行或者配置文件中 设置参数:aof-use-rdb-preamble yes
工作原理:
在重写AOF文件时,redis会首先将数据集以RDB的格式转储到哦内存中并作为AOF文件的开头部分,在重写之后,redis继续使用传统的AOF格式在AOF文件中写入命令。这样在使用AOF混合持久化方式下,AOF文件头部使用的是RDB文件格式,因为RDB可以更好的实现转储和加载,同时也保留了AOF数据一致性的特点。
redis保证了RDB和AOF重写不会同时进行,当同时使用RDB和AOF,redis会首先加载AOF文件,如果发现AOF文件的头部是RDB格式(魔数字符串),则是开启了混合持久化,那么将先加载RDB部分。