# 哨兵模式配置

URL: https://caijiao.org/redis/07-security/03-sentinel
Source: docs/redis/07-security/03-sentinel.md
Description: Redis 哨兵模式配置帮助用户实现 Redis 高可用性，自动故障转移，并监控 Redis 实例的状态。

Redis 哨兵模式（Redis Sentinel）是一种用于高可用性和自动故障转移的机制。哨兵模式能够监控主节点和从节点的状态，自动进行故障转移，并提供客户端连接管理。通过哨兵模式，您可以确保 Redis 集群在出现主节点故障时能够自动切换到备用节点，从而保证 Redis 服务的持续可用性。

## 1. 哨兵基本配置

### 1.1 启动 Redis 哨兵

Redis 哨兵是一个独立的进程，负责监控主节点和从节点的健康状态。当主节点出现故障时，哨兵会自动选举新的主节点并进行故障转移。哨兵并不直接处理客户端请求，而是通过监控 Redis 实例的状态来协调集群中的数据同步和主从切换。

您可以通过以下命令启动 Redis 哨兵：

```bash
redis-server /path/to/sentinel.conf --sentinel
```

### 1.2 配置哨兵文件

哨兵的配置通常存储在一个单独的配置文件（例如 `sentinel.conf`）中。以下是一些常见的哨兵配置项。

```txt
# 指定哨兵要监控的主节点
sentinel monitor mymaster <master-ip> <master-port> 2

# 设置故障转移触发的最大时长（秒）
sentinel down-after-milliseconds mymaster 30000

# 设置哨兵投票时的等待时间（秒）
sentinel failover-timeout mymaster 180000

# 设置哨兵的通知脚本路径
sentinel notification-script mymaster /path/to/notify.sh

# 设置哨兵的客户端连接脚本路径
sentinel client-reconfig-script mymaster /path/to/reconfig.sh
```

### 1.3 关键配置项说明

- `sentinel monitor`: 指定哨兵要监控的主节点。参数中 `mymaster` 是主节点的名字，`<master-ip>` 是主节点的 IP 地址，`<master-port>` 是主节点的端口，`2` 表示监控主节点的哨兵数量阈值，表示至少需要 2 个哨兵确认主节点故障才能触发故障转移。

- `sentinel down-after-milliseconds`: 定义当主节点下线（无响应）时，哨兵等待的时间。默认情况下，这个值为 30 秒。

- `sentinel failover-timeout`: 定义哨兵触发故障转移所需的时间（毫秒）。当主节点不可用时，哨兵将在此时间后开始进行故障转移。

- `sentinel notification-script`: 指定故障转移或事件通知时执行的脚本路径。您可以根据自己的需要编写该脚本进行报警或其他操作。

- `sentinel client-reconfig-script`: 当故障转移完成后，客户端的配置将被重新配置，指定此脚本可以执行某些操作。

## 2. 启动多个哨兵

为了确保高可用性，建议至少启动三个哨兵节点来监控 Redis 集群。通过增加哨兵数量，您可以避免因单点故障导致的监控失效。

启动哨兵时，可以通过不同的配置文件和不同的端口启动多个哨兵实例：

```bash
redis-server /path/to/sentinel1.conf --sentinel
redis-server /path/to/sentinel2.conf --sentinel
redis-server /path/to/sentinel3.conf --sentinel
```

每个哨兵实例将监控主节点的状态，并通过投票机制进行故障转移。当大多数哨兵认为主节点不可用时，才会启动故障转移过程。

## 3. 哨兵的故障转移

当 Redis 主节点出现故障时，哨兵会自动进行故障转移，选举一个从节点作为新的主节点。故障转移的过程如下：

1. 哨兵检测到主节点不可用（通过 `sentinel down-after-milliseconds` 配置项指定的时间）。
2. 哨兵通过投票机制确认主节点故障。当大多数哨兵达成共识时，故障转移会开始。
3. 哨兵选择一个从节点作为新的主节点，并将其提升为主节点。
4. 其他的从节点会开始同步新的主节点。
5. 客户端会收到新的主节点信息，重新连接新的主节点。

### 3.1 哨兵选举过程

- 每个哨兵都可以为故障转移过程投票。
- 故障转移需要大多数哨兵同意，才能执行。只有在多数哨兵认为主节点故障时，故障转移才会开始。
- 在故障转移的过程中，哨兵会通过 `RECONFIGURE` 命令通知客户端更新主节点的信息。

## 4. 客户端连接到 Redis 哨兵模式

在哨兵模式下，客户端需要连接到哨兵节点来获取当前的主节点信息。Redis 提供了 `sentinel` 命令来帮助客户端获取主节点的地址。

### 4.1 使用 `sentinel get-master-addr-by-name` 获取主节点地址

客户端可以使用 `sentinel get-master-addr-by-name` 命令来获取主节点的 IP 和端口：

```bash
SENTINEL get-master-addr-by-name mymaster
```

此命令将返回当前主节点的 IP 和端口。如果发生故障转移，哨兵会自动返回新的主节点信息。

### 4.2 使用 `sentinel slaves` 获取从节点地址

您还可以使用 `sentinel slaves` 命令获取与主节点关联的所有从节点信息：

```bash
SENTINEL slaves mymaster
```

该命令将返回所有从节点的 IP 和端口。

## 5. 哨兵故障转移后的恢复

如果 Redis 主节点因故障被停用，并且哨兵进行了故障转移，您可以在恢复主节点后，通过手动将其重新配置为从节点来恢复原有的主从结构。

1. 在恢复后的主节点上，使用 `SLAVEOF` 命令将其设置为从节点：

   ```bash
   SLAVEOF <new-master-ip> <new-master-port>
   ```

2. 主节点恢复为从节点后，Redis 集群的其他节点会自动进行数据同步。

3. 如果希望将该节点重新设置为主节点，可以手动停止其他哨兵进行的故障转移，并将该节点提升为主节点。

## 6. 常见问题及解决方案

### 6.1 哨兵无法选举新的主节点

如果哨兵无法成功选举新的主节点，可能是由于以下原因：

- 哨兵数量不足，导致无法获得多数投票。
- 哨兵监控的主节点 IP 地址错误。
- 哨兵配置文件中存在错误，导致哨兵无法正确启动。

### 6.2 故障转移后客户端未自动切换

客户端可能没有正确获取新的主节点信息，导致无法连接到新的主节点。确保客户端实现了 `sentinel get-master-addr-by-name` 机制，并在主节点切换后及时更新连接。

### 6.3 哨兵监控的主节点不可达

如果 Redis 主节点在防火墙或网络配置中被阻止，哨兵将无法监控主节点的状态。确保网络通信正常，并且哨兵能够访问主节点。

## 总结

通过配置 Redis 哨兵模式，您可以实现 Redis 的高可用性和自动故障转移，确保在主节点发生故障时，Redis 集群能够继续正常运行。合理配置哨兵，增加哨兵实例数量，并确保客户端能够及时获取最新的主节点信息，是确保 Redis 集群高可用性的关键。
