Redis提供了两种不同的持久化方法来讲数据存储到硬盘里边:
-
RDB(基于快照),将某一时刻的所有数据保存到一个RDB文件中。
-
AOF(append-only-file),当Redis服务器执行写命令的时候,将执行的写命令保存到AOF文件中。
RDB
命令
-
SAVE
会阻塞Redis服务器进程,服务器不能接收任何请求,直到RDB文件创建完毕为止。 -
BGSAVE
创建出一个子进程,由子进程来负责创建RDB文件,服务器进程可以继续接收请求。
Redis服务器在启动的时候,如果发现有RDB文件,就会自动载入RDB文件(不需要人工干预)
-
服务器在载入RDB文件期间,会处于阻塞状态,直到载入工作完成。
除了手动调用SAVE
或者BGSAVE
命令生成RDB文件之外,我们可以使用配置的方式来定期执行
如何配置快照持久化
redis中的快照持久化默认是开启的,redis.conf中相关配置主要有如下几项:
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
dbfilename dump.rdb
dir ./
前面三个save相关的选项表示备份的频率,分别表示900秒内至少一个键被更改则进行快照,300秒内至少10个键被更改则进行快照,60秒内至少10000个键被更改则进行快照,
stop-writes-on-bgsave-error表示在快照创建出错后,是否继续执行写命令,rdbcompression则表示是否对快照文件进行压缩,dbfilename表示生成的快照文件的名字,dir则表示生成的快照文件的位置,在redis中,快照持久化默认就是开启的。我们可以通过如下步骤验证快照持久化的效果:
1.进入redis安装目录,如果有dump.rdb文件,先将之删除。如下:
![p299]()
2.启动redis,随便向redis中存储几个数据,然后关闭redis并退出,如下:
[root@localhost redis-4.0.8]# redis-server redis.conf
[root@localhost redis-4.0.8]# redis-cli
127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> set k2 v2
OK
127.0.0.1:6379> SHUTDOWN
not connected> exit
3.退出来后,我们发现刚刚删掉的dump.rdb文件又回来了,这就是生成的备份文件。
4.此时再次启动redis并进入,发现刚刚存储的数据都还在,这是因为redis在启动时加载了dump.rdb中的数据。好了,关闭redis并退出。
5.将redis目录下的dump.rdb文件删除。
6.再次启动redis并进入到控制台,所有的数据都不存在了。
快照持久化操作流程
通过上面的介绍,小伙伴们对快照持久化都有一个大致的认识了,那么这个东西到底是怎么运行的?持久化的时机是什么?我们来仔细扒一扒。
1.在redis运行过程中,我们可以向redis发送一条save命令来创建一个快照,save是一个阻塞命令,redis在接收到save命令之后,开始执行备份操作之后,在备份操作执行完毕之前,将不再处理其他请求,其他请求将被挂起,因此这个命令我们用的不多。save命令执行如下:
127.0.0.1:6379> SAVE
OK
2.在redis运行过程中,我们也可以发送一条bgsave命令来创建一个快照,不同于save命令,bgsave命令会fork一个子进程,然后这个子进程负责执行将快照写入硬盘,而父进程则继续处理客户端发来的请求,这样就不会导致客户端命令阻塞了。如下:
127.0.0.1:6379> BGSAVE
Background saving started
3.如果我们在redis.conf中配置了如下选项:
save 900 1
save 300 10
save 60 10000
那么当条件满足时,比如900秒内有一个key被操作了,那么redis就会自动触发bgsava命令进行备份。我们可以根据实际需求在redis.conf中配置多个这种触发规则。
4.还有一种情况也会触发save命令,那就是我们执行shutdown命令时,当我们用shutdown命令关闭redis时,此时也会执行一个save命令进行备份操作,并在备份操作完成后将服务器关闭。
5.还有一种特殊情况也会触发bgsave命令,就是在主从备份的时候。当从机连接上主机后,会发送一条sync命令来开始一次复制操作,此时主机会开始一次bgsave操作,并在bgsave操作结束后向从机发送快照数据实现数据同步。
快照持久化的缺点
快照持久化有一些缺点,比如save命令会发生阻塞,bgsave虽然不会发生阻塞,但是fork一个子进程又要耗费资源,在一些极端情况下,fork子进程的时间甚至超过数据备份的时间。定期的持久化也会让我们存在数据丢失的风险,最坏的情况我们可能丢失掉最近一次备份到当下的数据,具体丢失多久的数据,要看我们项目的承受能力,我们可以根据项目的承受能力配饰save参数
AOF
AOF是通过保存Redis服务器所执行的写命令来记录数据库的数据的,针对每个key的写命令生成一个AOF文件
总结
RDB和AOF并不互斥,它俩可以同时使用。
-
RDB的优点:载入时恢复数据快、文件体积小。
-
RDB的缺点:会一定程度上丢失数据(因为系统一旦在定时持久化之前出现宕机现象,此前没有来得及写入磁盘的数据都将丢失。)
-
AOF的优点:丢失数据少(默认配置只丢失一秒的数据)。
-
AOF的缺点:恢复数据相对较慢,文件体积大
如果Redis服务器同时开启了RDB和AOF持久化,服务器会优先使用AOF文件来还原数据(因为AOF更新频率比RDB更新频率要高,还原的数据更完善)
AOF持久化是将被执行的命令写到aof文件末尾,在恢复时只需要从头到尾执行一遍写命令即可恢复数据,AOF在redis中默认也是没有开启的,需要我们手动开启,开启方式如下:
打开redis.conf配置文件,修改appendonly属性值为yes,如下:
appendonly yes
另外几个和AOF相关的属性如下:
appendfilename "appendonly.aof"
# appendfsync always
appendfsync everysec
# appendfsync no
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
这几个属性的含义分别如下:
1.appendfilename表示生成的AOF备份文件的文件名。
2.appendfsync表示备份的时机,always表示每执行一个命令就备份一次,everysec表示每秒备份一次,no表示将备份时机交给操作系统。
3.no-appendfsync-on-rewrite表示在对aof文件进行压缩时,是否执行同步操作。
4.最后两行配置表示AOF文件的压缩时机,这个我们一会再细说。
同时为了避免快照备份的影响,我们将快照备份关闭,关闭方式如下:
save ""
# save 900 1
# save 300 10
# save 60 10000
此时,当我们在redis中进行数据操作时,就会自动生成AOF的配置文件appendonly.aof,此时没有dump.rdb文件,这时我们将redis关闭并重启,会发现之前的数据都还在,这就是AOF备份的结果。
AOF备份的几个关键点
1.通过上面的介绍,小伙伴们了解到appendfsync的取值一共有三种,我们在项目中首选everysec,always选项会严重降低redis性能。
2.使用everysec,最坏的情况下我们可能丢失1秒的数据。
AOF文件的重写与压缩
AOF备份有很多明显的优势,当然也有劣势,那就是文件大小。随着系统的运行,AOF的文件会越来越大,甚至把整个电脑的硬盘填满,AOF文件的重写与压缩机制可以在一定程度上缓解这个问题。
当AOF的备份文件过大时,我们可以向redis发送一条bgrewriteaof命令进行文件重写,如下:
127.0.0.1:6379> BGREWRITEAOF
Background append only file rewriting started
(0.71s)
bgrewriteaof的执行原理和我们上文说的bgsave的原理一致,这里我就不再赘述,因此bgsave执行过程中存在的问题在这里也一样存在。
bgrewriteaof也可以自动执行,自动执行时间则依赖于auto-aof-rewrite-percentage和auto-aof-rewrite-min-size配置,auto-aof-rewrite-percentage 100表示当目前aof文件大小超过上一次重写时的aof文件大小的百分之多少时会再次进行重写,如果之前没有重写,则以启动时的aof文件大小为依据,同时还要求AOF文件的大小至少要大于64M(auto-aof-rewrite-min-size 64mb)。
最佳实践
1.如果redis只做缓存服务器,那么可以不使用任何持久化方式。
2.同时开启两种持久化方式,在这种情况下,当redis重启的时候会优先载入AOF文件来恢复原始的数据, 因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整;RDB的数据不完整时,同时使用两者时服务器重启也只会找AOF文件。那要不要只使用AOF呢? 作者建议不要,因为RDB更适合用于备份数据库(AOF在不断变化不好备份), 快速重启,而且不会有AOF可能潜在的bug,留着作为一个万一的手段。
3.因为RDB文件只用作后备用途,建议只在slave上持久化RDB文件,而且只要15分钟备份一次就够了,只保留save 900 1这条规则。
4.如果Enalbe AOF,好处是在最恶劣情况下也只会丢失不超过两秒数据,启动脚本较简单只load自己的AOF文件就可以了。代价一是带来了持续的IO,二是AOF rewrite的最后将rewrite过程中产生的新数据写到新文件造成的阻塞几乎是不可避免的。只要硬盘许可,应该尽量减少AOF rewrite的频率,AOF重写的基础大小默认值64M太小了,可以设到5G以上。默认超过原大小100%大小时重写可以改到适当的数值。
5.如果不Enable AOF ,仅靠Master-Slave Replication 实现高可用性也可以。能省掉一大笔IO也减少了rewrite时带来的系统波动。代价是如果Master/Slave同时倒掉,会丢失十几分钟的数据,启动脚本也要比较两个Master/Slave中的RDB文件,载入较新的那个。
转自 https://mp.weixin.qq.com/s?__biz=MzI1NDY0MTkzNQ==&mid=2247484570&idx=1&sn=37ffb660b4d1d250bfd89ece438b3f98&scene=21#wechat_redirect