Redis持久化方案

article/2025/9/22 21:06:45

持久化方式

通常数据库存在三种用于持久操作以防止数据损坏的常见策略:

  • 1.是数据库不关心故障,而是在数据文件损坏后从数据备份或快照中恢复。RDB就是这种情况
  • 2.该数据库使用操作日志记录每个操作的操作行为,以在失败后通过日志恢复一致性。由于操作日志是按顺序追加写入的,因此不会出现无法恢复操作日志的情况。类似于Mysql的重做和撤消日志。
  • 3.数据库不修改旧数据,而仅通过追加进行写入,因此数据本身就是日志,因此永远不会出现数据无法恢复的情况。CouchDB是一个很好的例子。AOF类似这种情况

严格上讲Redis为持久化提供了三种方式:

  • RDB:在指定的时间间隔能对数据进行快照存储,类似于MysQL的dump备份文件。
  • AOF:记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据(MySQL的binlog)
  • RDB与AOE混合使用,这是Redis4.0开始的新特性。在混合使用中AOF读取RDB数据重建原始数据集,集二者优势为
    一体。

操作

[root@localhost ~]# cd /usr/local/redis/
[root@localhost redis]# ll
total 0
drwxr-xr-x. 2 root root 152 Dec 12 20:58 bin
[root@localhost redis]# mkdir conf
[root@localhost redis]# mkdir data
[root@localhost redis]# mkdir log
[root@localhost redis]# vim /usr/local/redis/conf/redis.conf

配置文件

# 放行访问IP限制
bind 0.0.0.0
# 后台启动
daemonize yes
# 日志存储目录及日志文件名
logfile "/usr/local/redis/log/redis.log"
# rdb数据文件名
dbfilename dump.rdb
# rdb数据文件和aof数据文件的存储目录
dir /usr/local/redis/data
#设置密码
requirepass 123456

[root@localhost redis]# bin/redis-server conf/redis.conf

RDB持久化

我们可以配置Redis在n秒内如果超过m个key被修改就自动做快照,下面是默认的快照保存配置(这3个选项都屏蔽,则RDB禁用)∶

# 900秒内如果超过1个key改动,则发起快照保存
save 900 1
# 300秒内如果超过10个key改动,则发起快照保存
save 300 10
# 60秒内如果超过1W个key改动,则发起快照保存
save 60 10000

快照

把整个内存数据映射到硬盘中,保存一份到硬盘,因此恢复数据起来比较快,把数据映射回去即可,不像AOF,一条条的执行操作命令。

快照是默认的持久化方式。这种方式是就是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.db。可以通过配置设置自动做快照持久化的方式。

产生快照的情况有以下几种:

  • 手动bgsave执行,非阻塞
  • 手动save执行,阻塞
  • 根据配置文件自动执行(bgsave方式)
  • 客户端发送shutdown,系统会先执行save命令阻塞客户端,然后关闭服务器
  • 当有主从架构时,从服务器向主服务器发送sync命令来执行复制操作时,主服务器会执行bgsaxe操作

RDB工作原理

Redis默认会将快照文件存储在Redis当前进程的工作目录中的dump.rdb文件中,可以通过配置dir和dbfilename两个参数分别指定快照文件的存储路径和文件名。流程过程如下(rdb.c中)。


BGSAVE会fork一个子进程来保存RDB,在这个期间能够正常接受外界命令,这时候如果主进程有修改的语句,就会把需要修改的数据复制出来,给子进程使用,主进程改干嘛干嘛。
保存好的新的RDB后,会将新RDB替换旧的RDB。如果期间还有SAVE,或BGSAVE命令执行,会被拒绝,如果有BGREWRITEAOF命令,会在BGSAVE执行结束后再执行。

RBD的优点

  • 紧凑压缩的二进制文件
  • fork子进程性能最大化
  • 启动效率高

RDB的缺点

  • 生成快照的时机问题
  • fork子进程的开销问题

AOF持久化

它也是Redis持久化的重要手段之一,AOF (Append Only File)只追加文件,也就是每次处理完请求命令后都会将此命令追加到aof文件的末尾。而RDB是压缩成二进制等时机开子进程去干这件事。

通过配置进行启动,默认是关闭的。

# 默认appendonly为no
appendonly yes
appendfilename "appendonly.aof"
# RDB文件和AOF文件所在目录
dir /usr/local/redis/data

同步策略

Redis中提供了3种AOF同步策略:

  • 每秒同步(默认,每秒调用一次fsync,这种模式性能并不是很糟糕)
  • 每修改同步(会极大消弱Redis 的性能,因为这种模式下每次write后都会调用fsync)。
  • 不主动同步(由操作系统自动调度刷磁盘,性能是最好的)
# 每秒钟同步一次,该策略为AOF的缺省策略
appendfsync everysec
# 每次有数据修改发生时都会写入AOF文件
appendfsync always
# 从不同步。高效但是数据不会主动被持久化
appendfsync no

工作原理


AOF的频率高的话肯定会对Redis带来性能影响,因为每次都是刷盘操作。跟mysql一样了。Redis每次都是先将命令放到缓冲区,然后根据具体策略(每秒/每条指令/缓冲区满)进行刷盘操作。如果配置的always,那么就是典型阻塞,如果是everysec每秒的话,那么会开一个同步线程去每秒进行刷盘操作,对主线程影响稍小。

写入文件与恢复

AOF文件是一个只进行append操作的日志文件,因此在写入过程中即使出现宕机现象,也不会破坏日志文件中已经存在的内容。假如一次操作只是写入了一半数据就出现了系统崩溃问题,不用担心,在Redis下一次启动之前,我们可以通过redis-check-aof工具来帮助我们修复问题。

AOF文件有序地保存了对数据库执行的所有写入操作,这些写入操作以Redis协议的格式保存,因此 AoF文件的内容非常容易被人读懂,对文件进行分析( parse)也很轻松。

导出(export)AOF文件也非常简单:举个例子,如果你不小心执行了FLUSHALL
命令,但只要AOF文件未被重写,那么只要停止服务器,移除AQEFA文件未尾的 FLUSHALL命令,并重启Redis,就可以将数据集恢复到FLUSHALL执行之前的状态。

重写

Redis可以在AOF文件体积变得过大时,自动地在后台对AOF进行rewrite。即Redis以append模式不断的将修改数据写入到老的磁盘文件中,同时Redis还会创建一个新的文件用于记录此期间有哪些修改命令被执行。

因为Redis在创建新AOF文件的过程中,会继续将命令追加到现有的AOF文件里面,即使重写过程中发生停机,现有的AOF文件也不会丢失。

而一旦新AOF文件创建完毕,Redis 就会从旧AOF 文件切换到新 AOF文件,并开始对新AOF文件进行追加操作。

为什么要重写

比如我有业务很简单,就来回delete set同一个key。就这个业务运行了10年,那么aof文件将记录无数个delete k1, set k1。其实都是重复的,但是我aof每次都追加,文件变成了1T大小。这时候Redis宕机了,要恢复,你想想1TB大小的aof文件去恢复,累死了。最主要的是1TB大小只记录了两个命令,所以压缩其实就是来处理这件事的。

rewrite触发条件

  • 客户端执行bgrewriteaof命令.
  • auto-aof-rewrite-min-size 64mb
  • auto-aof-rewrite-percentage 100

常用配置

# fsync持久化策略
appendfsync everysec
# AOF重写期间是否禁止fsync;如果开启该选项,可以减轻文件重写时CPU和硬盘的负载(尤其是硬盘),但是可能会丢失AOF重写期间的数据;需要在负载和安全性之间进行平衡
no-appendfsync-on-rewrite no
# 当前aof文件大于多少字节后才触发重写
auto-aof-rewrite-min-size 64mb
# 当前写入日志文件的大小超过上一次rewrite之后的文件大小的百分之100时,也就是2倍时触发Rewrite
auto-aof-rewrite-percentage 100
# 如果AOF文件结尾损坏,Redis启动时是否仍载入AOF文件
aof-load-truncated yes

AOF优点

  • 数据不易丢失
  • 自动重写机制
  • 易懂易恢复

AOF缺点

  • AOF文件恢复数据慢
  • AOF持久化效率低

如何选择RDB和AOF

同时开启

Redis先加载AOF文件来恢复原始数据,因为AOF数据比rdb更完整,但是aof存在潜在的bug,如把错误的操作记录写入了aof,会导出数据恢复失败,所以可以把RDB作为后备数据。

为了考虑性能,可以只在slave上开启RDB,并且15min备份一次,如果为了避免AOF rewite的IO以及阻塞,可以在Redis集群中不开启AOE,靠集群的备份机制来保证可用性,在启动时选取较新的RDB文件,如果集群全部崩溃,会丢失15min前的数据。

混合模式

Redis4.0开始支持该模式。

解决的问题: Redis在重启时通常是加载AOF文件,但加载速度慢。因为RDB数据不完整,所以加载AOF

开启方式: aof-use-rdb-preamble true

开启后,AOF在重写时会直接读取RDB中的内容。

运行过程:通过bgrwriteaof完成,不同的是当开启混合持久化后

  • 1.子进程会把内存中的数据以RDB的方式写入aof中
  • 2.把重写缓冲区中的增量命令以AOF方式写入到文件
  • 3.将含有RDB个数和AOF格数的AOF数据覆盖旧的AOF文件

新的AOF文件中,一部分数据来自RDB文件,一部分来自Redis运行过程时的增量数据

数据恢复

当我们开启了混合持久化时,启动Redis依然优先加载aof文件,aof文件加载可能有两种情况如下:

  • aof文件开头是rdb的格式,先加载rdb内容再加载剩余的aof
  • aof文件开头不是rdb的格式,直接以aof格式加载整个文件

优点:既能快速备份又能避免大量数据丢失

缺点:RDB是压缩格式,AOF在读取它时可读性较差

二者动态切换

在Redis 2.2或以上版本,可以在不重启的情况下,从RDB切换到AOF:

  • 为最新的 dump.rdb文件创建一个备份
  • 将备份放到一个安全的地方
cp dump.rdb dump.rdb.bak

执行以下两条命令:

# 开启aof
redis-cli config set appendonly yes
# 关闭rdb
redis-cli config set save ""
  • 确保写命令会被正确地追加到AOF文件的末尾
  • 执行的第一条命令开启了AOF功能: Redis会阻塞直到初始AOF文件创建完成为止,之后Redis 会继续处理命令请求,并开始将写入命令追加到AOF文件末尾

Redis容灾备份

开启RDB持久化

save 900 1
save 300 10
save 60 10000

开启AOF配置

# 开启aof
appendonly yes
appendfilename "appendony.aof"# rewrite
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb# appendfsync always
appendfsync everysec
# appendfsync no

RDB日志备份,编写脚本定时备份

vim一个redis-rdb-copy-per-hour.sh

#!bin/bash
cur_date=$(date "+%Y%m%d%H%M%S")
rm -rf /usr/local/redis/snapshotting/$cur_date
mkdir -p /usr/local/redis/snapshotting/$cur_date
cp /usr/local/redis/data/dump.rdb /usr/local/redis/snapshotting/$cur_date
del_date=$(date -d -48hour "+%Y%m%d%H%M")
rm -rf /usr/local/redis/snapshotting/$del_date

使用crontab定时器执行备份脚本

crontab -e

然后写入生产环境可以调整一下每小时执行一次


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

相关文章

Redis持久化详解

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

Redis的持久化方式

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

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

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

Redis持久化

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

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

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

STM32-Arduino编程 CAN总线通信

STM32-Arduino编程 CAN总线通信 环境说明使用Arduino开发STM32原因直接开始操作 环境说明 开发软件:vscodePlatformIO 操作系统:win10 开发板:STM32F103C8T6 CAN总线通信模块: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原因直接开始操作 环境说明 开发软件:vscodePlatformIO 操作系统:win10 开发板:STM32F103C8T6 其他硬件:USB转TTL模块(需要安装对应驱动) 使用A…

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

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

Arduino编程语言之setup()和loop()

Arduino编程语言之setup()和loop() setup() 当程序开始执行时,将调用setup()函数,使用此函数 ①用来初始化变量 ②管脚模式 ③调用库函数 注意:setup()函数将只运行一次。 例子: int ledPin 13; void setup() { pinMode(ledP…

esp8266使用Arduino编程实现自动浇水、OTA升级功能

创作前情: 上海疫情已有一段时间,从三月初算起来已过了一个多月,当时用了泡沫箱种了些小香葱,这几天把它搬到了室外阳台,由于浇水不方便,想着做一个自动浇水的设备。 实现目的: 可以远程控制浇…

ESP8266-Arduino编程实例-MPL3115A2压力传感器驱动

MPL3115A2压力传感器驱动 1、MPL3115A2介绍 MPL3115A2 是一款紧凑型压阻式绝对压力传感器,具有 I2C 数字接口。 MPL3115A2 具有 20 kPa 至 110 kPa 的宽工作范围,该范围涵盖了地球上的所有表面高度。 MEMS 使用片上温度传感器进行温度补偿。 压力和温度数据被馈送到高分辨率…

ESP8266-Arduino编程实例-AHT20温湿度传感器驱动

AHT20温湿度传感器驱动 1、AHT20介绍 AHT20作为新一代温湿度传感器,在尺寸和智能方面树立了新标准。 它嵌入在适合回流焊接的双排扁平无铅封装中,底部为 3 x 3 mm,高度为 1.0 mm。 该传感器以标准IAHT20输出校准后的数字信号,作为新一代温湿度传感器,在尺寸和智能方面树…

ESP8266-Arduino编程实例-中断

中断 本文将演示如何使用 ESP8266 NodeMCU 的中断和定时器。 中断检测 GPIO 状态的变化且无需不断检查其当前值。通过使用中断,当检测到更改时,会触发事件(调用函数)。 在实例中,使用 PIR 运动传感器检测运动:当检测到运动时,ESP8266 会启动一个定时器并打开 LED 预定…

ESP8266-Arduino编程实例-MLX90393磁场传感器驱动

MLX90393磁场传感器驱动 1、MLX90393介绍 MLX90393 磁场传感器可以在运行时重新编程为不同的模式和不同的设置。 该传感器使用 Melexis 专有的 Triaxis 技术提供与沿 XYZ 轴感应的磁通密度成比例的 16 位输出,还提供温度输出信号。 这些数字值可通过 I2C 和 SPI 获得,其中 …

arduino新手入门详细教程系列之【Ⅱ:arduino编程环境配置】

目录 一)下载Arduino IDE 二)安装驱动 三)认识Arduino IDE 四)下载一个Blink程序 五)blink程序 更多优质文章请关注博主: 沄边小卖部的博客_CSDN博客-笔记,计算机类相关,《初级会计实务》考试学习分享…

ESP8266-Arduino编程实例-PWM

PWM 本文将演示如何使用ESP8266 NodeMCU生成PWM信号,通过随时间改变占空比来调节 LED 亮度。 ESP8266 GPIO 可以设置为输出 0V 或 3.3V,但在0~3.3V之间不能输出任何电压。 尽管如此,可以使用脉宽调制 (PWM) 输出“假”中电平电压,从而产生不同级别的 LED 亮度的方式。 如…

Arduino编程基础与常用函数(详细)解析

Arduino编程基础 关键字: if、if…else、for、switch、case、while、do…while、break、continue、return、goto。 语法符号:每条语句以“;”结尾,每段程序以“{}”括起来。 数据类型: boolean、 char、 int、 unsign…

Arduino入门-Arduino编程语言入门教程

随着社会的发展,越来越多的中小学生、老师、创客们、设计师、艺术家等都在玩Arduino,那Arduino编程语言入门难吗?我们都知道Arduino使用C/C编写程序,虽然C兼容C语言,但这是两种语言,C语言是一种面向过程的编程语言&…