专注于高性能网络应用开发,核心技术包括PHP、Java、GO、NodeJS等后端语言,VUE、UNI、APP等前端开发,服务器运维、数据库、实时通信、AI等领域拥有丰富经验

构建坚如磐石的Redis高可用集群:从零开始部署与配置

在当今的高并发应用架构中,Redis作为高性能的内存数据库,被广泛应用于缓存、会话存储、消息队列等场景。然而,单机Redis部署存在以下几个关键问题:

  1. 单点故障风险:单机部署一旦服务器宕机或网络中断,整个Redis服务将不可用,严重影响业务连续性。
  2. 性能瓶颈:随着业务规模增长,单机Redis的内存容量和处理能力可能成为系统瓶颈,无法满足高并发需求。
  3. 数据持久性问题:虽然Redis提供了RDB和AOF两种持久化机制,但在单机环境下,数据安全风险仍然较高。
  4. 可用性挑战:对于要求99.99%可用性的核心业务,单机Redis难以提供足够的服务保障。

为了解决这些问题,我们需要构建Redis高可用集群,确保服务的连续性、数据的安全性和系统的可扩展性。

具体可看之前的文章 Redis高可用服务架构分析与搭建的几种方案

Redis Cluster部署与配置

环境准备

假设我们使用6台服务器(3主3从)来部署Redis Cluster,每台服务器配置如下:

  • 操作系统:CentOS 7.x 或 Ubuntu 18.04+
  • Redis版本:6.2.x 或更高版本
  • 内存:至少8GB
  • 网络:千兆网卡,确保节点间网络互通

安装Redis

在每台服务器上安装Redis:

# 下载Redis源码
wget http://download.redis.io/releases/redis-6.2.5.tar.gz

# 解压并编译
tar xzf redis-6.2.5.tar.gz
cd redis-6.2.5
make

# 安装到系统
make install

配置Redis Cluster

创建Redis配置文件redis-cluster.conf,内容如下:

# 端口设置,每个节点使用不同端口(7000-7005)
port 7000

# 启用集群模式
cluster-enabled yes

# 集群配置文件,由Redis自动维护
cluster-config-file nodes-7000.conf

# 节点超时时间,单位毫秒
cluster-node-timeout 5000

# 开启AOF持久化
appendonly yes

# 设置访问密码
requirepass your_password

# 主从节点访问密码
masterauth your_password

# 绑定IP,根据实际情况修改
bind 192.168.1.100

# 后台运行
daemonize yes

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

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

注解

  • cluster-enabled yes:启用Redis Cluster模式,这是集群模式的关键配置
  • cluster-config-file:指定集群配置文件名,Redis会自动维护这个文件,记录集群状态
  • cluster-node-timeout:设置节点超时时间,超过这个时间未收到节点响应,则认为该节点故障
  • requirepassmasterauth:设置集群访问密码,提高安全性
  • 每个节点需要使用不同的端口和配置文件

启动Redis节点

在每台服务器上启动Redis实例:

# 创建数据目录和日志目录
mkdir -p /var/lib/redis/7000
mkdir -p /var/log/redis

# 启动Redis实例
redis-server /path/to/redis-cluster.conf

创建集群

使用redis-cli工具创建集群:

# 在任意一台服务器上执行以下命令
redis-cli -a your_password --cluster create \
192.168.1.100:7000 192.168.1.101:7001 192.168.1.102:7002 \
192.168.1.103:7003 192.168.1.104:7004 192.168.1.105:7005 \
--cluster-replicas 1

注解

  • -a your_password:指定Redis密码
  • --cluster create:创建集群的命令
  • 后面跟着6个节点的IP和端口,前三个将作为主节点,后三个作为从节点
  • --cluster-replicas 1:表示每个主节点分配1个从节点

执行命令后,系统会显示配置信息,输入yes确认创建集群。

验证集群状态

使用redis-cli连接集群并查看状态:

# 连接集群
redis-cli -c -h 192.168.1.100 -p 7000 -a your_password

# 查看集群信息
cluster info

# 查看节点信息
cluster nodes

基本操作示例

# 设置键值
set key1 value1

# 获取键值
get key1

# 查看键所在的槽位
cluster keyslot key1

# 查看槽位信息
cluster slots

难点讲解

1. 数据分片原理

Redis Cluster通过分片(sharding)机制将数据分散到多个节点。它将整个数据集划分为16384个哈希槽(hash slots),每个键根据CRC16算法计算出哈希值,然后对16384取模,确定所属的哈希槽。

每个节点负责一部分哈希槽,例如:

  • 节点A:0-5460号哈希槽
  • 节点B:5461-10922号哈希槽
  • 节点C:10923-16383号哈希槽

当客户端要操作某个键时,会先计算键的哈希槽,然后找到负责该哈希槽的节点进行操作。如果客户端连接的节点不负责该哈希槽,会返回MOVED重定向错误,指导客户端连接正确的节点。

2. 故障转移机制

Redis Cluster通过主从复制和哨兵机制实现高可用:

  1. 主从复制:每个主节点都有一个或多个从节点,从节点定期从主节点复制数据。
  2. 故障检测:集群中的节点通过Gossip协议互相交换状态信息,当某个主节点被标记为FAIL(故障)时,其从节点会发起选举。
  3. 故障转移:从节点选举出新的主节点,并更新集群配置,其他节点会感知到这一变化。
  4. 客户端通知:客户端在收到MOVED或ASK重定向时,会更新内部的路由表,将请求发送到正确的节点。

故障转移过程对客户端是透明的,但客户端需要支持MOVED和ASK重定向处理。

3. 集群扩容与缩容

扩容操作

  1. 添加新节点

    # 启动新的Redis实例
    redis-server /path/to/new-redis-cluster.conf
    
    # 将新节点添加到集群
    redis-cli -a your_password --cluster add-node 192.168.1.106:7006 192.168.1.100:7000
  2. 重新分片

    # 将部分哈希槽从现有节点迁移到新节点
    redis-cli -a your_password --cluster reshard 192.168.1.100:7000 \
    --cluster-from <node-id> \
    --cluster-to <new-node-id> \
    --cluster-slots 1000 \
    --cluster-yes

缩容操作

  1. 迁移哈希槽:将待删除节点的哈希槽迁移到其他节点。
  2. 移除节点

    # 从集群中移除节点
    redis-cli -a your_password --cluster del-node 192.168.1.100:7000 <node-id>

4. 客户端连接与路由

Redis Cluster客户端需要支持集群协议,能够处理MOVED和ASK重定向:

  • MOVED重定向:表示键的哈希槽已经永久迁移到其他节点,客户端应更新路由表。
  • ASK重定向:表示键的哈希槽正在迁移,客户端应先向目标节点发送ASKING命令,然后再发送操作命令。

以下是Java客户端Jedis的连接示例:

import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPoolConfig;

import java.util.HashSet;
import java.util.Set;

public class RedisClusterExample {
    public static void main(String[] args) {
        // 创建连接池配置
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxTotal(10);
        poolConfig.setMaxIdle(5);
        poolConfig.setMinIdle(1);
        
        // 设置集群节点
        Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>();
        jedisClusterNodes.add(new HostAndPort("192.168.1.100", 7000));
        jedisClusterNodes.add(new HostAndPort("192.168.1.101", 7001));
        jedisClusterNodes.add(new HostAndPort("192.168.1.102", 7002));
        jedisClusterNodes.add(new HostAndPort("192.168.1.103", 7003));
        jedisClusterNodes.add(new HostAndPort("192.168.1.104", 7004));
        jedisClusterNodes.add(new HostAndPort("192.168.1.105", 7005));
        
        // 创建JedisCluster对象
        JedisCluster jedisCluster = new JedisCluster(jedisClusterNodes, 2000, 2000, 5, "your_password", poolConfig);
        
        // 使用集群
        jedisCluster.set("key1", "value1");
        String value = jedisCluster.get("key1");
        System.out.println("key1的值: " + value);
        
        // 关闭连接
        jedisCluster.close();
    }
}

注解

  • JedisCluster会自动处理MOVED和ASK重定向,维护集群路由表
  • 连接池配置应根据实际应用场景调整,避免资源浪费或连接不足
  • 密码参数需要与Redis配置中的密码一致

总结

Redis Cluster提供了完整的高可用和分布式解决方案,通过数据分片、主从复制和自动故障转移,确保了Redis服务的高可用性和可扩展性。在实际部署过程中,需要注意以下几点:

  1. 网络稳定性:节点间的网络通信对集群稳定性至关重要,建议使用专用网络或VPC。
  2. 内存规划:合理规划每个节点的内存使用,避免内存溢出导致节点故障。
  3. 数据持久化:根据业务需求选择合适的持久化策略,平衡数据安全性和性能。
  4. 监控告警:建立完善的监控体系,及时发现并处理集群异常。
  5. 备份策略:定期备份集群数据,确保在极端情况下可以恢复数据。

通过本文的介绍,相信您已经掌握了Redis Cluster的部署与配置方法,可以根据实际业务需求构建高可用的Redis集群环境。

相关文章

macOS arm64芯片上编译Redis最新版的指南

在macOS的M1芯片上,由于架构的变化,直接编译某些软件可能会遇到一些挑战。Redis作为一款流行的开源内存中数据结构存储系统,其编译过程也不例外。本文将介绍如何在macOS arm64(M1...

Redis高可用服务架构分析与搭建的几种方案

高可用Redis架构设计与实现Redis作为一款基于内存的高性能key-value数据库,已经在许多Web应用中得到了广泛使用,通常用于存储用户会话状态、加速数据查询以及实现消息队列和发布/订阅...

PHP+Redis查询附近的人功能

在之前的博客《MySQL 查询附近的人》中,使用 MySQL 查询附近的人在用户较少时性能表现尚可。然而,随着应用用户的增多,查询性能问题开始凸显。因此,这篇文章介绍了使用 Redis 的 GE...

RediSearch简单使用教程 附PHP示例

Redisearch 是一个基于 Redis 的高性能搜索引擎,可以在 Redis 数据结构上实现全文搜索功能。下面是一个简单的教程,介绍如何使用 Redisearch 进行中文搜索,并使用 P...