Redis哨兵搭建教程
# Redis哨兵搭建教程
Redis哨兵(Sentinel)是Redis的高可用解决方案,能够自动监控、通知和故障转移。
## 前言
Redis哨兵是Redis官方提供的高可用解决方案,能够自动监控主从节点状态,在主节点故障时自动进行故障转移。本文将详细介绍如何搭建Redis哨兵集群。
## 环境准备
### 服务器规划
本文使用3台服务器搭建Redis哨兵集群:
| 服务器IP | Redis端口 | 哨兵端口 | 角色 |
|----------|-----------|----------|------|
| 192.168.1.10 | 6379 | 26379 | Master + Sentinel1 |
| 192.168.1.11 | 6379 | 26379 | Slave1 + Sentinel2 |
| 192.168.1.12 | 6379 | 26379 | Slave2 + Sentinel3 |
### 系统要求
- 操作系统:CentOS 7+ 或 Ubuntu 18.04+
- Redis版本:5.0+(建议使用6.0+)
- 内存:至少2GB RAM
- 网络:服务器之间网络互通
## 安装Redis
### 1. 安装依赖
```bash
# CentOS
yum install -y gcc make tcl
# Ubuntu
apt-get install -y build-essential tcl
```
### 2. 下载并编译Redis
```bash
cd /usr/local/src
wget http://download.redis.io/releases/redis-6.2.6.tar.gz
tar xzf redis-6.2.6.tar.gz
cd redis-6.2.6
make
make install
```
### 3. 创建目录结构
```bash
mkdir -p /etc/redis
mkdir -p /var/log/redis
mkdir -p /var/lib/redis
mkdir -p /var/run/redis
```
## 配置Redis主从复制
### Master配置文件
在192.168.1.10上创建配置文件 `/etc/redis/redis.conf`:
```bash
bind 0.0.0.0
port 6379
daemonize yes
pidfile /var/run/redis/redis.pid
logfile /var/log/redis/redis.log
dir /var/lib/redis
requirepass "your_password"
masterauth "your_password"
save 900 1
save 300 10
save 60 10000
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
```
### Slave配置文件
在192.168.1.11和192.168.1.12上创建配置文件 `/etc/redis/redis.conf`:
```bash
bind 0.0.0.0
port 6379
daemonize yes
pidfile /var/run/redis/redis.pid
logfile /var/log/redis/redis.log
dir /var/lib/redis
replicaof 192.168.1.10 6379
masterauth "your_password"
requirepass "your_password"
replica-read-only yes
replica-priority 100
save 900 1
save 300 10
save 60 10000
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
```
### 启动Redis实例
```bash
# 在所有节点上执行
redis-server /etc/redis/redis.conf
# 检查状态
redis-cli -h 192.168.1.10 -p 6379 -a "your_password" ping
redis-cli -h 192.168.1.11 -p 6379 -a "your_password" ping
redis-cli -h 192.168.1.12 -p 6379 -a "your_password" ping
```
### 验证主从复制
```bash
# 在Master上查看复制信息
redis-cli -h 192.168.1.10 -p 6379 -a "your_password" info replication
# 在Slave上查看复制信息
redis-cli -h 192.168.1.11 -p 6379 -a "your_password" info replication
```
## 配置Redis哨兵
### 哨兵配置文件
在所有3台服务器上创建哨兵配置文件 `/etc/redis/sentinel.conf`:
```bash
port 26379
daemonize yes
pidfile /var/run/redis/sentinel.pid
logfile /var/log/redis/sentinel.log
dir /var/lib/redis
# 监控主节点,quorum为2表示2个哨兵认为主节点下线才进行故障转移
sentinel monitor mymaster 192.168.1.10 6379 2
# 主节点密码
sentinel auth-pass mymaster your_password
# 30秒无响应认为下线
sentinel down-after-milliseconds mymaster 30000
# 故障转移超时时间180秒
sentinel failover-timeout mymaster 180000
# 故障转移时同时同步的从节点数量
sentinel parallel-syncs mymaster 1
```
### 启动哨兵
```bash
# 在所有节点上执行
redis-sentinel /etc/redis/sentinel.conf
# 检查哨兵状态
redis-cli -p 26379 info sentinel
```
### 验证哨兵集群
```bash
# 查看监控的主节点
redis-cli -p 26379 sentinel masters
# 查看从节点信息
redis-cli -p 26379 sentinel slaves mymaster
# 查看其他哨兵信息
redis-cli -p 26379 sentinel sentinels mymaster
```
## 故障转移测试
### 模拟Master故障
```bash
# 停止Master节点
redis-cli -h 192.168.1.10 -p 6379 -a "your_password" shutdown nosave
```
### 观察故障转移过程
```bash
# 实时查看哨兵日志
tail -f /var/log/redis/sentinel.log
```
哨兵会自动选择一个Slave升级为Master,整个过程自动完成。
### 验证新的Master
```bash
# 查看新的Master信息
redis-cli -p 26379 sentinel get-master-addr-by-name mymaster
# 连接新的Master
redis-cli -h <新Master的IP> -p 6379 -a "your_password" info replication
```
### 恢复原Master
```bash
# 重启原Master节点
redis-server /etc/redis/redis.conf
# 原Master会自动成为新Master的从节点
```
## 客户端连接
### Python客户端
```python
from redis.sentinel import Sentinel
# 配置哨兵地址
sentinel = Sentinel([
('192.168.1.10', 26379),
('192.168.1.11', 26379),
('192.168.1.12', 26379)
], socket_timeout=0.1)
# 获取主节点连接
master = sentinel.master_for('mymaster', password='your_password')
master.set('key', 'value')
# 获取从节点连接
slave = sentinel.slave_for('mymaster', password='your_password')
value = slave.get('key')
print(value)
```
### Java客户端(Jedis)
```java
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisSentinelPool;
import java.util.HashSet;
import java.util.Set;
public class RedisSentinelExample {
public static void main(String[] args) {
// 哨兵地址
Set
sentinels.add("192.168.1.10:26379");
sentinels.add("192.168.1.11:26379");
sentinels.add("192.168.1.12:26379");
// 创建连接池
JedisSentinelPool pool = new JedisSentinelPool(
"mymaster",
sentinels,
"your_password"
);
// 获取连接
Jedis jedis = null;
try {
jedis = pool.getResource();
jedis.set("key", "value");
String value = jedis.get("key");
System.out.println(value);
} finally {
if (jedis != null) {
jedis.close();
}
pool.close();
}
}
}
```
### Go客户端
```go
package main
import (
"fmt"
"github.com/go-redis/redis/v8"
"context"
)
func main() {
// 创建哨兵客户端
rdb := redis.NewFailoverClient(&redis.FailoverOptions{
MasterName: "mymaster",
SentinelAddrs: []string{
"192.168.1.10:26379",
"192.168.1.11:26379",
"192.168.1.12:26379",
},
Password: "your_password",
})
ctx := context.Background()
// 写操作
err := rdb.Set(ctx, "key", "value", 0).Err()
if err != nil {
panic(err)
}
// 读操作
val, err := rdb.Get(ctx, "key").Result()
if err != nil {
panic(err)
}
fmt.Println(val)
}
```
## 监控与维护
### 查看哨兵状态
```bash
# 查看哨兵信息
redis-cli -p 26379 info sentinel
# 查看主节点信息
redis-cli -p 26379 sentinel masters
# 查看从节点信息
redis-cli -p 26379 sentinel slaves mymaster
```
### 查看Redis性能
```bash
# 查看统计信息
redis-cli -h 192.168.1.10 -p 6379 -a "your_password" info stats
# 查看内存使用
redis-cli -h 192.168.1.10 -p 6379 -a "your_password" info memory
# 查看持久化状态
redis-cli -h 192.168.1.10 -p 6379 -a "your_password" info persistence
```
### 日志监控
```bash
# 实时查看哨兵日志
tail -f /var/log/redis/sentinel.log
# 实时查看Redis日志
tail -f /var/log/redis/redis.log
```
### 备份策略
```bash
# 定期备份RDB文件
cp /var/lib/redis/dump.rdb /backup/redis/dump_$(date +%Y%m%d).rdb
# 定期备份AOF文件
cp /var/lib/redis/appendonly.aof /backup/redis/appendonly_$(date +%Y%m%d).aof
```
## 常见问题
### 哨兵无法启动
```bash
# 检查配置文件语法
redis-sentinel /etc/redis/sentinel.conf --test-memory 1
# 检查端口是否被占用
netstat -tlnp | grep 26379
# 检查日志
cat /var/log/redis/sentinel.log
```
### 故障转移失败
```bash
# 检查quorum配置
redis-cli -p 26379 sentinel get-master-addr-by-name mymaster
# 检查从节点状态
redis-cli -h 192.168.1.11 -p 6379 info replication
# 检查网络连通性
ping 192.168.1.10
ping 192.168.1.11
ping 192.168.1.12
```
### 主从同步延迟
```bash
# 优化复制缓冲区大小
# 在redis.conf中设置:
repl-backlog-size 10mb
repl-backlog-ttl 3600
```
### 哨兵脑裂
```bash
# 增加quorum数量
sentinel monitor mymaster 192.168.1.10 6379 3
# 增加故障转移超时时间
sentinel failover-timeout mymaster 300000
```
## 最佳实践
### 部署建议
1. 哨兵数量至少3个,建议5个(奇数)
2. 哨兵应该部署在不同的物理服务器上
3. Redis和哨兵应该在同一内网
4. 每个哨兵至少需要512MB内存
### 安全建议
1. 为所有Redis实例设置强密码
2. 使用防火墙限制访问
3. 生产环境建议启用SSL加密
4. 定期更新Redis版本
### 性能优化
1. 根据业务需求选择RDB或AOF持久化
2. 合理设置maxmemory和淘汰策略
3. 调整TCP参数优化网络性能
4. 建立完善的监控告警体系
## 总结
Redis哨兵是成熟的高可用解决方案,能够有效保障Redis服务的稳定性。通过本文的介绍,你应该能够:
1. 理解Redis哨兵的架构和工作原理
2. 成功搭建Redis主从复制集群
3. 配置和部署Redis哨兵
4. 进行故障转移测试
5. 集成客户端连接哨兵
6. 进行监控和维护
7. 解决常见问题
记住:在生产环境中,务必做好充分的测试和监控,确保系统的高可用性!






