【Redis原理探索】深入对持久化原理的认识(进阶篇)

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
日志服务 SLS,月写入数据量 50GB 1个月
简介: 【Redis原理探索】深入对持久化原理的认识(进阶篇)

前提回顾


Redis本身在内存中进行数据存储和操作;如果仅仅是在内存中进行数据存储,那就会导致以下问题:


  1. 数据随进程退出而消失:当服务器断电或Redis Server进程退出时,内存肯定随之释放,最后数据也会丢失;可能有些小伙伴认为只是作为缓存,数据没有了,重新从数据库中读取放在里面即可,试想,如果是高并发场景,数据库岂不是压力很大;


  1. 重要数据无法恢复:数据丢失之后无法进行恢复,对于一些重要的数据,只是存在Redis中,而没有存在关系型数据库,如果数据丢失便不可恢复;比如刷礼品排行榜,如果数据丢失,用户肯定不愿意的;




持久化方式


Redis针对数据持久化有两种方案,如下:


  • RDB(Redis DataBase):快照形式,即指定时间间隔将Redis内存中的快照数据保存在物理磁盘上,数据保存在*.rdb文件中,以二进制的形式进行存储,恢复数据直接加载即可;


  • AOF(Append Only File):日志形式,即将每条写命令以append-only模式记录在*.aof文件中,不能修改文件,只能进行追加;后续恢复数据自动执行日志文件中的命令即可恢复数据;


  • 混合就是RDB和AOF的结合:两种方式都可以通过配置文件轻松搞定。




RDB持久化


理论放到后面再说,先来看看实际操作,再来做总结;上次对配置文件简单进行说明,这次就直接找到快照那配置就行啦,先看看默认配置


image.png


通过 save seconds changes进行条件配置,如果触发条件就自动进行RDB持久化操作。默认配置中包含以下三种条件,满足其中一个就自动保存数据到磁盘:


save 900 1:900秒内(15分钟)至少有1个key的值进行修改;
save 300 10:300秒内(五分钟)至少有10个key的值进行修改;
save 60 10000:900秒内(1分钟)至少有10000个key的值进行修改;
复制代码



RDB其他配置项


如果rdb备份文件写入失败了怎么办?这些通过配置文件中SNAPSHOTTING部分都有详细的说明,并提供相关配置项进行设置。


  • stop-writes-on-bgsave-error
  • 认设置为yes,即当RDB备份数据失败时,Redis会停止接收数据,保证数据的一致性;如果对数据一致性要求不高的,可以将其进行关闭,设置为no,但推荐都开启;


  • rdbcompression:默认设置为yes,开启压缩之后会采用LZF算法对备份文件dump.rdb进行压缩,但会消耗点CPU性能进行处理,但影响并不大,推荐都开启;


  • rdbchecksum:默认设置为yes,即开启之后会对备份文件数据进行校验,但会消耗CPU性能,如果追求性能提高可以将其关闭,但影响也不大,推荐都开启;


  • dbfilename:默认为dump.rdb,即默认的备份文件名为dump.rdb,可以通过这个配置进行修改;


  • dir:默认为当前目录,即备份的文件存放的目录。



RDB手动触发备份


上面说到自动触发备份,其实在实际应用场景中,有些需求很急,如果要求等到满足条件备份完成之后才处理问题,间隔时间短还好点,如果间隔时间超过5分钟,估计等待处理问题的人要上房揭瓦啦。


Redis同样为大家考虑到了,提供手动备份的方式,如下:


  • save:直接执行save命令,但会阻塞主进程操作,只能等待备份完成之后才能进行其他处理;


  • bgsave:直接执行bgsave命令,主进程会fork一个子进程进行备份操作,不阻塞主进程;当数据过大时,可能会在fork的时候有短暂的耗时,但影响不大; 上面的自动备份其实最后也是bgsave这种模式。


  • flushall:执行flushall命令会触发RDB备份,但是备份文件是空的



停止自动备份


可以通过配置文件的形式配置,也可以通过命令的形式进行关闭,但通过命令的方式,服务器重启之后就失效了,所以一般建议通过配置文件进行配置;


  • 配置文件方式:去除所有关于save的配置,或者配置一个save seconds changes 即可,重启redis-server;


  • 命令方式:在客户端中执行 config set save seconds changes 即可,但redis-server重启时就恢复默认值了;


image.png

  1. 当触发bgsave持久化时(满足配置条件或手动执行bgsave命令),主进程fork一个子进程进行持久化操作,fork的作用是复制一个与当前进程一样的子进程,该子进程的所有数据都和原进程一致,主进程不参与任何持久化IO操作;


  1. 为了不影响原有rdb文件的使用,子进程会将快照数据先写入到临时文件; 当快照数据完全备份到临时文件时,就替换掉原有的rdb文件,从而得到最新数据的rdb文件;


注:当执行save命令的时候,会导致阻塞,只有等快照数据持久化完成之后,才能做其他事情;



RDB持久化优缺点


每一项技术在解决已有问题的时候,肯定也会带来新问题,RDB用来解决持久化问题,那它有什么优缺点呢?


优点


  • RDB保存的数据文件比较紧凑,对比AOF来说,相同数据的文件大小比较小;大量数据持久化时速度相对AOF比较快


  • RDB中bgsave模式对主进程影响比较小,只有在主进程fork子进程的时候耗费资源,但影响不大;自动备份后台用的就是bgsave模式


缺点


  • RDB可能会丢失最后一次没有备份的数据,如果在最后一次没开始备份之前,服务器挂了,那最后一次的数据就没了


  • 当数据量巨大时,主进程在fork子进程的时候,可能会导致稍微的卡顿





AOF持久化


RDB的缺点来看,很大程度上是因为可能会丢失最后一次备份之前的数据,对于一些重要数据来说,是不能接受的。 而AOF的出现,将数据丢失风险极大的降低。先不说那么多,实操一把再慢慢聊。


AOF默认情况是没开启的,打开配置文件,为了不让RDB备份影响,这里暂时先将RDB备份禁用掉,如下:


禁用RDB备份:


image.png


注释进行先关的配置即可。




开启AOF备份


根据上一篇文章提到的,先找到APPEND ONLY MODE配置块,将AOF备份开启appendonly yes


image.png


当一启动redis-server的时候,appendonly.aof文件就已经生成了。



appendonly.aof文件


尝试打开appendonly.aof文件看看,和dump.rdp文件有什么不同;


image.png


  • appendonly.aof只记录写命令,读命令不记录,而且记录方式是以追加的方式,所- 以速度相对比较快;


  • 同RDB一样,在redis-server重启时,自动加载AOF文件命令依次执行,最终将数据进行恢复;




AOF其他配置项


针对每一个功能都可以通过配置项进行完成,使用非常方便;


  • appendonly:默认no,不开启AOF持久化;可以通过设置为yes开启


  • appendfilename:默认appendonly.aof,代表生成的AOF日志文件名,可以更改


  • appendfsync:默认everysec,设置同步命令到磁盘的策略,即默认每秒通过fsync进行一次命令同步到磁盘;有三种命令同步策略可以选择,如下:always:只要有写入命令就通过fsync同步到磁盘,数据完整性好,但效率不好;everysec:每秒通过fsync进行一次命令同步到磁盘,可能会导致一秒中数据的丢失,因为可能在命令还没同步的时候,机器挂掉等操作,但可接受;综合考虑,推荐使用这种策略;no:不同步,由操作系统处理,这种数据不能保证安全


  • auto-aof-rewrite-percentage:默认100,搭配auto-aof-rewrite-min-size一起触发AOF文件重写策略,即默认当当前AOF文件大小是上次重写的两倍时才重写,为了避免比率达到触发条件,但文件很小就触发重写的情况,所以搭配auto-aof-rewrite-min-size设置AOF文件的最小重写大小;即当前AOF文件大小达到比率的同时文件大小不低于auto-aof-rewrite-min-size设置的值才触发重写


  • auto-aof-rewrite-min-size:默认64mb,搭配auto-aof-rewrite-percentage使用。





AOF触发重写


当执行的写命令过多时,就会导致AOF文件过度增大,而对于一些重复性的命令存在AOF文件中是没有必要的,如下图所示:


image.png


上图中多次对a1这个Key进行多次写入,最终的值为10,可见如果AOF文件中只记录一条最终值的写命令岂不是最好,从而减少AOF文件的大小;这里文件大小肯定达不到自动触发重写的条件,这里就手动触发,然后再看看AOF文件内容,是否进行了优化,如下:


重写之后的AOF文件的确是我们自己想要,是不是觉得Redis更加牛X了;触发重写有以下两种方式:


  • 自动触发:即当满足设置的auto-aof-rewrite-percentage和auto-aof-rewrite-min-size值会自动触发重写


  • 手动触发:在客户端中执行bgrewriteaof命令


AOF重写流程


看完这篇文章,你对Redis持久化的迷惑就全解开了,超全面 简要说明:



image.png


  1. 当触发到重写AOF文件时,主进程fork一个子进程,子进程根据内存中的现有数据进行命令精简化,重写到新的AOF文件中;


2.在子进程正在重写AOF文件时,如果有新的写命令,将其存放到重写缓冲区


3.(AOF_REWRITE_BUFFER_BLOCK),同时也同步到原来的AOF文件;


4.当子进程重写完成之后,通知主进程将重写缓冲区中的新命令写入到新AOF文件中,完成之后,用新的AOF文件将原来的AOF文件替换;


5.最后得到优化之后的AOF文件,减少文件大小;




AOF文件修复


对于AOF文件内容的合法性怎么解决呢,有可能由于突然事件,比如宕机,导致AOF文件写入不完整;也有可能有人恶意添加不规范数据,redis会怎么处理呢?这里就模拟手动修改AOF文件,如下:


image.png



根据提示,使用redis-check-aof --fix filename 进行修复,如下:

image.png




还有redis也能对rdb文件修复,文中没有体现,但小伙伴记得去尝试一下,用redis-check-rdb这个工具即可,在windows版本中redis没有提供此工具,去linux用高点的版本实操一把。


AOF持久化优缺点


AOF的出现,是解决了RDB丢失最后一次没保存的数据,极大的降低了数据丢失的风险,但其也带来相关问题;


优点


  • 降低数据丢失风险,如果丢失,最多一秒数据;


  • 以追加方式记录日志,速度快;


  • 自动优化AOF文件,文件过大时进行重写,精简AOF文件;


缺点


  • 相同大数据,AOF文件比RDB文件大,占用磁盘空间;


  • 对于大数据的恢复,速度没有RDB快;




混合持久化


Redis4.0之后,提供了混合持久化配置开启功能; 混合持久化就是结合RDB和AOF各自优点进行整合的持久化方案,从而解决使用AOF恢复数据较慢的问题;



原理就是在AOF文件的前半段加入RDB快照数据,后面才是增量数据的命令记录;在配置文件中进行配置即可:aof-use-rdb-preamble yes,高版本redis都默认开启这种混合持久化模式;


  • 优点:解决了单纯AOF恢复数据较慢的问题;


  • 缺点:不能兼容低版本redis场景;


选择哪个持久化比较合适?


  • 如果需求对数据完整性要求不是很高,可以接受短时间数据丢失,RDB快照持久化方式是最好不过的选择;


  • 如果对数据完整性要求比较严格,使用AOF日志形式进行持久化比较合适;


如果redis版本在4.0以上,可以使用混合持久化的方式,降低纯AOF文件的恢复数据的时间;


如果仅仅是缓存,缓存数据也不重要,并发也不是很高,可以不用开启持久化;


注: 如果不是使用混合持久化,而是将RDB和AOF同时开启,redis-server恢复数据的时候会优先使用AOF文件进行数据恢复,因为AOF文件相对比较完整;





相关实践学习
基于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
相关文章
|
5天前
|
监控 NoSQL 测试技术
【赵渝强老师】Redis的AOF数据持久化
Redis 是内存数据库,提供数据持久化功能,支持 RDB 和 AOF 两种方式。AOF 以日志形式记录每个写操作,支持定期重写以压缩文件。默认情况下,AOF 功能关闭,需在 `redis.conf` 中启用。通过 `info` 命令可监控 AOF 状态。AOF 重写功能可有效控制文件大小,避免性能下降。
|
5天前
|
存储 监控 NoSQL
【赵渝强老师】Redis的RDB数据持久化
Redis 是内存数据库,提供数据持久化功能以防止服务器进程退出导致数据丢失。Redis 支持 RDB 和 AOF 两种持久化方式,其中 RDB 是默认的持久化方式。RDB 通过在指定时间间隔内将内存中的数据快照写入磁盘,确保数据的安全性和恢复能力。RDB 持久化机制包括创建子进程、将数据写入临时文件并替换旧文件等步骤。优点包括适合大规模数据恢复和低数据完整性要求的场景,但也有数据完整性和一致性较低及备份时占用内存的缺点。
|
1月前
|
存储 缓存 NoSQL
大数据-45 Redis 持久化概念 RDB AOF机制 持久化原因和对比
大数据-45 Redis 持久化概念 RDB AOF机制 持久化原因和对比
35 2
大数据-45 Redis 持久化概念 RDB AOF机制 持久化原因和对比
|
21天前
|
存储 NoSQL 定位技术
Redis geo原理
Redis的GEO功能基于Earth Mapper(http://earth-api.org/)库,它允许存储地理位置信息并执行一些基于该信息的操作。
25 3
|
1月前
|
设计模式 NoSQL 网络协议
大数据-48 Redis 通信协议原理RESP 事件处理机制原理 文件事件 时间事件 Reactor多路复用
大数据-48 Redis 通信协议原理RESP 事件处理机制原理 文件事件 时间事件 Reactor多路复用
36 2
|
1月前
|
消息中间件 分布式计算 NoSQL
大数据-41 Redis 类型集合(2) bitmap位操作 geohash空间计算 stream持久化消息队列 Z阶曲线 Base32编码
大数据-41 Redis 类型集合(2) bitmap位操作 geohash空间计算 stream持久化消息队列 Z阶曲线 Base32编码
25 2
|
1月前
|
存储 缓存 NoSQL
大数据-46 Redis 持久化 RDB AOF 配置参数 混合模式 具体原理 触发方式 优点与缺点
大数据-46 Redis 持久化 RDB AOF 配置参数 混合模式 具体原理 触发方式 优点与缺点
56 1
|
1月前
|
NoSQL 关系型数据库 MySQL
Redis 事务特性、原理、具体命令操作全方位诠释 —— 零基础可学习
本文全面阐述了Redis事务的特性、原理、具体命令操作,指出Redis事务具有原子性但不保证一致性、持久性和隔离性,并解释了Redis事务的适用场景和WATCH命令的乐观锁机制。
185 0
Redis 事务特性、原理、具体命令操作全方位诠释 —— 零基础可学习
|
1月前
|
消息中间件 NoSQL Kafka
大数据-116 - Flink DataStream Sink 原理、概念、常见Sink类型 配置与使用 附带案例1:消费Kafka写到Redis
大数据-116 - Flink DataStream Sink 原理、概念、常见Sink类型 配置与使用 附带案例1:消费Kafka写到Redis
126 0