探索Redis设计与实现11:使用快照和AOF将Redis数据持久化到硬盘中

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: 使用快照和AOF将Redis数据持久化到硬盘中 转自https://blog.csdn.net/xlgen157387/article/details/61925524 前言 我们知道Redis是一款内存服务器,就算我们对自己的服务器足够的信任,不会出现任何软件或者硬件的故障,但也会有可能出现突然断电等情况,造成Redis服务器中的数据失效。

使用快照和AOF将Redis数据持久化到硬盘中

转自https://blog.csdn.net/xlgen157387/article/details/61925524


前言

我们知道Redis是一款内存服务器,就算我们对自己的服务器足够的信任,不会出现任何软件或者硬件的故障,但也会有可能出现突然断电等情况,造成Redis服务器中的数据失效。因此,我们需要向传统的关系型数据库一样对数据进行备份,将Redis在内存中的数据持久化到硬盘等非易失性介质中,来保证数据的可靠性。

将Redis内存服务器中的数据持久化到硬盘等介质中的一个好处就是,使得我们的服务器在重启之后还可以重用以前的数据,或者是为了防止系统出现故障而将数据备份到一个远程的位置。

还有一些场景,例如:

对于一些需要进行大量计算而得到的数据,放置在Redis服务器,我们就有必要对其进行数据的持久化,如果需要对数据进行恢复的时候,我们就不需进行重新的计算,只需要简单的将这台机器上的数据复制到另一台需要恢复的Redis服务器就可以了。
  • 1

Redis给我们提供了两种不同方式的持久化方法:快照(Snapshotting) 和 只追加文件(append-only-file)

(1)名词简介

快照(RDB):就是我们俗称的备份,他可以在定期内对数据进行备份,将Redis服务器中的数据持久化到硬盘中;

只追加文件(AOF):他会在执行写命令的时候,将执行的写命令复制到硬盘里面,后期恢复的时候,只需要重新执行一下这个写命令就可以了。类似于我们的MySQL数据库在进行主从复制的时候,使用的是binlog二进制文件,同样的是执行一遍写命令;

(2)快照持久化通用的配置:

save 60 1000  #60秒时间内有1000次写入操作的时候执行快照的创建
stop-writes-on-bgsave-error no  #创建快照失败的时候是否仍然继续执行写命令
rdbcompression yes  #是否对快照文件进行压缩
dbfilename dump.rdb   #如何命名硬盘上的快照文件
dir ./  #快照所保存的位置
  • 1
  • 2
  • 3
  • 4
  • 5

(3)AOP持久化配置:

appendonly no  #是否使用AOF持久化
appendfsync everysec  #多久执行一次将写入内容同步到硬盘上
no-appendfsync-on-rewrite no #对AOF进行压缩的时候能否执行同步操作
auto-aof-rewrite-percentage 100  #多久执行一次AOF压缩
auto-aof-rewrite-min-size 64mb  #多久执行一次AOF压缩
dir ./ #AOF所保存的位置
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

需要注意的是:这两种持久化的方式既可以单独的使用,也可以同时使用,具体选择哪种方式需要根据具体的情况进行选择。

快照持久化

快照就是我们所说的备份。用户可以将Redis内存中的数据在某一个时间点进行备份,在创建快照之后,用户可以对快照进行备份。通常情况下,为了防止单台服务器出现故障造成所有数据的丢失,我们还可以将快照复制到其他服务器,创建具有相同数据的数据副本,这样的话,数据恢复的时候或者服务器重启的时候就可以使用这些快照信息进行数据的恢复,也可以防止单台服务器出现故障的时候造成数据的丢失。

但是,没我们还需要注意的是,创建快照的方式,并不能完全保证我们的数据不丢失,这个大家可以很好的理解,因为快照的创建时定时的,并不是每一次更新操作都会创建一个快照的。系统发生崩溃的时候,用户将丢失最近一次生成快照之后更改的所有数据。因此,快照持久化的方式只适合于数据不经常修改或者丢失部分数据影响不大的场景。

一、创建快照的方式:

(1)客户端通过向Redis发送BGSAVE 命令来创建快照。

使用BGSAVE的时候,Redis会调用fork来创建一个子进程,然后子进程负责将快照写到硬盘中,而父进程则继续处理命令请求。

使用场景:

如果用户使用了save设置,例如:save 60 1000 ,那么从Redis最近一次创建快照之后开始计算,当“60秒之内有1000次写入操作”这个条件满足的时候,Redis就会自动触发BGSAVE命令。

如果用户使用了多个save设置,那么当任意一个save配置满足条件的时候,Redis都会触发一次BGSAVE命令。

(2)客户端通过向Redis发送SAVE 命令来创建快照。

接收到SAVE命令的Redis服务器在快照创建完毕之前将不再响应任何其他命令的请求。SAVE命令并不常用,我们通常只在没有足够的内存去执行BGSAVE命令的时候才会使用SAVE命令,或者即使等待持久化操作执行完毕也无所谓的情况下,才会使用这个命令;

使用场景:

当Redis通过SHUTDOWN命令接收到关闭服务器的请求时,或者接收到标准的TERM信号时,会执行一次SAVE命令,阻塞所有的客户端,不再执行客户端发送的任何命令,并且在执行完SAVE命令之后关闭服务器。

二、使用快照持久化注意事项:

我们在使用快照的方式来保存数据的时候,如果Redis服务器中的数据量比较小的话,例如只有几个GB的时候。Redis会创建子进程并将数据保存到硬盘里边,生成快照所需的时间比读取数据所需要的时间还要短。

但是,随着数据的增大,Redis占用的内存越来越大的时候,BGSAVE在创建子进程的时候消耗的时间也会越来越多,如果Redis服务器所剩下的内存不多的时候,这行BGSAVE命令会使得系统长时间地停顿,还有可能导致服务器无法使用。

各虚拟机类别,创建子线程所耗时间:

这里写图片描述

因此,为了防止Redis因为创建子进程的时候出现停顿,我们可以考虑关闭自动保存,转而通过手动的方式发送BGSAVE或者SAVE来进行持久化,

手动的方式发送BGSAVE也会出现停顿的现象,但是我们可以控制发送该命令的时间来控制出现停顿的时候不影响具体的业务请求。

另外,值得注意的是,在使用SAVE命令的时候,虽然会一直阻塞Redis直到快照生成完毕,但是其不需要创建子进程,所以不会向BGSAVE一样,因为创建子进程而导致Redis停顿。也正因为如此,SAVE创建快照的速度要比BGSAVE创建快照的速度更快一些。

创建快照的时候,我们可以在业务请求,比较少的时候,比如凌晨三、四点,通过手写脚本的方式,定时执行。

AOF持久化

AOF持久化会将被执行的写命令写到AOF文件的末尾,以此来记录数据发生的变化。这样,我们在恢复数据的时候,只需要从头到尾的执行一下AOF文件即可恢复数据。

一、打开AOF持久化选项

我们可以通过使用如下命令打开AOF:

appendonly yes
  • 1

我们,通过如下命令来配置AOF文件的同步频率:

appendfsync everysec/always/no
  • 1

二、appendfsync同步频率的区别

appendfsync同步频率的区别如下图:

这里写图片描述

(1)always的方式固然可以对没一条数据进行很好的保存,但是这种同步策略需要对硬盘进行大量的写操作,所以Redis处理命令的速度会受到硬盘性能的限制。

普通的硬盘每秒钟只能处理大约200个写命令,使用固态硬盘SSD每秒可以处理几万个写命令,但是每次只写一个命令,这种只能怪不断地写入很少量的数据的做法有可能引发严重的写入放大问题,这种情况下降严重影响固态硬盘的使用寿命。

(2)everysec的方式,Redis以每秒一次的频率大队AOF文件进行同步。这样的话既可以兼顾数据安全也可以兼顾写入性能。

Redis以每秒同步一次AOF文件的性能和不使用任何持久化特性时的性能相差无几,使用每秒更新一次 的方式,可以保证,即使出现故障,丢失的数据也在一秒之内产生的数据。

(3)no的方式,Redis将不对AOF文件执行任何显示的同步操作,而是由操作系统来决定应该何时对AOF文件进行同步。

这个命令一般不会对Redis的性能造成多大的影响,但是当系统出现故障的时候使用这种选项的Redis服务器丢失不定数量的数据。

另外,当用户的硬盘处理写入操作的速度不够快的话,那么缓冲区被等待写入硬盘的数据填满时,Redis的写入操作将被阻塞,并导致Redis处理命令请求的速度变慢,因为这个原因,一般不推荐使用这个选项。

三、重写/压缩AOF文件

随着数据量的增大,AOF的文件可能会很大,这样在每次进行数据恢复的时候就会进行很长的时间,为了解决日益增大的AOF文件,用户可以向Redis发送BGREWRITEAOF 命令,这个命令会通过移除AOF文件中的冗余命令来重写AOF文件,是AOF文件的体检变得尽可能的小。

BGREWRITEAOF的工作原理和BGSAVE的原理很像:Redis会创建一个子进程,然后由子进程负责对AOF文件的重写操作。

因为AOF文件重写的时候汇创建子进程,所以快照持久化因为创建子进程而导致的性能和内存占用问题同样会出现在AOF文件重写的 时候。

四、触发重写/压缩AOF文件条件设定

AOF通过设置auto-aof-rewrite-percentage 和 auto-aof-rewrite-min-size 选项来自动执行BGREWRITEAOF。

其具体含义,通过实例可以看出,如下配置:

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

表示当前AOF的文件体积大于64MB,并且AOF文件的体积比上一次重写之后的体积变大了至少一倍(100%)的时候,Redis将执行重写BGREWRITEAOF命令。

如果AOF重写执行的过于频繁的话,可以将auto-aof-rewrite-percentage 选项的值设置为100以上,这种最偶发就可以让Redis在AOF文件的体积变得更大之后才执行重写操作,不过,这也使得在进行数据恢复的时候执行的时间变得更加长一些。

验证快照文件和AOF文件

无论使用哪种方式进行持久化,我们在进行恢复数据的时候,Redis提供了两个命令行程序:

redis-check-aof
redis-check-dump
  • 1
  • 2

他们可以再系统发生故障的时候,检查快照和AOF文件的状态,并对有需要的情况对文件进行修复。

如果用户在运行redis-check-aof命令的时候,指定了--fix 参数,那么程序将对AOF文件进行修复。

程序修复AOF文件的方法很简单:他会扫描给定的AOF文件,寻找不正确或者不完整的命令,当发现第一个出现错误命令的时候,程序会删除出错命令以及出错命令之后的所有命令,只保留那些位于出错命令之前的正确命令。大部分情况,被删除的都是AOF文件末尾的不完整的写命令。

总结

上述,一起学习了两种支持持久化的方式,一方面我们需要通过快照或者AOF的方式对数据进行持久化,另一方面,我们还需要将持久化所得到的文件进行备份,备份到不同的服务器上,这样才可以尽可能的减少数据丢失的损失。


微信公众号【黄小斜】大厂程序员,互联网行业新知,终身学习践行者。关注后回复「Java」、「Python」、「C++」、「大数据」、「机器学习」、「算法」、「AI」、「Android」、「前端」、「iOS」、「考研」、「BAT」、「校招」、「笔试」、「面试」、「面经」、「计算机基础」、「LeetCode」 等关键字可以获取对应的免费学习资料。 


                     wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
9天前
|
缓存 NoSQL 关系型数据库
13- Redis和Mysql如何保证数据⼀致?
该内容讨论了保证Redis和MySQL数据一致性的几种策略。首先提到的两种方法存在不一致风险:先更新MySQL再更新Redis,或先删Redis再更新MySQL。第三种方案是通过MQ异步同步以达到最终一致性,适用于一致性要求较高的场景。项目中根据不同业务需求选择不同方案,如对一致性要求不高的情况不做处理,时效性数据设置过期时间,高一致性需求则使用MQ确保同步,最严格的情况可能涉及分布式事务(如Seata的TCC模式)。
35 6
|
9天前
|
NoSQL Redis
05- Redis的数据淘汰策略有哪些 ?
Redis 提供了 8 种数据淘汰策略:挥发性 LRU、LFU 和 TTL(针对有过期时间的数据),挥发性随机淘汰,以及全库的 LRU、LFU 随机淘汰,用于在内存不足时选择删除。另外,还有不淘汰策略(no-eviction),允许新写入操作报错而非删除数据。
10 1
|
16天前
|
NoSQL Redis
Redis事务:保证数据操作的一致性和可靠性
Redis事务:保证数据操作的一致性和可靠性
|
1月前
|
NoSQL Java 数据库连接
使用Java实现从数据库查出数据存入Redis,并在查询时先查Redis,如果Redis中没有数据再从数据库中读取
使用Java实现从数据库查出数据存入Redis,并在查询时先查Redis,如果Redis中没有数据再从数据库中读取
344 1
|
16天前
|
NoSQL 安全 网络安全
保护Redis:建立铁壁般的安全防线,守护你的数据财富
保护Redis:建立铁壁般的安全防线,守护你的数据财富
|
16天前
|
消息中间件 存储 NoSQL
Redis Stream: 实时消息处理的利器,让你的数据流畅又可靠!
Redis Stream: 实时消息处理的利器,让你的数据流畅又可靠!
|
16天前
|
NoSQL 安全 网络安全
Redis连接:加速数据访问与保障安全传输的关键
Redis连接:加速数据访问与保障安全传输的关键
|
16天前
|
存储 消息中间件 缓存
Redis 字符串:用一串数据解决多种问题
Redis 字符串:用一串数据解决多种问题
|
21天前
|
缓存 NoSQL Shell
【Redis深度专题】「核心技术提升」探究Redis服务启动的过程机制的技术原理和流程分析的指南(持久化功能分析)
【Redis深度专题】「核心技术提升」探究Redis服务启动的过程机制的技术原理和流程分析的指南(持久化功能分析)
25 0
|
1月前
|
存储 JSON NoSQL
Redis与Python的完美结合:实现高效数据交互和应用场景全解析
Redis与Python的完美结合:实现高效数据交互和应用场景全解析
113 0

热门文章

最新文章