






















在之前的文章中,我们领略了Redis基于内存的极速性能。但这也引出了一个关键问题:如果服务器重启或宕机,内存中的数据岂不是会全部丢失? 今天,我们就来深入探讨Redis如何解决这个"阿喀琉斯之踵",以及如何构建高可用的Redis架构。
想象一下,Redis就像一个拥有"超强记忆力"的天才,但它的记忆只存在于脑海中(内存)。一旦受到冲击(重启/宕机),所有记忆都会消失。为了避免这种"失忆"悲剧,Redis提供了两种"记忆备份"机制:RDB和AOF。
持久化的本质:将内存中的数据以某种形式保存到磁盘中,确保在服务重启后能够恢复数据。
RDB(Redis DataBase)的机制很简单:在特定时间点,将内存中所有数据生成一个快照文件保存到磁盘。这个文件通常以.rdb为后缀。
你可以把它理解为给整个数据库拍一张全家福,照片记录了那个瞬间的所有数据状态。
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快照当我们执行BGSAVE时,Redis会:
优点:
缺点:
AOF(Append Only File)采用了一种完全不同的思路:记录每一个写操作命令,以日志的形式追加到文件末尾。
这就像是写日记,记录下每一天发生的事情,而不是只拍几张照片。
要开启AOF,需要在配置文件中设置:
# 开启AOF持久化
appendonly yes
# AOF文件名
appendfilename "appendonly.aof"
# 同步策略
appendfsync everysec
| 策略 | 机制 | 数据安全性 | 性能影响 |
|---|---|---|---|
| always | 每个写命令都同步到磁盘 | 最高,最多丢失一个命令 | 最差,每次写都要磁盘IO |
| everysec | 每秒同步一次(默认) | 平衡,最多丢失一秒数据 | 良好,性能与安全的折中 |
| no | 由操作系统决定同步时机 | 最低,可能丢失较多数据 | 最好,完全异步 |
生产环境推荐使用everysec,在性能和数据安全之间取得最佳平衡。
随着运行时间增长,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
优点:
redis-check-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
这种组合的优势:
单机Redis存在单点故障风险,主从复制是构建高可用架构的第一步。
SYNC命令假设我们有:
方法一:配置文件
在从节点的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
# 在主节点查看复制信息
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
主从复制解决了数据备份问题,但如果主节点宕机,需要手动切换,这期间服务会不可用。哨兵模式就是为了解决这个问题。
Redis Sentinel是一个分布式系统,用于管理多个Redis实例,主要功能包括:
通常我们会部署奇数个哨兵实例(如3个或5个),通过投票机制来决定是否进行故障转移,避免误判。
假设我们有:
创建哨兵配置文件 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
客户端不再直接连接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系统的核心技术:
记住这个演进路径:
单机Redis → 开启持久化 → 搭建主从复制 → 部署哨兵集群
现在,你的Redis已经不再是那个"内存失忆"的脆弱系统,而是一个具备数据持久化和自动故障恢复能力的高可用服务!
思考与实践:
欢迎在评论区分享你在配置过程中遇到的问题和解决方案!
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。