当前位置: 首页 > news >正文

RAIDS持久化

RAIDS持久化

什么是 Redis 持久化?

Redis 作为一个键值对内存数据库(NoSQL),数据都存储在内存当中,在处理客户端请求时,所有操作都 在内存当中进行,

样做有什么问题呢?其实,只要稍微有点计算机基础知识的人都知道,存储在内存当中的数据,只要 服务器关机(各种原因引起的),内存中的数据就会消失了。 不仅服务器关机会造成数据消失,Redis 服务器守护进程退出,内存中的数据也一样会消失。

对于只把 Redis 当缓存来用的项目来说,数据消失或许问题不大,重新从数据源把数据加载进来就可以 了。

但如果直接把用户提交的业务数据存储在 Redis 当中,把 Redis 作为数据库来使用,在其放存储重要业 务数据,那么 Redis 的内存数据丢失所造成的影响也许是毁灭性。 为了避免内存中数据丢失,Redis 提供了对持久化的支持,我们可以选择不同的方式将数据从内存中保存 到硬盘当中,使数据可以持久化保存。

Redis 提供了 RDB 和 AOF 两种不同的数据持久化方式: RDB:Redis DataBase AOF:Appen-only File

RDB

RDB 是一种快照存储持久化方式,具体就是将 Redis 某一时刻的内存数据保存到硬盘的文件当中,默认 保存的文件名为 dump.rdb,而在 Redis 服务器启动时,会重新加载 dump.rdb 文件的数据到内存当中 恢复数据。

开启 RDB 持久化方式

开启 RDB 持久化方式很简单,客户端可以通过向 Redis 服务器发送 save 或 bgsave 命令让服务器生成 RDB 文件,或者通过服务器配置文件指定触发 RDB 条件。

save 命令:是一个同步操作
# 同步数据到磁盘上 127.0.0.1:6379> save OK

当客户端向服务器发送 Save 命令请求进行持久化时,服务器会阻塞 Save 命令之后的其他客户端的请 求,直到数据同步完成。

如果数据量太大,同步数据会执行很久,而这期间 Redis 服务器也无法接收其他请求,所以,最好不要 在生产环境使用 Save 命令。

范例:save执行过程会使用主进程进行快照

# 查看默认进程 [root@localhost ~]# pstree -p | grep redis-server ; ll -h /var/lib/redis |-redis-server(2104)-+-{redis-server}(2105) | |-{redis-server}(2106) | `-{redis-server}(2107) total 4.0K -rw-r--r-- 1 redis redis 92 Feb 21 17:58 dump.rdb # 执行save [root@localhost ~]# redis-cli 127.0.0.1:6379> debug populate 5000000 #这是 Redis 的一个调试命令(debug command),用于快速生成大量测试数据,这个命令不会触发持久化(AOF / RDB 不会记录它,因为它属于 调试命令)。 OK (5.99s) 127.0.0.1:6379> save OK (5.07s) # 再开个窗口 [root@localhost ~]# pstree -p | grep redis-server ; ll -h /var/lib/redis |-redis-server(2104)-+-{redis-server}(2105) | |-{redis-server}(2106) | `-{redis-server}(2107) total 64M -rw-r--r-- 1 redis redis 92 Feb 21 17:59 dump.rdb -rw-r--r-- 1 redis redis 51M Feb 21 17:59 temp-2104.rdb #主进程号2104

Bgsave:与 Save 命令不同,Bgsave 命令是一个异步操作。

# 异步保存数据到磁盘上 127.0.0.1:6379> bgsave Background saving started

当客户端发服务发出 bgsave 命令时,Redis 服务器主进程会 Forks 一个子进程来数据同步问题,在将数 据保存到 RDB 文件之后,子进程会退出。

所以,与 save 命令相比,Redis 服务器在处理 Bgsave 采用子线程进行 IO 写入。

而主进程仍然可以接收其他请求,但 Forks 子进程是同步的,所以 Forks 子进程时,一样不能接收其他 请求。

这意味着,如果 Forks 一个子进程花费的时间太久(一般是很快的),Bgsave 命令仍然有阻塞其他客户 的请求的情况发生。

服务器配置自动触发:除了通过客户端发送命令外,还有一种方式,就是在 Redis 配置文件中的 Save 指 定到达触发 RDB 持久化的条件,比如【多少秒内至少达到多少写操作】就开启 RDB 数据同步。例如我们可以在配置文件 redis.conf 指定如下的选项:

# 以下是默认值 [root@localhost ~]# vim /etc/redis.conf 218 save 900 1 # 900秒内修改了1个KEY即触发保存RDB 219 save 300 10 # 300秒内修改了10个KEY即触发保存RDB 220 save 60 10000 # 60秒内修改了10000个KEY即触发保存RDB

这种通过服务器配置文件触发 RDB 的方式,与 Bgsave 命令类似,达到触发条件时,会 Forks 一个子进 程进行数据同步。

[root@localhost ~]# redis-cli 127.0.0.1:6379> flushall OK 127.0.0.1:6379> debug populate 5000000 OK (8.99s) 127.0.0.1:6379> get key:0 value:0" 127.0.0.1:6379> get key:1 "value:1" 127.0.0.1:6379> get key:2 "value:2" 127.0.0.1:6379> get key:499999 "value:499999" 127.0.0.1:6379> get key:5000000 (nil) 127.0.0.1:6379> bgsave Background saving started #再开个窗口 [root@localhost ~]# pstree -p | grep redis-server ; ll -h /var/lib/redis |-redis-server(2104)-+-redis-server(2266) | |-{redis-server}(2105) | |-{redis-server}(2106) | `-{redis-server}(2107) total 191M -rw-r--r-- 1 redis redis 127M Feb 21 17:54 dump.rdb -rw-r--r-- 1 redis redis 62M Feb 21 17:55 temp-2266.rdb #新开了个子进程 2266

RDB 文件

前面介绍了三种让服务器生成 RDB 文件的方式,无论是由主进程生成还是子进程来生成,其过程如下:

生成临时 RDB 文件,并写入数据。 完成数据写入,用临时文代替代正式 RDB 文件。 删除原来的 DB 文件。

RDB 默认生成的文件名为 dump.rdb,当然,我可以通过配置文件进行更加详细配置。

241 rdbcompression yes # 是否压缩rbd文件 253 dbfilename dump.rdb # rdb文件的名称 263 dir /var/lib/redis # rdb文件保存目录
RDB的几个优点:

与 AOF 方式相比,通过 RDB 文件恢复数据比较快。 RDB 文件非常紧凑,适合于数据备份。 通过 RDB 进行数据备份,由于使用子进程生成,所以对 Redis 服务器性能影响较小。

RDB 的几个缺点:

如果服务器宕机的话,采用 RDB 的方式会造成某个时段内数据的丢失,比如我们设置 10 分钟同步 一次或 5 分钟达到 1000 次写入就同步一次,那么如果还没达到触发条件服务器就死机了,那么这 个时间段的数据会丢失。

使用 Save 命令会造成服务器阻塞,直接数据同步完成才能接收后续请求。

使用 Bgsave 命令在 Forks 子进程时,如果数据量太大,Forks 的过程也会发生阻塞,另外,Forks 子进程会耗费内存。

AOF

聊完了 RDB,来聊聊 Redis 的另外一个持久化方式:AOF(Append-only file)。

与 RDB 存储某个时刻的快照不同,AOF 持久化方式会记录客户端对服务器的每一次写操作命令,并将这 些写操作以 Redis 协议追加保存到以后缀为 AOF 文件末尾。 在 Redis 服务器重启时,会加载并运行 AOF 文件的命令,以达到恢复数据的目的。

①开启 AOF 持久化方式

Redis 默认不开启 AOF 持久化方式,我们可以在配置文件中开启并进行更加详细的配置,如下面的 redis.conf 文件:

# aof机制默认关闭 699 appendonly no # aof文件名 703 appendfilename "appendonly.aof" # 写入策略,always表示每个写操作都保存到aof文件中,也可以是everysec或no 729 appendfsync everysec # 默认不重写aof文件 751 no-appendfsync-on-rewrite no # 保存目录 dir /var/lib/redis

错误开启AOF功能,会导致数据丢失 注意:AOF模式默认是关闭的,第一次开启AOF后,并重启服务生效后,会因为AOF的优先级高于RDB, 而AOF默认没有数据文件存在,从而导致所有数据丢失

[root@localhost ~]# redis-cli 127.0.0.1:6379> dbsize (integer) 5000000 [root@localhost ~]# vim /etc/redis.conf 699 appendonly yes #修改此行 [root@localhost ~]# systemctl restart redis [root@localhost ~]# redis-cli 127.0.0.1:6379> dbsize (integer) 0

正确启用AOF功能,防止数据丢失

[root@localhost ~]# ll /var/lib/redis/ total 4 -rw-r--r-- 1 redis redis 127M Feb 21 17:27 dump.rdb [root@localhost ~]# redis-cli 127.0.0.1:6379> config get appendonly 1) "appendonly" 2) "no" 127.0.0.1:6379> config set appendonly yes #自动触发AOF重写,会自动备份所有数据 到AOF文件 OK 127.0.0.1:6379> config get appendonly 1) "appendonly" 2) "yes" [root@localhost ~]# ll /var/lib/redis/ total 8 -rw-r--r-- 1 redis redis 127M Feb 21 17:29 appendonly.aof -rw-r--r-- 1 redis redis 127M Feb 21 17:29 dump.rdb [root@localhost ~]# vim /etc/redis.conf 699 appendonly yes #修改此行 # 验证 [root@localhost ~]# systemctl restart redis [root@localhost ~]# redis-cli 127.0.0.1:6379> DBSIZE (integer) 5000000
②三种写入策略

在上面的配置文件中,我们可以通过 appendfsync 选项指定写入策略,有三个选项:

appendfsync always # appendfsync everysec # appendfsync no

always:客户端的每一个写操作都保存到 AOF 文件当中,这种策略很安全,但是每个写操作都有 IO 操 作,所以也很慢。

everysec:appendfsync 的默认写入策略,每秒写入一次 AOF 文件,因此,最多可能会丢失 1s 的数 据

no:Redis 服务器不负责写入 AOF,而是交由操作系统来处理什么时候写入 AOF 文件。更快,但也是最 不安全的选择,不推荐使用。

③AOF 文件重写

AOF重写是通过读取服务器当前的数据库状态来实现的。

我举个例子大家就明白了,假设我对 Redis 执行了下面六条命令:

rpush list "A" rpush list "B" rpush list "C" rpush list "D" rpush list "E" rpush list "F"

那么服务器为了保存当前 list键 的状态,会在AOF文件中写入上述六条命令。 而我现在要对 AOF 进行重写的话,其实最高效最简单的方式不是挨个读取和分析现有AOF文件中的这六 条命令。

而是直接从数据库中读取键 list 的值,然后用一条命令: rpush list “A” “B” “C” “D” “E” “F” ,可 以直接代替原 AOF 文件中的六条命令。 命令由六条减少为一条,重写的目的就达到了。

两种重写方式:通过在 redis.conf 配置文件中的选项 no-appendfsync-on-rewrite 可以设置是否开启重 写。 这种方式会在每次 Fsync 时都重写,影响服务器性能,因此默认值为 no,不推荐使用。

# 默认不重写aof文件 no-appendfsync-on-rewrite no
# 让服务器异步重写追加aof文件命令 127.0.0.1:6379> bgrewriteaof Background append only file rewriting started [root@localhost ~]# pstree -p | grep redis-server ; ll -h /var/lib/redis/ |-redis-server(1924)-+-redis-server(1940) | |-{redis-server}(1925) | |-{redis-server}(1926) | `-{redis-server}(1927) total 318M -rw-r--r-- 1 redis redis 127M Feb 24 14:29 appendonly.aof -rw-r--r-- 1 redis redis 127M Feb 24 14:27 dump.rdb -rw-r--r-- 1 redis redis 43M Feb 24 14:32 temp-rewriteaof-1940.aof
重写 AOF 文件的好处:

压缩 AOF 文件,减少磁盘占用量。 将 AOF 的命令压缩为最小命令集,加快了数据恢复的速度。

③AOF 文件损坏

在写入 AOF 日志文件时,如果 Redis 服务器宕机,则 AOF 日志文件文件会出格式错误。 在重启 Redis 服务器时,Redis 服务器会拒绝载入这个 AOF 文件,可以通过以下步骤修复 AOF 并恢复数 据:

备份现在 AOF 文件,以防万一。 使用 redis-check-aof 命令修复 AOF 文件,该命令格式如下:

# 修复aof日志文件 [root@localhost ~]# redis-check-aof --fix /var/lib/redis/appendonly.aof The AOF appears to start with an RDB preamble. Checking the RDB preamble to start: [offset 0] Checking RDB file --fix [offset 26] AUX FIELD redis-ver = '5.0.3' [offset 40] AUX FIELD redis-bits = '64' [offset 52] AUX FIELD ctime = '1771664520' [offset 67] AUX FIELD used-mem = '858552' [offset 83] AUX FIELD aof-preamble = '1' [offset 85] Selecting DB ID 0 [offset 1202] Selecting DB ID 1 [offset 1245] Checksum OK [offset 1245] \o/ RDB looks OK! \o/ [info] 110 keys read [info] 0 expires [info] 0 already expired RDB preamble is OK, proceeding with AOF tail... AOF analyzed: size=1245, ok_up_to=1245, diff=0 AOF is valid

重启 Redis 服务器,加载已经修复的 AOF 文件,恢复数据。

AOF 的优点:

AOF 只是追加日志文件,因此对服务器性能影响较小,速度比 RDB 要快,消耗的内存较少。

AOF 的缺点:

AOF 方式生成的日志文件太大,即使通过 AFO 重写,文件体积仍然很大。 恢复数据的速度比 RDB 慢。

选择 RDB 还是 AOF 呢?

通过上面的介绍,我们了解了 RDB 与 AOF 各自的优点与缺点,到底要如何选择呢? 通过下面的表示,我们可以从几个方面对比一下 RDB 与 AOF,在应用时,要根据自己的实际需求,选择 RDB 或者 AOF。

其实,如果想要数据足够安全,可以两种方式都开启,但两种持久化方式同时进行 IO 操作,会严重影响 服务器性能,因此有时候不得不做出选择。

当 RDB 与 AOF 两种方式都开启时,Redis 会优先使用 AOF 日志来恢复数据,因为 AOF 保存的文件比 RDB 文件更完整。

小结:

上面讲了一大堆 Redis 的持久化机制的知识,其实,如果你只是单纯把 Redis 作为缓存服务器, 那么可以完全不用考虑持

但是,在如今的大多数服务器架构中,Redis 不单单只是扮演一个缓存服务器的角色,还可以作为数据 库,保存我们的业务数据,此时,我们则需要好好了解有关 Redis 持久化策略的区别与选择。

http://www.jsqmd.com/news/696901/

相关文章:

  • ARMv8 PMU架构与性能监控实践指南
  • 直热式电开水锅炉制造企业哪家好,全国性价比高的推荐 - 工业推荐榜
  • 榴莲叶子病害检测数据集VOC+YOLO格式420张4类别有增强
  • Weka机器学习模型评估方法与实战指南
  • Cosmos-Reason1-7B开源镜像:符合GPLv3协议的可审计、可复现推理工具链
  • EthereumJ同步机制深度解析:快速同步与区块下载的完整流程
  • GZXTaoBaoAppFlutter个人中心设计:卡片式布局与数据展示全指南
  • AArch64程序计数器与分支指令深度解析
  • 探讨实力强的国标钢管定制机构,天津洪伟钢管费用多少钱? - myqiye
  • Phi-4-mini-flash-reasoning部署教程:多实例并行部署与GPU资源隔离方案
  • 百度网盘直连解析:免费解决限速困扰的终极方案
  • qmc-decoder快速入门:5分钟学会解密QQ音乐加密文件
  • 基于LLM的智能代码审查工具Shippie:从原理到CI/CD集成实战
  • 基于DQN的超级马里奥AI训练:从环境搭建到奖励函数设计实战
  • Park UI组件设计哲学:基于Ark UI和Panda CSS的架构解析
  • 说说天津服务不错的国标钢管定制专业公司,哪家口碑好? - mypinpai
  • GAN技术发展与应用:从基础到实战
  • 宝润机械作为钢拱架焊接机器人厂家,性价比怎么样? - 工业设备
  • marketingskills与Claude Code集成:打造智能营销助手的完整教程
  • 3步掌握个人数据恢复:从加密文件到可读内容的完整指南
  • 如何快速上手Bash3Boilerplate:新手入门完整教程
  • Komodo Edit项目管理功能:从单一文件到复杂项目的完整工作流
  • Elementary数据监控终极指南:从零到专家
  • 2026年河南口碑不错的盖梁骨架焊接机器人公司排名,哪家更靠谱 - 工业品牌热点
  • macOS iMessage自动化开发:基于TypeScript的SDK实现消息收发与监听
  • 如何快速搭建缠论可视化系统:基于TradingView本地SDK的完整指南
  • VINS_Fusion实战解析:如何将算法从实验室数据集迁移到自己的机器人上?
  • fvcore性能优化:如何通过缓存和并行化提升计算速度
  • Uniform性能优化技巧:提升表单渲染速度的10个方法
  • 【智能算法】霜冰优化算法(RIME)实战:从自然机理到代码落地