忘忧的小站

  • 首页
  • 文章归档
  • 日志
  • 关于页面

  • 搜索
异常处理 AutoWrapper 入门 NoSql 数据库 sqlserver 1 分布式索引 索引 全文搜索 Lucene.Net GPS 音视频 过滤 AOP 时区 升级 ABP.Zero 数据备份 linux 阿里云盘 aliyunpan 面试题 Signalr S 汉字 css html 前端 拼音键盘 在线键盘 uniapp .Net Core XMLRPC Serilog LOKI Nlog 分布式日志 加密 总结 人生 Asp.Net Core Swagger Web Element-plus Quasar 匹配 JavaScript 正则 .Net 后台 架构师 Redis EF CORE MySQL 自考 英语 集群 Jenkins CI/DI 内网穿透 代理 ABP 学习 后端 软考

Redis入门:Redis的持久化与高可用

发表于 2025-03-27 | 分类于 NoSql | 0 | 阅读次数 18422

Redis的持久化与高可用:如何避免"内存失忆"?

在之前的文章中,我们领略了Redis基于内存的极速性能。但这也引出了一个关键问题:如果服务器重启或宕机,内存中的数据岂不是会全部丢失? 今天,我们就来深入探讨Redis如何解决这个"阿喀琉斯之踵",以及如何构建高可用的Redis架构。

一、数据持久化:为什么需要"记忆备份"?

想象一下,Redis就像一个拥有"超强记忆力"的天才,但它的记忆只存在于脑海中(内存)。一旦受到冲击(重启/宕机),所有记忆都会消失。为了避免这种"失忆"悲剧,Redis提供了两种"记忆备份"机制:RDB和AOF。

持久化的本质:将内存中的数据以某种形式保存到磁盘中,确保在服务重启后能够恢复数据。

二、RDB持久化:给数据拍"快照"

1. 工作原理

RDB(Redis DataBase)的机制很简单:在特定时间点,将内存中所有数据生成一个快照文件保存到磁盘。这个文件通常以.rdb为后缀。

你可以把它理解为给整个数据库拍一张全家福,照片记录了那个瞬间的所有数据状态。

2. 触发机制

RDB有三种主要的触发方式:

自动触发(配置策略)

在redis.conf配置文件中,我们可以设置自动触发快照的条件:

# 在900秒(15分钟)内,如果至少有1个key发生变化,则触发bgsave
save 900 1

# 在300秒(5分钟)内,如果至少有10个key发生变化,则触发bgsave  
save 300 10

# 在60秒内,如果至少有10000个key发生变化,则触发bgsave
save 60 10000

手动触发

# 1. SAVE命令(同步)- 阻塞主进程,直到快照完成,期间不处理任何请求
127.0.0.1:6379> SAVE
OK

# 2. BGSAVE命令(异步)- 后台执行快照,主进程继续处理请求
127.0.0.1:6379> BGSAVE
Background saving started

其他情况

  • 执行SHUTDOWN命令关闭Redis时,如果没有开启AOF,会自动执行RDB快照
  • 主从复制时,主节点会向从节点发送RDB文件进行全量同步

3. RDB的工作流程(BGSAVE)

当我们执行BGSAVE时,Redis会:

  1. Fork子进程:主进程创建一个子进程(copy-on-write机制,内存占用不会翻倍)
  2. 子进程写盘:子进程将内存数据写入临时RDB文件
  3. 替换旧文件:写入完成后,用新的RDB文件替换旧的
  4. 清理工作:子进程退出,通知主进程完成

4. 优缺点分析

优点:

  • ✅ 性能影响小:BGSAVE通过子进程操作,主进程几乎不受影响
  • ✅ 文件紧凑:二进制格式,文件较小,适合备份和传输
  • ✅ 恢复速度快:恢复大数据集时比AOF快很多

缺点:

  • ❌ 可能丢失数据:两次快照之间的数据修改会丢失
  • ❌ Fork可能阻塞:数据集很大时,fork操作本身可能耗时较长

三、AOF持久化:记录每一个"成长瞬间"

1. 工作原理

AOF(Append Only File)采用了一种完全不同的思路:记录每一个写操作命令,以日志的形式追加到文件末尾。

这就像是写日记,记录下每一天发生的事情,而不是只拍几张照片。

2. 配置详解

要开启AOF,需要在配置文件中设置:

# 开启AOF持久化
appendonly yes

# AOF文件名
appendfilename "appendonly.aof"

# 同步策略
appendfsync everysec

3. AOF的三种同步策略

策略 机制 数据安全性 性能影响
always 每个写命令都同步到磁盘 最高,最多丢失一个命令 最差,每次写都要磁盘IO
everysec 每秒同步一次(默认) 平衡,最多丢失一秒数据 良好,性能与安全的折中
no 由操作系统决定同步时机 最低,可能丢失较多数据 最好,完全异步

生产环境推荐使用everysec,在性能和数据安全之间取得最佳平衡。

4. AOF重写机制

随着运行时间增长,AOF文件会越来越大,而且包含很多已经过期的命令(比如对同一个key的多次set)。为了解决这个问题,Redis提供了AOF重写机制。

重写的本质:基于当前内存数据,生成一个新的、更精简的AOF文件,只包含恢复当前数据所需的最小命令集合。

# 手动触发AOF重写
127.0.0.1:6379> BGREWRITEAOF
Background append only file rewriting started

自动重写配置:

# 当AOF文件体积比上次重写后体积增长100%时,自动触发重写
auto-aof-rewrite-percentage 100

# AOF文件体积至少达到64MB时才会触发重写
auto-aof-rewrite-min-size 64mb

5. 优缺点分析

优点:

  • ✅ 数据安全:配置合理时最多丢失1秒数据
  • ✅ 可读性强:AOF文件是文本格式,可以人工阅读和修改
  • ✅ 容错性好:即使文件尾部有损坏,也可以用redis-check-aof工具修复

缺点:

  • ❌ 文件较大:通常比RDB文件大
  • ❌ 恢复速度慢:需要重新执行所有命令,恢复大数据集时较慢
  • ❌ 性能影响:在高负载下,AOF可能比RDB稍慢

四、RDB vs AOF:如何选择?

特性 RDB AOF
数据安全性 可能丢失几分钟数据 最多丢失1秒数据
恢复速度 快 慢
文件大小 小(压缩的二进制) 大(文本命令)
性能影响 BGSAVE时影响小 写入时有一定开销
灾难恢复 适合 更适合
可读性 不可读 可读

生产环境推荐策略

两者结合使用,发挥各自优势:

# 在redis.conf中同时开启RDB和AOF
save 900 1
save 300 10
save 60 10000

appendonly yes
appendfsync everysec
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

这种组合的优势:

  • AOF保证数据安全性,最多丢失1秒数据
  • RDB用于冷备份、快速重启和主从同步
  • 重启时优先使用AOF恢复(数据更完整),其次使用RDB

五、主从复制:数据备份与读写分离

单机Redis存在单点故障风险,主从复制是构建高可用架构的第一步。

1. 什么是主从复制?

  • 主节点(Master):负责写操作,将数据变化同步给从节点
  • 从节点(Slave/Replica):复制主节点数据,负责读操作

2. 主从复制的工作原理

  1. 建立连接:从节点连接到主节点,发送SYNC命令
  2. 全量同步:主节点执行BGSAVE生成RDB文件,发送给从节点
  3. 增量同步:主节点将期间的写命令缓存起来,RDB传输完成后发送给从节点
  4. 命令传播:之后主节点每收到写命令,就异步发送给从节点

3. 如何配置主从复制?

假设我们有:

  • 主节点:127.0.0.1:6379
  • 从节点:127.0.0.1:6380

方法一:配置文件
在从节点的redis.conf中添加:

replicaof 127.0.0.1 6379
# 或者老版本使用:slaveof 127.0.0.1 6379

方法二:运行时命令

# 在从节点上执行
127.0.0.1:6380> REPLICAOF 127.0.0.1 6379
OK

4. 验证主从状态

# 在主节点查看复制信息
127.0.0.1:6379> INFO replication
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6380,state=online,offset=1234,lag=0

# 在从节点查看复制信息  
127.0.0.1:6380> INFO replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up

5. 主从架构的优势

  1. 数据冗余:从节点是主节点的完整备份
  2. 读写分离:主节点负责写,从节点负责读,提升读性能
  3. 故障恢复基础:为自动故障转移做准备

六、哨兵(Sentinel)模式:实现自动故障转移

主从复制解决了数据备份问题,但如果主节点宕机,需要手动切换,这期间服务会不可用。哨兵模式就是为了解决这个问题。

1. 哨兵是什么?

Redis Sentinel是一个分布式系统,用于管理多个Redis实例,主要功能包括:

  • 监控:持续检查主从节点是否正常运行
  • 通知:当被监控的Redis实例出现问题时,向管理员发送告警
  • 自动故障转移:主节点故障时,自动将一个从节点提升为新主节点,并让其他从节点复制新主节点
  • 配置提供者:客户端连接哨兵获取当前的主节点地址

2. 哨兵集群架构

通常我们会部署奇数个哨兵实例(如3个或5个),通过投票机制来决定是否进行故障转移,避免误判。

3. 搭建哨兵模式

假设我们有:

  • Redis主节点:127.0.0.1:6379
  • Redis从节点:127.0.0.1:6380、127.0.0.1:6381
  • 哨兵节点:127.0.0.1:26379、127.0.0.1:26380、127.0.0.1:26381

创建哨兵配置文件 sentinel-26379.conf:

port 26379
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
sentinel parallel-syncs mymaster 1

参数解释:

  • sentinel monitor mymaster 127.0.0.1 6379 2:监控名为mymaster的主节点,至少需要2个哨兵同意才判定主观下线
  • down-after-milliseconds:5000毫秒无响应认为节点主观下线
  • failover-timeout:故障转移超时时间
  • parallel-syncs:故障转移后,同时向新主节点同步的从节点数量

启动哨兵:

redis-sentinel sentinel-26379.conf
redis-sentinel sentinel-26380.conf  
redis-sentinel sentinel-26381.conf

4. 故障转移过程

  1. 主观下线:某个哨兵认为主节点不可用
  2. 客观下线:多个哨兵(达到quorum数量)都认为主节点不可用
  3. 选举领导者:哨兵之间选举一个领导者来执行故障转移
  4. 故障转移:领导者哨兵选择一个合适的从节点提升为新主节点
  5. 切换配置:通知其他从节点复制新主节点,更新客户端配置

5. 客户端如何连接哨兵?

客户端不再直接连接Redis节点,而是连接哨兵集群来获取当前的主节点地址。

Java客户端示例(使用Jedis):

Set<String> sentinels = new HashSet<>();
sentinels.add("127.0.0.1:26379");
sentinels.add("127.0.0.1:26380"); 
sentinels.add("127.0.0.1:26381");

JedisSentinelPool pool = new JedisSentinelPool("mymaster", sentinels);
try (Jedis jedis = pool.getResource()) {
    // 现在操作的是当前的主节点
    jedis.set("key", "value");
}

七、持久化与高可用配置总结

方案 数据安全 可用性 复杂度 适用场景
单机+持久化 中 低 低 开发测试、非核心业务
主从复制 高 中 中 读多写少,需要备份
哨兵模式 高 高 中 生产环境通用方案
Redis集群 高 极高 高 海量数据、高并发

总结

通过本篇的学习,我们掌握了构建可靠Redis系统的核心技术:

  1. 持久化是基础:RDB提供快照备份,AOF保证命令不丢失,两者结合使用最稳妥
  2. 主从复制提供冗余:数据多副本,读写分离提升性能
  3. 哨兵实现高可用:自动故障转移,服务不中断

记住这个演进路径:
单机Redis → 开启持久化 → 搭建主从复制 → 部署哨兵集群

现在,你的Redis已经不再是那个"内存失忆"的脆弱系统,而是一个具备数据持久化和自动故障恢复能力的高可用服务!


思考与实践:

  1. 在你的开发环境中尝试配置RDB和AOF,观察文件生成情况
  2. 搭建一个一主二从的Redis环境,并验证数据同步
  3. 部署三节点哨兵集群,模拟主节点宕机,观察自动故障转移过程

欢迎在评论区分享你在配置过程中遇到的问题和解决方案!

  • 本文作者: 忘忧
  • 本文链接: /archives/2944
  • 版权声明: 本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0 许可协议。转载请注明出处!
# Redis # NoSql
Redis入门:玩转Redis五大核心数据结构
Redis入门:Redis在项目中的实战应用
  • 文章目录
  • 站点概览
忘忧

忘忧

君子藏器于身,待时而动,何不利之有

59 日志
9 分类
67 标签
RSS
Github E-mail StackOverflow
Creative Commons
0%
© 2025 忘忧
由 Halo 强力驱动