Redis Sentinel 中文教程

1. 核心概念

Redis Sentinel 是 Redis 官方提供的高可用性解决方案,主要用于监控 Redis 主从集群的健康状态,并在主节点发生故障时自动进行故障转移。

1.1 主要功能

  • 监控:持续检查主节点和从节点是否正常运行
  • 通知:当监控的节点出现问题时,向管理员或其他应用程序发送通知
  • 自动故障转移:当主节点不可用时,自动将一个从节点提升为新的主节点
  • 配置提供者:客户端可以通过 Sentinel 获取当前 Redis 主节点的地址

1.2 架构组成

  • Sentinel 节点:运行 Sentinel 服务的 Redis 实例,通常部署 3 个或更多
  • 数据节点:包括主节点和从节点,存储实际数据
  • Arbiter:用于在故障转移过程中进行投票的机制

2. 安装与配置

2.1 安装 Redis

Redis Sentinel 是 Redis 的一部分,安装 Redis 后即可使用 Sentinel 功能。

# Ubuntu/Debian 系统
apt update
apt install redis-server

# CentOS/RHEL 系统
yum install epel-release
yum install redis

# 从源码编译安装
wget https://download.redis.io/redis-stable.tar.gz
tar -xzf redis-stable.tar.gz
cd redis-stable
make
make install

2.2 配置主从复制

在部署 Sentinel 之前,需要先搭建 Redis 主从复制集群。

主节点配置 (/etc/redis/redis.conf):

# 绑定地址
bind 0.0.0.0

# 端口
port 6379

# 保护模式
protected-mode no

# 后台运行
daemonize yes

# 日志文件
logfile "/var/log/redis/redis-server.log"

# 数据目录
dir "/var/lib/redis"

# 密码(可选)
requirepass your_password

从节点配置 (/etc/redis/redis.conf):

# 绑定地址
bind 0.0.0.0

# 端口
port 6379

# 保护模式
protected-mode no

# 后台运行
daemonize yes

# 日志文件
logfile "/var/log/redis/redis-server.log"

# 数据目录
dir "/var/lib/redis"

# 密码(可选)
requirepass your_password

# 主节点地址和端口
slaveof master_ip 6379

# 主节点密码
masterauth your_password

2.3 配置 Sentinel

创建 Sentinel 配置文件 /etc/redis/sentinel.conf

# 绑定地址
bind 0.0.0.0

# 端口
port 26379

# 后台运行
daemonize yes

# 日志文件
logfile "/var/log/redis/redis-sentinel.log"

# 数据目录
dir "/var/lib/redis"

# 监控主节点
# 格式:sentinel monitor <master-name> <ip> <port> <quorum>
# quorum:判断主节点故障所需的最小 Sentinel 数量
sentinel monitor mymaster master_ip 6379 2

# 主节点密码
sentinel auth-pass mymaster your_password

# 故障转移超时时间(毫秒)
sentinel down-after-milliseconds mymaster 30000

# 故障转移后,同时向新主节点发起复制的从节点数量
sentinel parallel-syncs mymaster 1

# 故障转移超时时间
sentinel failover-timeout mymaster 180000

3. 基本使用

3.1 启动 Sentinel

# 使用配置文件启动 Sentinel
redis-sentinel /etc/redis/sentinel.conf

# 或使用 redis-server 启动
redis-server /etc/redis/sentinel.conf --sentinel

3.2 检查 Sentinel 状态

# 连接到 Sentinel
redis-cli -p 26379

# 查看 Sentinel 信息
127.0.0.1:26379> INFO sentinel

# 查看主节点状态
127.0.0.1:26379> SENTINEL master mymaster

# 查看从节点状态
127.0.0.1:26379> SENTINEL slaves mymaster

# 查看 Sentinel 状态
127.0.0.1:26379> SENTINEL sentinels mymaster

3.3 客户端连接

客户端可以通过 Sentinel 获取当前的主节点地址,然后连接到主节点进行操作。

示例代码(Node.js)

const redis = require('redis');

// 连接到 Sentinel
const sentinelClient = redis.createClient({
  sentinels: [
    { host: 'sentinel1_ip', port: 26379 },
    { host: 'sentinel2_ip', port: 26379 },
    { host: 'sentinel3_ip', port: 26379 }
  ],
  name: 'mymaster',
  password: 'your_password'
});

// 测试连接
sentinelClient.on('error', (err) => console.log('Redis Client Error', err));

sentinelClient.connect().then(() => {
  console.log('Connected to Redis via Sentinel');
  
  // 执行命令
  return sentinelClient.set('key', 'value');
}).then(() => {
  return sentinelClient.get('key');
}).then((value) => {
  console.log('Got value:', value);
  sentinelClient.disconnect();
});

4. 高级功能

4.1 手动故障转移

在某些情况下,可能需要手动触发故障转移,例如进行系统维护时:

# 连接到 Sentinel
redis-cli -p 26379

# 执行手动故障转移
127.0.0.1:26379> SENTINEL failover mymaster

4.2 配置持久化

Sentinel 会自动将配置更改持久化到配置文件中,确保重启后配置仍然有效。

4.3 监控多个主节点

可以在一个 Sentinel 配置文件中监控多个主节点:

# 监控第一个主节点
sentinel monitor master1 192.168.1.10 6379 2
sentinel auth-pass master1 password1

# 监控第二个主节点
sentinel monitor master2 192.168.1.20 6379 2
sentinel auth-pass master2 password2

5. 最佳实践

5.1 部署建议

  • Sentinel 数量:建议部署奇数个 Sentinel(3 个或 5 个),以避免脑裂问题
  • 部署位置:将 Sentinel 部署在不同的物理机器或虚拟机上,确保高可用性
  • 网络配置:确保 Sentinel 之间以及 Sentinel 与 Redis 节点之间的网络畅通
  • 防火墙:确保开放必要的端口(Redis: 6379,Sentinel: 26379)

5.2 性能优化

  • 调整监控频率:根据实际需求调整 down-after-milliseconds 参数
  • 优化故障转移速度:合理设置 failover-timeoutparallel-syncs 参数
  • 资源分配:为 Sentinel 分配足够的 CPU 和内存资源

5.3 安全配置

  • 设置密码:为 Redis 节点和 Sentinel 设置强密码
  • 限制访问:通过 bind 参数限制只接受特定 IP 的连接
  • 使用 TLS:在生产环境中启用 TLS 加密

6. 故障排查

6.1 常见问题

  • Sentinel 无法发现主节点:检查网络连接、密码配置和主节点状态
  • 故障转移失败:检查 Sentinel 数量是否足够、网络延迟是否过高
  • 脑裂问题:确保部署奇数个 Sentinel,并合理设置 quorum
  • 配置不同步:检查 Sentinel 配置文件是否正确,确保所有 Sentinel 配置一致

6.2 日志分析

Sentinel 的日志文件(/var/log/redis/redis-sentinel.log)包含了详细的操作信息,可用于排查问题:

# 查看 Sentinel 日志
tail -f /var/log/redis/redis-sentinel.log

# 搜索错误信息
grep -i error /var/log/redis/redis-sentinel.log

# 搜索故障转移相关信息
grep -i failover /var/log/redis/redis-sentinel.log

7. 实用案例

7.1 构建高可用 Redis 集群

场景:构建一个高可用的 Redis 集群,确保服务不中断。

解决方案

  1. 部署架构

    • 1 个主节点
    • 2 个从节点
    • 3 个 Sentinel 节点(部署在不同机器上)
  2. 配置步骤

    • 配置主从复制
    • 配置 Sentinel
    • 启动所有节点
  3. 测试故障转移

    • 模拟主节点故障(停止主节点服务)
    • 观察 Sentinel 日志,确认故障转移过程
    • 检查新的主节点状态
    • 重启原主节点,观察其是否成为从节点

示例配置

# 主节点配置(redis.conf)
port 6379
daemonize yes
requirepass your_strong_password

# 从节点 1 配置(redis.conf)
port 6379
daemonize yes
requirepass your_strong_password
slaveof master_ip 6379
masterauth your_strong_password

# 从节点 2 配置(redis.conf)
port 6379
daemonize yes
requirepass your_strong_password
slaveof master_ip 6379
masterauth your_strong_password

# Sentinel 配置(sentinel.conf)
port 26379
daemonize yes
sentinel monitor mymaster master_ip 6379 2
sentinel auth-pass mymaster your_strong_password
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000

7.2 与应用集成

场景:在 Node.js 应用中集成 Redis Sentinel,实现高可用的缓存服务。

解决方案

  1. 安装依赖

    npm install redis
  2. 配置连接

    const redis = require('redis');
    
    // 创建 Redis 客户端,通过 Sentinel 连接
    const redisClient = redis.createClient({
      sentinels: [
        { host: 'sentinel1', port: 26379 },
        { host: 'sentinel2', port: 26379 },
        { host: 'sentinel3', port: 26379 }
      ],
      name: 'mymaster',
      password: 'your_strong_password'
    });
    
    // 监听错误事件
    redisClient.on('error', (err) => {
      console.error('Redis error:', err);
    });
    
    // 监听重连事件
    redisClient.on('reconnecting', () => {
      console.log('Redis reconnecting...');
    });
    
    // 监听连接事件
    redisClient.on('connect', () => {
      console.log('Redis connected');
    });
    
    // 监听就绪事件
    redisClient.on('ready', () => {
      console.log('Redis ready');
    });
    
    // 连接到 Redis
    async function connectRedis() {
      try {
        await redisClient.connect();
        console.log('Successfully connected to Redis via Sentinel');
      } catch (err) {
        console.error('Failed to connect to Redis:', err);
      }
    }
    
    // 使用示例
    async function setCache(key, value, expiration = 3600) {
      try {
        await redisClient.set(key, JSON.stringify(value), {
          EX: expiration
        });
        return true;
      } catch (err) {
        console.error('Error setting cache:', err);
        return false;
      }
    }
    
    async function getCache(key) {
      try {
        const value = await redisClient.get(key);
        return value ? JSON.parse(value) : null;
      } catch (err) {
        console.error('Error getting cache:', err);
        return null;
      }
    }
    
    // 导出函数
    module.exports = {
      connectRedis,
      setCache,
      getCache
    };
  3. 使用示例

    const redisService = require('./redis-service');
    
    // 启动时连接 Redis
    redisService.connectRedis();
    
    // 设置缓存
    await redisService.setCache('user:1', { id: 1, name: '张三', email: 'zhangsan@example.com' });
    
    // 获取缓存
    const user = await redisService.getCache('user:1');
    console.log('User from cache:', user);

8. 总结

Redis Sentinel 是构建高可用 Redis 集群的关键组件,通过监控、通知和自动故障转移功能,确保 Redis 服务的持续可用性。本教程详细介绍了 Redis Sentinel 的核心概念、部署配置、使用方法和最佳实践,帮助开发者快速掌握 Redis Sentinel 的使用技巧,构建稳定可靠的 Redis 高可用集群。

在实际应用中,应根据具体需求和场景,合理配置 Sentinel 参数,确保系统的稳定性和性能。同时,定期进行故障演练,熟悉故障转移过程,以便在实际故障发生时能够快速响应和处理。

« 上一篇 ZooKeeper 教程 - 分布式协调服务 下一篇 » Redis Cluster 中文教程