[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
View Code

可以使用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
View Code

查看是否开启了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部分。 

原文地址:https://www.cnblogs.com/ytuan996/p/10668844.html