前言
本次进行Redis 哨兵模式(Sentinel) 的详细讲解,包括其 实现原理、作用、适用场景、配置方式,并附带一个带注释的Go语言示例,帮助大家更好的理解与接入,在一定程度上实现服务的高可用。
✅ 一、Redis哨兵模式简介
哨兵模式(Sentinel) 是 Redis 提供的高可用解决方案,用于实现主从架构下的 自动故障转移、服务监控与通知告警。
🧠 二、哨兵模式的核心作用
1、监控(Monitoring)
- 哨兵会不断检查主节点和从节点是否可达。
2、自动故障转移(Automatic Failover)
- 当主节点宕机时,会自动将一个从节点提升为主节点,完成主从切换。
3、通知(Notification)
- 系统管理员会收到 Redis Sentinel 的事件通知。
4、配置提供者(Configuration Provider)
- 应用可通过哨兵获取当前主节点的地址,避免写死主节点地址。
⚙️ 三、哨兵模式实现原理
1、多哨兵实例分布运行,互相通过 Redis 协议通信。
2、主观下线判断(sdown):某个哨兵无法 ping 通主节点,认为它可能挂了。
3、客观下线判断(odown):多数哨兵都判断某节点挂了,才进行自动主从切换。
4、领导选举(Raft-like):多个哨兵中选出一个“leader”负责 failover。
5、通知从节点和客户端:将新的主节点通知其他从节点及客户端。
🧩 四、适用场景
场景 | 是否适合哨兵模式 |
---|---|
小型或中型系统,高可用为主 | ✅ 非常适合 |
需自动容灾,无人工干预 | ✅ 适合 |
大型复杂系统,超高并发 | ❌ 建议用 Redis Cluster |
业务对一致性要求极高 | ⚠️ 谨慎使用(因故障转移有延迟) |
🧾 五、Redis哨兵配置示例
示例拓扑结构:
3个Sentinel实例 + 1主(master) + 2从(slave)
1. redis.conf(主、从节点配置)
# 所有节点开启主从复制
# 主节点
port 6379
# 从节点
port 6380
replicaof 127.0.0.1 6379
2. sentinel.conf 配置文件(每个哨兵配置类似)
port 26379
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 10000
sentinel parallel-syncs mymaster 1
说明:
mymaster:主节点名称
127.0.0.1 6379:主节点地址
2:至少需要几个哨兵认为主节点不可达才判定为“客观下线”
3. 启动哨兵(每个都要)
redis-sentinel sentinel.conf
🧪 六、Go语言接入哨兵模式示例
我们可以使用 github.com/go-redis/redis/v8 实现 Redis Sentinel 连接:
✅ Go代码示例(含注释)
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/go-redis/redis/v8"
)
// 初始化 Redis 客户端,使用哨兵连接方式
func newSentinelRedisClient() *redis.Client {
rdb := redis.NewFailoverClient(&redis.FailoverOptions{
MasterName: "mymaster", // 与 sentinel.conf 中保持一致
SentinelAddrs: []string{":26379", ":26380", ":26381"},
DB: 0,
Password: "", // 可配置密码
})
// Ping 验证连接
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
if err := rdb.Ping(ctx).Err(); err != nil {
log.Fatalf("Redis连接失败: %v", err)
}
return rdb
}
func main() {
rdb := newSentinelRedisClient()
ctx := context.Background()
// 写入数据
if err := rdb.Set(ctx, "key1", "value1", 0).Err(); err != nil {
log.Fatal("写入失败:", err)
}
// 读取数据
val, err := rdb.Get(ctx, "key1").Result()
if err != nil {
log.Fatal("读取失败:", err)
}
fmt.Println("读取结果:", val)
}
📌 七、总结对比:哨兵 VS 集群
特性 | Sentinel 哨兵模式 | Redis Cluster |
---|---|---|
主从切换 | ✅ 自动支持 | ✅ 自动支持 |
数据分片 | ❌ 不支持 | ✅ 支持 |
实现复杂度 | ⭐ 简单 | 🚀 高 |
客户端连接 | 🧭 客户端需支持发现 | ⚠️ 更复杂 |
✅ 八、结语
Redis 哨兵模式是一个轻量级、高可用的架构解决方案,适合对高可用要求较高但架构不复杂的业务场景。结合 Go 项目,建议使用 FailoverClient 配合配置中心(如 etcd/Nacos)进行主节点动态发现。