Redis从入门到精通(14):redis的数据持久化详解

Redis数据都是存储在内存中,一旦发生宕机或者断电的情况内存中的数据就会消失,所以数据的本地持久化存储就额外重要。这一节我们来看看Redis的两种持久化方式,RDB和AOF。

我是T型人小付,一位坚持终身学习的互联网从业者。喜欢我的博客欢迎在csdn上关注我,如果有问题欢迎在底下的评论区交流,谢谢。

RDB方式

save命令

客户端执行一次save命令就会进行一次本地化,保存的目录为配置文件中dir配置项,保存的文件名为配置文件中dbfilename配置项,默认是dump.rdb

配置文件内容如下:

[root@testmachine redis]# cat redis.conf | grep ^dir
dir /usr/local/redis/
[root@testmachine redis]# cat redis.conf | grep ^dbfilename
dbfilename dump.rdb

执行操作:

127.0.0.1:6380> save
OK

生成本地持久化文件:

[root@testmachine redis]# pwd
/usr/local/redis
[root@testmachine redis]# ll dump.rdb
-rw-r--r-- 1 root root 107 Feb 23 16:37 dump.rdb
相关配置

和持久化相关的配置有下面四个:

  • dbfilename dump.rdb
    用来设定持久化文件的名字,通常配置为dump-端口号.rdb,例如dump-6380.rdb

  • dir /
    用来设定持久化文件的保存目录,经过实际测试,这里要放绝对路径

  • rdbcompression yes
    采用压缩的方式进行持久化,保持yes即可

  • rdbchecksum yes
    读和写过程中检查文件完整性,保持yes即可

数据的恢复

数据只要被持久化了下来,即使是意外断电,redis服务程序突然中断也不会影响到原始数据。只要在再次启动的时候,使用相同的配置文件,redis会自动将持久化的数据读取到内存中。

save命令的缺点

因为redis是单线程的,假如save命令耗时过长,会导致服务端长时间阻塞,所以线上不建议使用save命令的方式做持久化

bgsave命令

为了解决save的阻塞问题,引入了bgsave的方式,将持久化的过程在后台进行,不会造成阻塞:

127.0.0.1:6380> bgsave
Background saving started
127.0.0.1:6380>

但是这样也造成了缺点,就是无法在客户端看到保存成功的返回,只能通过查看log来进行验证。

那么如果bgsave中途出错了怎么办,有一个配置项可以进行设置:

  • stop-writes-on-bgsave-error yes
    如果中途出错就停止写入文件,保持默认的yes即可

服务端自动持久化

除了人为手动去做持久化,还可以让服务端自动操作。根据配置中的save second changes项来设定条件,满足条件就触发bgsave过程,通常都会设定多个条件配合使用

save 900 1
save 300 10
save 60 10000

上述设定就是在900秒内有一次key更改,或者300秒内有10次key更改,或者60秒内有10000次key更改,都会触发bgsave。可以看到操作越密集,持久化也就越频繁。每次持久化完成以后都会将计时重置。

RDB方式的优缺点

优点:

  • RDB是一个紧凑压缩的二进制文件,存储效率较高
  • RDB存储的是某时间点的数据快照,非常适合做数据备份
  • RDB恢复数据比AOF要快很多

缺点:

  • RDB无法做到实时持久化,所以几乎一定会有数据丢失
  • bgsave每次都要fork出子进程去完成后台备份,牺牲掉了一些性能
  • Redis的各个版本之间的RDB格式存在不兼容的现象

AOF方式

为了解决RDB的缺点,引入了AOF的持久化方式,将备份数据改为备份对数据的操作

  • 每次对数据内容有修改的操作都被记录下来,确保了实时性
  • 不需要子进程,节约了性能
  • 没有兼容性问题

AOF的三种策略

  • always
    每一条命令都会进行一次AOF操作,数据完整性最高。但是在操作较频繁,例如每秒几十万次的场景,会涉及到大量IO操作,会大大降低性能
  • everysec
    每秒进行一次AOF操作,如果出现宕机,会丢失一秒钟的数据,准确性也比较高
  • no
    由操作系统来控制写入AOF的的时间,不可控

不推荐使用always,除非对数据完整性要求非常高。一般场景用everysec策略即可。

AOF配置项

一共有三个配置项

  • appendonly no
    开启AOF功能,默认是no,改为yes开启
  • appendfilename “appendonly.aof”
    配置AOF文件的名字,也是建议配置为appendonly-端口号.aof的格式。文件的保存目录和RDB中是同一个配置项
  • appendfsync everysec
    上面提到的三种AOF策略
[root@testmachine redis]# cat redis.conf | grep ^append
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec

修改配置重启redis之后在RDB的目录中出现了一个大小为0的文件

[root@testmachine redis]# pwd
/usr/local/redis
[root@testmachine redis]# ll appendonly.aof
-rw-r--r-- 1 root root 0 Feb 23 18:44 appendonly.aof

注意,在配置文件中开启AOF,因为Redis重启后恢复数据优先以AOF来恢复,会导致原先的数据虽然写入了RDB文件,但是重启Redis服务后并没有读到内存中,查询会显示没有任何key。只有当删除了AOF文件并且关闭了AOF功能后才会恢复到RDB中读取。

验证AOF

打开AOF,重启Redis,然后进行操作

127.0.0.1:6380> set a 1
OK
127.0.0.1:6380> set b 2
OK
127.0.0.1:6380>

发现AOF文件大小增加了

[root@testmachine redis]# pwd
/usr/local/redis
[root@testmachine redis]# ll appendonly.aof
-rw-r--r-- 1 root root 77 Feb 23 18:44 appendonly.aof

如果持续修改key,每一秒钟这个文件都会变化一次,文件会越来越大。

AOF重写

这里有一个问题,例如我对一个key先赋值再删除,或者是对一个key更新多遍,AOF还是会原封不动的把命令从头到尾记录一遍,但是其实只有最后一条命令是有意义的。为了消除这些冗余,使得AOF存储和恢复更高效,就需要用到AOF重写。

AOF重写的几条规则:

  • 已经过期的数据不再记录
  • 按照数据最终的状态进行记录
  • 对同一数据的重复操作合并

和RDB一样,既可以手动执行命令完成重写,也可以通过修改配置项让服务端自动完成重写

手动重写

首先删除原先的AOF文件,重启redis服务,达到清除AOF记录的目的

[root@testmachine redis]# rm appendonly.aof
rm: remove regular file ‘appendonly.aof’? y
[root@testmachine redis]# systemctl restart redis

然后我们对同一个key多次操作,故意造成冗余记录

127.0.0.1:6380> set a 1
OK
127.0.0.1:6380> set a 2
OK
127.0.0.1:6380> set a 3
OK
127.0.0.1:6380>

查看下AOF文件

[root@testmachine redis]# ll appendonly.aof
-rw-r--r-- 1 root root 104 Feb 23 20:28 appendonly.aof
[root@testmachine redis]# cat appendonly.aof
*2
$6
SELECT
$1
0
*3
$3
set
$1
a
$1
1
*3
$3
set
$1
a
$1
2
*3
$3
set
$1
a
$1
3

然后手动对AOF进行重写,和bgsave一样也是在后台进行的

127.0.0.1:6380> bgrewriteaof
Background append only file rewriting started
127.0.0.1:6380>

过一会再去查看AOF文件

[root@testmachine redis]# ll appendonly.aof
-rw-r--r-- 1 root root 102 Feb 23 20:52 appendonly.aof

发现AOF文件大小确实减小了。

但是再cat的时候,发现AOF里面是乱码,我怀疑是我环境的问题。而且会发现不仅AOF文件变了,RDB文件也变了。

自动重写

配置文件中有两个配置项用来设置自动重写的触发门限:

  • auto-aof-rewrite-percentage 100
  • auto-aof-rewrite-min-size 64mb

其中第一个是百分比,触发条件为
(aof_current_size - aof_base_size) / aof_base_size = auto-aof-rewrite-percentage

第二个是绝对值,触发条件为
aof_current_size = auto-aof-rewrite-min-size

其中的两个变量可以在客户端通过info Persistence查看

127.0.0.1:6380> info Persistence
# Persistence
loading:0
rdb_changes_since_last_save:0
rdb_bgsave_in_progress:0
rdb_last_save_time:1582462921
rdb_last_bgsave_status:ok
rdb_last_bgsave_time_sec:1
rdb_current_bgsave_time_sec:-1
rdb_last_cow_size:167936
aof_enabled:1
aof_rewrite_in_progress:0
aof_rewrite_scheduled:0
aof_last_rewrite_time_sec:0
aof_current_rewrite_time_sec:-1
aof_last_bgrewrite_status:ok
aof_last_write_status:ok
aof_last_cow_size:139264
aof_current_size:233
aof_base_size:102
aof_pending_rewrite:0
aof_buffer_length:0
aof_rewrite_buffer_length:0
aof_pending_bio_fsync:0
aof_delayed_fsync:0
127.0.0.1:6380>

百分比和绝对值可以只配置一个,如果将百分比设置为0就是关闭自动重写功能。

RDB和AOF方案对比

持久化方式RDBAOF
占用存储空间
存储速度
恢复速度
数据安全性会丢失数据根据策略决定
资源消耗
启动优先级
  • 对数据完整性要求比较高的,采用AOF持久化方案
  • 数据呈现阶段性有效,且对恢复时间要求较高的,采用AOF持久化方案
  • AOF和RDB可以同时打开互不影响,重启后Redis优先采用AOF来恢复数据
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值