解决Redis持久化数据丢失

article/2025/9/22 20:47:48

为什么持久化?

持久化是Redis保障高可用性的基础。因为Redis是一个内存数据库,它的数据均保存在内存中,如果Redis实例发生宕机,在没有数据备份前提下,你的生产数据将会全部丢失。这时完善的持久化机制,可以把内存中的数据持久化到磁盘上,方便我们进行备份数据和快速恢复数据。

但是持久化就一定能保证数据不丢失吗?

首先我们要了解Redis为了保证高可用性,一般都是从一下几个方面入手的:

  • 数据持久化
  • 主从复制
  • 自动故障恢复
  • Redis集群

常见的Redis持久化有两种:(1)RDB快照持久化(2)AOF持久化,区别在于RDB持久化保存完整的数据,AOF缓存的是redis指令(当然我们该可以简化AOF缓存的指令)。缺点也很明显,RDB是某一时刻的数据快照,因此它的数据并不全,生成RDB文件的代价是比较大的,它会消耗大量的CPU和内存资源。RDB持久化适用于主从全量同步数据、数据库备份。AOF适合做增量数据的持久化。Redis启动会优先加载AOF文件进行数据恢复。

AOF 持久化

什么是 AOF 持久化

AOF(Append Only File):通过保存数据库执行的命令来记录数据库的状态。

AOF日志对数据库命令的保存顺序是,Redis 先执行命令,把数据写入内存,然后才记录日志。

为什么要后记录日志呢

1、后写,能够避免记录到错误的命令。因为是先执行命令,后写入日志,只有命令执行成功了,命令才能被写入到日志中。

2、避免阻塞当前的写操作,是在命令执行后才记录日志,所以不会阻塞当前的写操作。

AOF 的潜在风险

  • 1、如果命令执行成功,写入日志的时候宕机了,命令没有写入到日志中,这时候就有丢失数据的风险了,因为这时候没有写入日志,服务断电之后,这部分数据就丢失了。

这种场景在别的地方也很常见,比如基于 MQ 实现分布式事务,也会出现业务处理成功 + 事务消息发送失败这种场景,RabbitMQ,RocketMQ,Kafka 事务性,消息丢失和消息重复发送的处理策略

  • 2、AOF 的日志写入也是在主线程进行的,如果磁盘的压力很大,写入速度变慢了,会影响后续的操作。

这两种情况可通过调整 AOF 文件的写入磁盘的时机来避免

AOF 文件的写入和同步

AOF 文件持久化的功能分成三个步骤,文件追加(append),文件写入,文件同步(sync)。

AOF 文件在写入磁盘之前是先写入到 aof_buf 缓冲区中,然后通过调用 flushAppendOnlyFile 将缓冲区中的内容保存到 AOF 文件中。

写入的策略通过 appendfsync 来进行配置

  • Always:同步写回 每次写操作命令执行完后,同步将 AOF 日志数据写回硬盘;

  • Everysec:每秒写回 每次写操作命令执行完后,先将命令写入到 AOF 文件的内核缓冲区,然后每隔一秒将缓冲区里的内容写回到硬盘;

  • No:操作系统控制的写回 Redis 不在控制命令的写会时机,交由系统控制。每次写操作命令执行完成之后,命令会被放入到 AOF 文件的内核缓冲区,之后什么时候写入到磁盘,交由系统控制。

RDB 持久化

什么是 RDB 持久化

RDB(Redis database):实现方式是将存在 Redis 内存中的数据写入到 RDB 文件中保存到磁盘上从而实现持久化的。

和 AOF 不同的是 RDB 保存的是数据而不是操作,在进行数据恢复的时候,直接把 RDB 的文件读入到内存,即可完成数据恢复。

RDB 如何做内存快照

Redis 中对于如何备份数据到 RDB 文件中,提供了两种方式

  • 1、save: 在主线程中执行,不过这种会阻塞 Redis 服务进程;

  • 2、bgsave: 主线程会 fork 出一个子进程来负责处理 RDB 文件的创建,不会阻塞主线程的命令操作,这也是 Redis 中 RDB 文件生成的默认配置;

对于 save 和 bgsave 这两种快照方式,服务端是禁止这两种方式同时执行的,防止产生竞争条件。

Redis 中可以使用 save 选项,来配置服务端执行 BGSAVE 命令的间隔时间

## Save the DB on disk:##   save <seconds> <changes>##   Will save the DB if both the given number of seconds and the given#   number of write operations against the DB occurred.##   In the example below the behaviour will be to save:#   after 900 sec (15 min) if at least 1 key changed#   after 300 sec (5 min) if at least 10 keys changed#   after 60 sec if at least 10000 keys changed##   Note: you can disable saving completely by commenting out all "save" lines.##   It is also possible to remove all the previously configured save#   points by adding a save directive with a single empty string argument#   like in the following example:##   save ""save 900 1save 300 10save 60 10000

save 300 10 就是服务端在300秒,读数据进行了至少10次修改,就会触发一次 BGSAVE 命令

 

单节点模式

单节点模式下只使用RDB持久化,在某一时刻redis宕机,此时的数据并没有来得及进行rdb持久化备份,这就出现了数据丢失的可能。
在Redis单节点模式下,我们可以可以采用RDB+AOF结合使用防止Redis缓存数据丢失,一个进行全量数据备份,一个进行增量操作指令的备份。

Redis集群模式

在Redis集群主从结构下,如果不开启master的持久化,在master意外宕机后,由于数据全在master节点的内存上,在master节点重启后数据将会全部丢失。此时进行主从数据同步操作,将会导致slave从节点的数据也会被master节点的空数据覆盖清理掉。
在master-slave主从模式下master node 必须开启持久化功能来保证数据不丢失。

但是master-node开启持久化并不意味着数据就不会丢失。

数据异步复制时丢失

因为master-slave节点的数据同步是异步的,可能在数据同步完成前master节点发生宕机,此时这部分的数据就意外丢失了。

脑裂时数据丢失

所谓脑裂,是指master节点自己突然脱离正常网络(并没有宕机,还在运行中),与其他的salve节点的连接断开,但哨兵会认为master节点已经宕机,要从slave节点中重新选举新的master节点,这个时候集群中实际存在两个master节点,这就是脑裂。
虽然某一个slave节点被选举为master节点,但是客户端连接的master仍然是旧master节点,数据还是写向旧master节点上,当旧master节点再次恢复后,会作为slave节点挂在新master节点上,旧master节点中的数据会被新master节点上的数据同步清理掉。

解决方案

通过redis.conf 中配置项,设置至少有1个slave,数据复制和同步的延迟不能超过8秒,来减少异步复制和脑裂导致的数据丢失 :

min-slaves-to-write 1 
min-slaves-max-lag 8

如果所有的slave节点的数据同步延时都超过8s,master节点拒绝写请求。
这种情况下脑裂也就最多丢失8秒的数据。


http://chatgpt.dhexx.cn/article/LNKZUdEI.shtml

相关文章

Redis持久化:RDB和AOF

一、为什么需要持久化&#xff1f; Redis对数据的操作都是基于内存的&#xff0c;当遇到了进程退出、服务器宕机等意外情况&#xff0c;如果没有持久化机制&#xff0c;那么Redis中的数据将会丢失无法恢复。有了持久化机制&#xff0c;Redis在下次重启时可以利用之前持久化的文…

redis混合持久化

RDB &#xff08;即 Redis Data Base 的缩写&#xff09;和 AOF &#xff08;即 Append Only File 的缩写&#xff09;持久化各有利弊&#xff0c;RDB 可能会导致一定时间内的数据丢失&#xff0c;而 AOF 由于文件较大则会影响 Redis 的启动速度&#xff0c;为了能同时使用 RDB…

Redis持久化存储(详细)

来自知乎&#xff1a;https://zhuanlan.zhihu.com/p/77646963 分享学习 Redis 的数据全部在内存里&#xff0c;如果突然宕机&#xff0c;数据就会全部丢失&#xff0c;因此必须有一种机制来保证 Redis 的数据不会因为故障而丢失&#xff0c;这种机制就是 Redis 的持久化机制。…

redis持久化配置及两种方式

持久化 redis持久化是指在指定的时间间隔内将内存中的数据集快照(snapshotting)写入磁盘&#xff0c;恢复时是将快照文件读入内存 redis提供了两种持久化方式 一&#xff1a;RDB内存快照 1&#xff1a;概念 RDB的实现方式为&#xff0c;在指定时间将当前时刻内存中的数据生成一…

redis持久化概念

1、前言 Redis是一种高级key-value数据库。它跟memcached类似&#xff0c;不过数据可以持久化&#xff0c;而且支持的数据类型很丰富。有字符串&#xff0c;链表&#xff0c;集 合和有序集合。支持在服务器端计算集合的并&#xff0c;交和补集(difference)等&#xff0c;还支持…

redis持久化机制

redis持久化机制 RDB&#xff08;redis database&#xff09;触发方式配置文件自动化触发save命令bgsave命令shutdown命令flushall命令主从复制 AOF&#xff08;append only file&#xff09;AOF方式的三种写入策略触发方式 混合持久化 redis默认的持久化机制是RDB。 redis是常…

Redis持久化方式

1 RDB RDB(Snapshot 内存快照) 。RDB是默认的持久化方式&#xff0c;按照一定的策略周期性的将内存中的数据生成快照保存到磁盘。 每次快照持久化都是将内存数据完整写入到磁盘一次。并不是增量&#xff0c;如果数据量过大&#xff0c;会引起大量的磁盘IO&#xff0c;影响性能…

Redis持久化面试题

Redis持久化面试题 1.redis中有哪些持久化方式&#xff1f;2.RDB的工作原理3.RDB触发机制4.RDB持久化的缺点5.AOF的工作原理6.开启AOF7.AOF触发机制8.RDB和AOF的优缺点9.RDB和AOF的优先级 1.redis中有哪些持久化方式&#xff1f; ​ redis中的持久化有两种方式&#xff0c;分别…

Redis 持久化

目录 Redis 中的持久化 Redis 的核心架构 IO多路复用线程模型 核心工作单线程模型 Redis持久化介绍 持久化的意义 持久化机制 持久化方式对比 Redis 持久化 - RDB RDB简介 RDB的触发机制 Redis持久化- AOF AOF简介 AOF 的重写机制 AOF的触发机制 AOF重写机制的副…

Redis持久化方案

持久化方式 通常数据库存在三种用于持久操作以防止数据损坏的常见策略: 1&#xff0e;是数据库不关心故障&#xff0c;而是在数据文件损坏后从数据备份或快照中恢复。RDB就是这种情况2&#xff0e;该数据库使用操作日志记录每个操作的操作行为&#xff0c;以在失败后通过日志…

Redis持久化详解

一、概述 在Redis中&#xff0c;实现高可用的技术主要包括持久化、复制、哨兵和集群&#xff0c;下面分别说明它们的作用&#xff0c;以及解决了什么样的问题。 持久化&#xff1a;持久化是最简单的高可用方法(有时甚至不被归为高可用的手段)&#xff0c;主要作用是数据备份…

Redis的持久化方式

Redis支持两种方式的持久化&#xff0c;一种是RDB方式、另一种是AOF&#xff08;append-only-file&#xff09;方式&#xff0c;两种持久化方式可以单独使用其中一种&#xff0c;也可以将这两种方式结合使用。 •RDB&#xff1a;根据指定的规则“定时”将内存中的数据存储在硬…

Redis持久化详解(简单易懂)

首先先来谈一谈对持久化的理解 持久化(Persistence) 在Redis中的工作原理就是将你存储在缓存中的数据集异步的保存在你的磁盘中实现持久存储 当电脑或者服务器发生宕机时 我们的内存会被清空 但是存储在磁盘中的数据不会丢失 当我们再次打开Redis时 磁盘中的数据集就会再次同步…

Redis持久化

Redis的持久化方式 Redis的持久化有两种方式&#xff1a;RDB和AOF&#xff0c;redis默认采用的是RDB的方式。 RDB 在默认配置中&#xff0c;Redis将内存数据库快照保存在名字为dump.rdb的二进制文件中。 可以配置持久化策略&#xff1a;save N M&#xff0c;让redis在“N秒…

Redis - 持久化有哪几种方式,怎么选?

1、AOF 持久化 Redis是基于内存的&#xff0c;如果Redis服务器挂了&#xff0c;数据就会丢失。为了避免数据丢失了&#xff0c;Redis提供了两种持久化方式&#xff0c;RDB和AOF。我们先来介绍AOF。 AOF&#xff08;append only file&#xff09; 持久化&#xff0c;采用日志的…

STM32-Arduino编程 CAN总线通信

STM32-Arduino编程 CAN总线通信 环境说明使用Arduino开发STM32原因直接开始操作 环境说明 开发软件&#xff1a;vscodePlatformIO 操作系统&#xff1a;win10 开发板&#xff1a;STM32F103C8T6 CAN总线通信模块&#xff1a;TJA1050 使用Arduino开发STM32原因 STM32开发比较常…

ESP8266-Arduino编程实例-QRE1113红外反射传感器

QRE1113红外反射传感器 1、QRE1113介绍 QRE1113 具有易于使用的模拟输出,它会根据反射回传感器的红外光量而有所不同。 QRE1113 IR 反射传感器由两部分组成 - 一个 IR 发射 LED 和一个 IR 敏感光电晶体管。 当 VCC 和 GND 引脚通电时,传感器内部的 IR LED 将亮起。 由于深…

ESP8266-Arduino编程实例-MLX90614红外测温传感器驱动

MLX90614红外测温传感器驱动 1、MLX90614传感器介绍 MLX90614 是一款非接触式红外测温仪,测量范围为 -70 至 +380 摄氏度。 MLX90614有以下特性: 体积小,成本低安装在带有两种引脚的分线板上用于 I2C 接口的 10k 上拉电阻,带有可选的焊接跳线在宽温度范围内进行工厂校准…

STM32-Arduino编程 串口通信

STM32-Arduino编程 串口通信 环境说明使用Arduino开发STM32原因直接开始操作 环境说明 开发软件&#xff1a;vscodePlatformIO 操作系统&#xff1a;win10 开发板&#xff1a;STM32F103C8T6 其他硬件&#xff1a;USB转TTL模块&#xff08;需要安装对应驱动&#xff09; 使用A…

ESP8266-Arduino编程实例-金属触摸传感器驱动

金属触摸传感器驱动 1、金属触摸传感器介绍 KY-036金属触摸传感器模块采用KRS13达林顿NPN晶体管,其信号由电路部分控制,电路部分集成LM393,内部有两个比较器。 当触摸弯曲在晶体管上的裸线(由晶体管的基极表示)时,环境的 50 Hz 信号被注入到高增益放大器中。放大器的输…