小伙用 12 张图讲明白了 Redis 持久化!(上)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 Tair(兼容Redis),内存型 2GB
简介: 小伙用 12 张图讲明白了 Redis 持久化!

00 前言


很多小伙伴都用 Redis 做缓存,那如果 Redis 服务器宕机,内存中数据全部丢失,应该如何做数据恢复呢?有人说很简单呀,直接从 MySQL 数据库再读回来就得了


这种方式存在两个问题:一是频繁访问 MySQL 数据库,有一定的风险;二是,从界面上来看,从 MySQL 读就不如从 Redis 快。


远哥远哥,那咋办呀?教教我吧。


我用中指抵着小胖的下吧,说到:傻瓜,我们可以做持久化呀。Redis 的持久化分两种,一种是 AOF,另一种是 RDB。来,坐哥哥腿上,我给你好好说道说道。


老规矩,先上张脑图:


640.png


0.1 什么是持久化?


持久化(Persistence),即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘)。持久化的主要应用是将内存中的对象存储在数据库中,或者存储在磁盘文件中、XML 数据文件中等等。持久化是将程序数据在持久状态和瞬时状态间转换的机制。


01 怎么理解 Redis 的单线程?


必须声明一点:Redis 的单线程,是指 Redis 的网络 IO 和键值对读写是由一个线程(主线程)完成的,这也是 Redis 对外提供键值存储服务的主要流程。但 Redis 的其他功能,比如持久化、异步删除、集群数据同步等,其实是由额外的线程执行的。


1.0 Redis 快的原因?


基于内存


  • 数据都存储在内存里,减少了一些不必要的 I/O 操作,操作速率很快。


高效的数据结构


  • 底层多种数据结构支持不同的数据类型,支持 Redis 存储不同的数据;
  • 不同数据结构的设计,使得数据存储时间复杂度降到最低。


合理的线程模型


  • I/O 多路复用模型同时监听多个客户端连接;
  • 单线程在执行过程中不需要进行上下文切换,减少了耗时。


02 AOF 持久化


AOF(Append Only File) 持久化是通过保存 Redis 服务器所执行的写命令来记录数据库状态,也就是每当 Redis 执行一个改变数据集的命令时(比如 SET), 这个命令就会被追加到 AOF 文件的末尾。


修改 redis.conf 配置文件,默认是 appendonly no(关闭状态),将 no 改为 yes 即可开启 AOF 持久化:


appendonly yes


在客户端输入如下命令也可,但是 Redis 服务器重启后会失效。


192.168.17.101:6379> config set appendonly yes
OK


AOF 持久化功能的实现可以分为命令追加(append)、文件写回磁盘两个步骤。


2.0 命令追加


AOF 持久化功能开启时,Redis 在执行完一个写命令之后,会将被执行的写命令追加到服务器状态的 aof_buf 缓冲区的末尾,此时缓冲区的记录还没有写入到 appendonly.aof 文件中


2.0.1 AOF 的格式


AOF 保存的是 Redis 的写命令,比如:执行命令 set testkey testvalue,它存储的内容如下图所示:


640.png


其中,“*3” 表示当前命令有三个部分,每部分都是由 $+ 数字开头,后面紧跟着具体的命令、键或值。这里,数字表示这部分中的命令、键或值一共有多少字节。例如, $3 set 表示这部分有 3 个字节,也就是 set 命令。


2.0.2 写后日志有啥优缺点?


AOF 记录日志的方式被称为写后日志,也就是先执行命令再记录,而 MySQL 中的 redo log、binlog 等都是写前日志。它的写入流程是下图这样的:


640.png


写后有什么优点?


  • 记录 AOF 时不会对命令进行语法检查 ,写后就只记录了执行成功的命令。(避免保存的错误的命令,恢复的时候就完犊子了)
  • 执行完之后再记录,不会阻塞当前的写操作


写后有什么缺陷?


  • 如果执行完一个命令还没来得及写日志就宕机了会造成响应数据丢失。
  • AOF 的写入由主线程处理,如果写入时出现较长耗时,那就会影响主线程处理后续的请求。


你发现没有?写后的两个缺陷都是 AOF 的写入磁盘时相发生的,我们来看看它是怎么写入的呢?


2.1 AOF 写入磁盘


AOF 提供了三个选择,也就是 AOF 配置项 appendfsync 的三个可选值。


  • Always,同步写回:每个写命令执行完,立马同步地将日志写回磁盘;
  • Everysec(默认),每秒写回:每个写命令执行完,只是先把日志写到 AOF 文件的内存缓冲区,每隔一秒把缓冲区中的内容写入磁盘;
  • No,操作系统控制的写回:每个写命令执行完,只是先把日志写到 AOF 文件的内存缓冲区,由操作系统决定何时将缓冲区内容写回磁盘。


2.1.0 三种策略的优缺点


针对避免主线程阻塞和减少数据丢失问题,这三种写回策略都无法做到两全其美。主要原因是:


  • Always(同步写回) 基本不丢数据,但是它在每一个写命令后都有一个慢速的落盘操作,影响主线程性能;
  • No(操作系统控制的写回)在写完缓冲区后,继续执行后续的命令,但是落盘的时机已经不在 Redis 手中了,只要 AOF 记录没有写回磁盘,一旦宕机对应的数据就丢失了;
  • Everysec(每秒写回)采用一秒写回一次的频率,避免了 Always 的性能开销,虽然减少了对系统性能的影响,但是如果发生宕机,上一秒内未落盘的命令操作仍然会丢失。


640.png


总结一下就是:想高性能,选择 No 策略;想高可靠性,选择 Always 策略;允许数据有一点丢失,又希望性能别受太大影响,选择 Everysec 策略。


2.2 AOF 恢复数据


不说了,看图:


640.png


2.3 AOF 重写


我不知道你发现没有?AOF 文件是不断地将写命令追加到文件的末尾来记录数据库状态的。写命令不断增加,AOF 体积也越来越大。


有些命令是执行多次更新同一条数据,但其实它是可以合并成同一条命令的。比如:LPUSH 对列表数据做了 6 次更改,但 AOF 只需要记录最后一次更改。因为日志恢复时,只需要执行最后一次更改的命令即可


为了处理这种情况,Redis 提供了 AOF 的重写机制。它的多变一功能,把 6 条写命令合并成一条。如下所示:


640.png


如果你的某些键有成百上千次的修改,重写机制节约的空间就很可观了。


2.3.1 触发重写


有两种触发的方法,一个是调用命令 BGREWRITEAOF;一个是修改配置文件参数。


# 方式一
192.168.17.101:6379> BGREWRITEAOF
Background append only file rewriting started
# 方式二
auto-aof-rewrite-percentage 100 #当前AOF文件大小和上一次重写时AOF文件大小的比值
auto-aof-rewrite-min-size 64mb  #文件的最小体积


2.3.2 重写步骤


  1. 创建子进程进行 AOF 重写
  2. 将客户端的写命令追加到 AOF 重写缓冲区
  3. 子进程完成 AOF 重写工作后,会向父进程发送一个信号
  4. 父进程接收到信号后,将 AOF 重写缓冲区的所有内容写入到新 AOF 文件中
  5. 对新的 AOF 文件进行改名,覆盖现有的 AOF 文件


640.png


2.4 相关配置


# 是否开启AOF功能
appendonly no
# AOF文件件名称
appendfilename "appendonly.aof"
# 写入AOF文件的三种方式
appendfsync always
appendfsync everysec
appendfsync no
# 重写AOF时,是否继续写AOF文件
no-appendfsync-on-rewrite no
# 自动重写AOF文件的条件
auto-aof-rewrite-percentage 100 #百分比
auto-aof-rewrite-min-size 64mb #大小
# 是否忽略最后一条可能存在问题的指令
aof-load-truncated yes


2.5 优缺点

优点


  1. AOF 文件可读性高,分析容易
  2. AOF 文件过大时,自动进行重写
  3. 追加形式,写入时不需要再次读取文件,直接加到末尾


缺点


  1. 相同数据量下,AOF 一般比 RDB 大
  2. AOF 恢复时需要重放命令,恢复速度慢
  3. 根据 fsync 策略,AOF 的速度可能慢于 RDB


相关实践学习
基于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
相关文章
|
2天前
|
监控 NoSQL 测试技术
【赵渝强老师】Redis的AOF数据持久化
Redis 是内存数据库,提供数据持久化功能,支持 RDB 和 AOF 两种方式。AOF 以日志形式记录每个写操作,支持定期重写以压缩文件。默认情况下,AOF 功能关闭,需在 `redis.conf` 中启用。通过 `info` 命令可监控 AOF 状态。AOF 重写功能可有效控制文件大小,避免性能下降。
|
2天前
|
存储 监控 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机制 持久化原因和对比
|
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
|
2月前
|
存储 NoSQL Redis
SpringCloud基础7——Redis分布式缓存,RDB,AOF持久化+主从+哨兵+分片集群
Redis持久化、RDB和AOF方案、Redis主从集群、哨兵、分片集群、散列插槽、自动手动故障转移
SpringCloud基础7——Redis分布式缓存,RDB,AOF持久化+主从+哨兵+分片集群
|
2月前
|
存储 缓存 NoSQL
Redis 大 Key 对持久化的影响及解决方案
Redis 大 Key 对持久化的影响及解决方案
42 1
|
2月前
|
存储 NoSQL 安全
8)详解 Redis 的配置文件以及数据持久化
8)详解 Redis 的配置文件以及数据持久化
37 0
|
2月前
|
存储 缓存 NoSQL
深入探究Redis的AOF持久化:保障数据安全与恢复性能的关键机制
深入探究Redis的AOF持久化:保障数据安全与恢复性能的关键机制
86 0
|
3月前
|
NoSQL Redis
Redis 临时manifest修改问题之确保被持久化到磁盘如何解决
Redis 临时manifest修改问题之确保被持久化到磁盘如何解决
下一篇
无影云桌面