面试官:你说你精通Redis,你看过持久化的配置吗?
2021-09-01 09:21
441 查看
前边我们已经介绍了
Redis五种数据类型的命令与配置文件的基本配置,今天让我们从理论和配置两个层面来揭开
Redis持久化的神秘面纱。
所谓持久化可以简单理解为将内存中的数据保存到硬盘上存储的过程。持久化之后的数据在系统重启或者宕机之后依然可以进行访问,保证了数据的安全性。
Redis有两种持久化方案,一种是快照方式(
SNAPSHOTTING),简称
RDB;一种是只追加模式(
APPEND ONLY MODE),称为AOF。接下来让我们分别了解一下它们的使用与注意事项。
RDB
RDB为
Redis DataBase的缩写,是
Redis默认的持久化方案。它能够在指定的时间间隔内将内存数据集快照(
snapshot)写入磁盘,恢复时将快照文件(
dump.rdb)读回内存。
我们先来扒一下配置文件中的
SNAPSHOTTING:
配置文件
save <seconds> <changes>
在给定的秒数内,如果对数据库执行的写入操作数达到设定的值,则将数据同步到数据文件。支持多个条件配合,
Redis默认配置文件中提供了三个条件:
save 900 1 //900s内有1个更改 save 300 10 //300s内有10个更改 save 60 10000 //60s内有10000次更改
注意:若不想用
RDB方案,可以把
save ""的注释打开,上边三个注释掉。
stop-writes-on-bgsave-error yes
当
bgsave出现错误时,
Redis是否停止执行写命令;
- 如果为
yes
,则当硬盘出现问题时,Redis
将停止接受写入操作,这样我们可以及时发现,避免数据的大量丢失; - 如果为
no
,则Redis
无视bgsave
的错误继续执行写命令。
如果已经设置了对
Redis服务器的正确监视和持久性,即采用了其他手段发现和控制数据完整性,可能希望禁用此功能,以便即使在磁盘、权限等方面出现问题时,Redis仍能正常工作。
注意:如果后台保存过程将再次开始工作,
Redis将自动允许再次写入。
rdbcompression yes
指定存储到本地数据库时是否压缩(
Redis采用
LZF压缩)数据,默认为
yes。如果为了节省
CPU时间,可以关闭该选项,但会导致数据库文件变得巨大。
rdbchecksum yes
从
RDB版本
5开始,在存储快照后,还可以使用
CRC64算法来进行数据校验,
CRC64校验放在文件的末尾。开启之后,保存和加载
RDB文件时会增加大约
10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能。
禁用校验和创建的
RDB文件的校验和为零,这将告诉加载代码跳过检查。
dbfilename dump.rdb
指定本地数据库文件名,重启之后自动加载进内存,手动执行
save命令的话即刻生效。
大坑请注意:
flushall、shutdown命令都会清空并提交至dump.rdb
dir ./
指定本地数据库存放目录。
理论
工作方式
- 当
Redis
需要保存dump.rdb
文件时,它会调用系统函数fork()
,创建一个子进程(与主进程完全一致); - 子进程将数据集写入临时文件
RDB
中; - 当子进程完成对新
RDB
文件的写入时,Redis
用新RDB
文件替换原来的RDB
文件,并删除旧的RDB
文件。
这种工作方式使得
Redis可以从写时复制(
copy-on-write)机制中获益。
如何触发RDB快照
- 配置文件中默认的快照配置;
- 命令
save
(阻塞, 只管保存快照,其他的等待)或者是bgsave
(异步)命令,快照同时还可以响应客户端命令; - 执行
flushall
命令,清空数据库所有数据,意义不大; - 执行
shutdown
命令,保证服务器正常关闭且不丢失任何数据,意义也不大。
通过RDB文件恢复数据
在实际开发中,一般会考虑到物理机硬盘损坏的情况,所以我们会选择备份
dump.rdb文件。将备份的
dump.rdb文件拷贝到
redis的安装目录的
bin目录下,重启
redis服务即可。
优点
RDB
是一个非常紧凑的文件,非常适用于数据集的备份;RDB
是一个紧凑的单一文件,很方便传送到另一个远端数据中心或者亚马逊的S3(可能加密),非常适用于灾难恢复;Redis
的主进程不进行I/O
操作,确保了极高的性能;- 适合大规模数据的恢复,对于数据的完整性和一致性要求不高的话,
RDB
比AOF
方式更加高效。
缺点
- 在
Redis
意外宕机时,你可能会丢失几分钟的数据; RDB
需要经常fork
子进程来保存数据集到硬盘上,当数据集比较大的时候,fork
的过程是非常耗时的,可能会导致Redis
在一些毫秒级内不能响应客户端的请求。如果数据集巨大并且CPU
性能不是很好的情况下,这种情况会持续1秒;AOF
也需要fork
,但是可以调节重写日志文件的频率来提高数据集的耐久度。
AOF
为了解决
RDB方式在宕机时丢失数据过多的问题,从
1.1版本开始,
Redis增加了一种
durable的持久化方式:
AOF。
AOF是
Append Only File的缩写,默认不开启。
AOF以日志的形式来记录每个写操作,只允许追加文件但不可以改写文件,当服务器重启的时候会重新执行这些命令来恢复原始的数据。
我们再来看一下配置文件中的
APPEND ONLY MODE:
配置文件
appendonly no
默认为关闭状态,改为
yes打开持久化。
AOF和
RDB可以同时启用而不会出现问题。
appendfilename "appendonly.aof"
文件默认名称,启动即创建。加载先于
dump.rdb文件
appendfsync
同步策略:系统函数
fsync()告诉操作系统在磁盘上实际写入数据。
Redis支持三种不同的模式
appendfsync always //每次发生数据变更会被立即记录到磁盘,性能较差但数据完整性比较好 appendfsync everysec //默认推荐,异步操作,每秒记录,如果宕机,有1秒内数据丢失 appendfsync no //不同步,只有在操作系统需要时在刷新数据
要想了解接下来的配置内容,先得说一下“日志重写”的原理:
重写
由于
AOF采用的是将命令追加到文件末尾的方式,所以随着写入命令的不断增加,
AOF文件的体积会变得越来越大。为避免出现此种情况,新增了重写机制:可以在不打断服务客户端的情况下,对
AOF文件进行重建(
rebuild)。
重写触发: 通过执行
bgrewriteaof命令,可以生成一个新的
AOF文件,该文件包含重建当前数据集所需的最少命令。
Redis 2.2需手动执行该命令,
Redis 2.4则可以通过修改配置文件的方式自动触发(配置在下边涉及)。
重写原理:
Redis
执行系统函数fork()
,创建一个子进程(与主进程完全一致);- 子进程开始将新
AOF
文件的内容写入到临时文件; - 对于所有新执行的写入命令,父进程一边将它们累积到一个内存缓存中,一边将这些改动追加到现有
AOF
文件的末尾,这样即使在重写的中途发生停机,现有的AOF
文件也是安全的; - 当子进程完成重写工作时,它给父进程发送一个信号,父进程在接收到信号之后,将内存缓存中的所有数据追加到新
AOF
文件的末尾。 Redis
原子地用新文件替换旧文件,之后所有命令都会直接追加到新AOF
文件的末尾。
no-appendfsync-on-rewrite no
当我们同时执行主进程的写操作和子进程的重写操作时,两者都会操作磁盘,而重写往往会涉及到大量的磁盘操作,这样就会造成主进程在写
aof文件的时候出现阻塞的情形。
为了解决这个问题,
no-appendfsync-on-rewrite参数出场了。
- 如果该参数设置为
no
,是最安全的方式,不会丢失数据,但是要忍受阻塞的问题; - 如果设置为
yes
,这就相当于将appendfsync
设置为no
,这说明并没有执行磁盘操作,只是写入了缓冲区。因此这样并不会造成阻塞(因为没有竞争磁盘),但是如果这个时候redis
挂掉,就会丢失数据。丢失多少数据呢?在linux
的操作系统的默认设置下,最多会丢失30s的数据。
因此,如果应用系统无法忍受延迟,而可以容忍少量的数据丢失,则设置为
yes;如果应用系统无法忍受数据丢失,则设置为
no。
auto-aof-rewrite-percentage 100
重写百分比,默认为上次重写后
aof文件大小的一倍。
auto-aof-rewrite-min-size 64mb
重写触发的最小值:64mb。
根据
auto-aof-rewrite-min-size和
auto-aof-rewrite-percentage参数确定自动触发时机。
Redis会记录上次重写时的
AOF大小,默认配置是当
AOF文件大小是上次
rewrite后大小的一倍且文件大于
64M时触发。
大型互联网公司一般都是
3G起步
aof-load-truncated yes
当
AOF文件被截断时,即
AOF文件的最后命令不完整,如果此时启动
Redis,会将
AOF数据加载回内存,此时便会出现问题。
- yes:加载一个截断的
AOF
,Redis
服务器开始发出日志,通知用户该事件; - no:服务器将中止并出现错误,拒绝启动。
当我们得知
AOF文件报错时,可以用以下方法来修复出错的
AOF文件:
为现有的
AOF
文件创建一个备份;使用
Redis
附带的redis-check-aof
命令,对原来的AOF
文件进行修复;redis-check-aof –fix
redis-check-aof --fix appendonly.aof
修复命令,杀光不符合规范的语法
(可选)使用
diff -u对比修复后的
AOF文件和原始
AOF文件的备份,查看两个文件之间的不同之处;
重启
Redis服务器,等待服务器载入修复后的
AOF文件,并进行数据恢复。
aof-use-rdb-preamble yes
在重写
AOF文件时,
Redis能够在
AOF文件中使用
RDB前导,以加快重写和恢复速度。启用此选项后,重写的
AOF文件由两个不同的节组成:
RDB file、
AOF tail
加载
Redis时,会识别
AOF文件以Redis字符串开头,并加载带前缀的
RDB文件,然后继续加载
AOF尾部。
理论
优点
- 数据的完整性和一致性更高,
AOF
的持久化通过使用不同的策略,最多丢失1秒的数据; AOF
文件是一个只进行追加的日志文件,不需要写入seek
;Redis
可以在AOF
文件体积变得过大时,自动地在后台对AOF
进行重写,重写操作是绝对安全的;AOF
文件记录的写入操作以Redis
协议的格式保存,容易读懂,容易对文件进行分析;
缺点
- 对于相同的数据集来说,
AOF
文件的体积通常要大于RDB
文件的体积; - 根据所使用的
fsync
策略,AOF
的速度可能会慢于RDB
。
在一般情况下,每秒
fsync的性能依然非常高,而关闭fsync可以让AOF的速度和RDB一样快, 即使在高负荷之下也是如此。 不过在处理巨大的写入载入时,RDB可以提供更有保证的最大延迟时间(latency)。
对比与总结
如何选择使用哪种持久化方式?
一般来说,如果想达到足以媲美
PostgreSQL的数据安全性,应该同时使用两种持久化功能。
如果非常关心数据,但仍然可以承受数分钟以内的数据丢失,那么可以只使用
RDB持久化。
由于AOF持久化的实时性更好,即当进程意外退出时丢失的数据更少,因此
AOF是目前主流的持久化方式。
有很多用户都只使用
AOF持久化,但我们并不推荐这种方式:因为定时生成
RDB快照(
snapshot)非常便于进行数据库备份,并且
RDB恢复数据集的速度也要比
AOF恢复的速度要快。
AOF和RDB之间的相互作用
在版本号大于等于
2.4的
Redis中,
BGSAVE执行的过程中,不可以执行
BGREWRITEAOF。反过来说,在
BGREWRITEAOF执行的过程中,也不可以执行
BGSAVE。这可以防止两个
Redis后台进程同时对磁盘进行大量的
I/O操作。
如果
BGSAVE正在执行,并且用户显示地调用
BGREWRITEAOF命令,那么服务器将向用户回复一个
OK状态, 并告知用户
BGREWRITEAOF已经被预定执行:一旦
BGSAVE执行完毕,
BGREWRITEAOF就会正式开始。
当
Redis启动时,如果
RDB持久化和
AOF持久化都被打开了, 那么程序会优先使用
AOF文件来恢复数据集,因为
AOF文件所保存的数据通常是最完整的。
备份redis数据
- 创建一个定期任务(
cron job
),每小时将一个RDB
文件备份到一个文件夹,并且每天将一个RDB
文件备份到另一个文件夹; - 确保快照的备份都带有相应的日期和时间信息,每次执行定期任务脚本时,使用
find
命令来删除过期的快照; - 至少每天一次,将
RDB
备份到你的数据中心之外,或者至少是备份到你运行Redis
服务器的物理机器之外。
性能建议
在实际应用时,因为
RDB文件只用作后备用途,建议只在
slave上持久化
RDB文件,而且只需要15分钟备份一次就够了,只保留
save 900 1这条规则。
如果开启
AOF,好处是在最恶劣情况下也只会丢失不超过2秒数据,启动脚本较简单只
load自己的
AOF文件就可以了。代价一是带来了持续的
IO,二是
AOF rewrite的最后将
rewrite过程中产生的新数据写到新文件造成的阻塞几乎是不可避免的。
只要硬盘许可,应该尽量减少
AOF rewrite的频率,
AOF重写的基础大小默认值
64M太小了,可以设置到
5G以上。默认超过原大小的100%时重写可以改到适当的数值。
如果不开启
AOF,仅靠
Master-Slave Replication实现高可用性也可以。能省掉一大笔
IO,也减少了
rewrite时带来的系统波动。代价是如果
Master/Slave同时倒掉,会丢失十几分钟的数据,启动脚本也要比较两个
Master/Slave中的
RDB文件,载入较新的那个。
以上就是今天的全部内容了,如果你有不同的意见或者更好的
idea,欢迎联系阿Q,添加阿Q可以加入技术交流群参与讨论呦!
相关文章推荐
- Redis系列~Redis持久化配置(二十)
- redis07-----Redis持久化配置
- Redis学习之持久化方式和配置
- redis 持久化和主从配置
- Redis学习之持久化方式和配置
- Redis持久化及其配置
- Redis只作为缓存,不做持久化的配置
- redis 配置文件 append only file(aof)部分---数据持久化
- Redis安装、配置、操作、持久化、主从、phpredis扩展安装使用详解之安装配置
- 非关系型数据库--redis的持久化策略(RDB,AOF)介绍及配置
- Redis安装、配置、操作、持久化、主从、phpredis扩展安装使用详解之操作使用
- redis源码分析(一)复习redis命令、持久化方案、主从同步原理、配置
- Redis安装+Redis持久化配置+jedis基本命令+demo(ubuntu下)
- redis 持久化、主从配置保证数据安全性能
- redis持久化配置
- 3、redis.conf中的持久化相关配置
- Redis持久化原理及配置详解(RDB方式和AOF方式)
- Redis(三) Redis的常用配置、持久化机制、事务、消息的发布订阅、主从复制机制
- redis持久化AOF与RDB配置
- redis 非持久化配置