Redis 高可用集群搭建与优化实践

艺帆风顺 发布于 2025-04-07 23 次阅读


在分布式系统中,缓存技术用于提升性能和响应速度。

Redis 作为一款高性能的键值存储系统,广泛应用于缓存、消息队列和会话管理等场景。随着业务规模的扩大,单机 Redis 的性能和可用性逐渐无法满足需求。

因此,搭建高可用的 Redis 集群可以解决这一问题。我将详细介绍 Redis 集群的两种常见方案——哨兵模式高可用集群模式并重点探讨 Redis 高可用集群的搭建过程、Java 客户端操作方式以及集群的原理分析

一、Redis 集群方案对比

一)哨兵模式

在 Redis 早期版本中,哨兵(Sentinel)模式是实现高可用的主要方式。哨兵通过监控主节点(master)的状态,在主节点发生故障时自动触发主从切换,将某个从节点(slave)提升为新的主节点。

然而,哨兵模式存在以下局限性:

  1. 配置复杂:哨兵的配置较为繁琐,需要手动配置哨兵节点和主从节点的关系。

  2. 性能瓶颈:在主从切换瞬间,可能会导致访问中断。

  3. 并发能力有限:哨兵模式只有一个主节点对外提供服务,无法支持高并发。

  4. 单节点内存限制主节点内存不宜过大,否则会影响持久化文件的大小和主从同步效率。

哨兵模式架构图

(二)高可用集群模式

Redis 集群是一种分布式架构,由多个主从节点组成,具备复制、高可用和分片特性

与哨兵模式相比,Redis 集群具有以下显著优势:

  1. 无需哨兵:集群模式下,节点移除和故障转移无需依赖哨兵,简化了配置。

  2. 水平扩展:集群没有中心节点,支持水平扩展,官方推荐最多扩展到 1000 个节点。

  3. 高性能和高可用性:集群模式的性能和可用性优于哨兵模式。

  4. 配置简单:集群的配置过程较为简单,易于维护

高可用集群架构图

二、Redis 高可用集群搭建

(一)集群架构设计

为了保证高可用性,Redis 集群至少需要三个主节点。本文以三台机器为例,每台机器部署一主一从,共六个 Redis 实例。每个主节点负责一部分槽位(slots),槽位的总数为 16384 个。

(二)搭建步骤

1. 创建目录结构

在第一台机器的 /usr/local 目录下创建 redis-cluster 文件夹,并在其下创建两个子文件夹 7001 和 7004,分别用于存放主节点和从节点的配置文件和数据。

mkdir -p /usr/local/redis-clustermkdir 7001 7004

2. 修改配置文件

将 redis.conf 配置文件复制到 7001 目录下,并修改以下配置:

daemonize yesport 7001pidfile /var/run/redis_7001.piddir /usr/local/redis-cluster/7001/cluster-enabled yescluster-config-file nodes-7001.confcluster-node-timeout 10000protected-mode noappendonly yesrequirepass mypasswordmasterauth mypassword

其中,cluster-enabled 开启集群模式,cluster-config-file 指定集群节点信息文件,cluster-node-timeout 设置节点超时时间

3. 复制配置文件

将修改后的配置文件复制到 7004 目录下,并修改端口号等配置项。对于其他两台机器,分别使用 7002 和 70057003 和 7006 作为端口号。

4. 启动 Redis 实例

分别启动六个 Redis 实例,并检查是否启动成功:

/usr/local/redis-5.0.3/src/redis-server /usr/local/redis-cluster/700*/redis.confps -ef | grep redis

5. 创建集群

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

/usr/local/redis-5.0.3/src/redis-cli -a mypassword --cluster create --cluster-replicas 1 192.168.1.101:7001 192.168.1.102:7002 192.168.1.103:7003 192.168.1.101:7004 192.168.1.102:7005 192.168.1.103:7006

其中,--cluster-replicas 1 表示每个主节点有一个从节点。

6. 验证集群

连接任意一个节点并验证集群状态:

/usr/local/redis-5.0.3/src/redis-cli -a mypassword -c -h 192.168.1.101 -p 7001cluster infocluster nodes

(三)集群搭建流程图

三、Java 客户端操作 Redis 集群

(一)依赖引入

使用 Jedis 客户端操作 Redis 集群,需在项目中添加以下依赖:

dependency>    groupId>redis.clientsgroupId>    artifactId>jedisartifactId>    version>3.6.0version>dependency>

(二)代码示例

以下是一个简单的 Java 代码示例,用于连接和操作 Redis 集群:

import redis.clients.jedis.HostAndPort;import redis.clients.jedis.JedisCluster;import java.util.HashSet;import java.util.Set;public class JedisClusterDemo {    public static void main(String[] args) {        Set nodes = new HashSet();        nodes.add(new HostAndPort("192.168.1.101"7001));        nodes.add(new HostAndPort("192.168.1.102"7002));        nodes.add(new HostAndPort("192.168.1.103"7003));        nodes.add(new HostAndPort("192.168.1.101"7004));        nodes.add(new HostAndPort("192.168.1.102"7005));        nodes.add(new HostAndPort("192.168.1.103"7006));        try (JedisCluster jedisCluster = new JedisCluster(nodes, 6000500010"mypassword")) {            jedisCluster.set("testKey""testValue");            System.out.println("Retrieved value: " + jedisCluster.get("testKey"));        } catch (Exception e) {            e.printStackTrace();        }    }}

(三)Spring Boot 整合

在 Spring Boot 项目中,可以通过以下配置整合 Redis 集群:

spring:  redis:    database: 0    timeout: 3000    password: mypassword    cluster:      nodes: 192.168.1.101:7001,192.168.1.102:7002,192.168.1.103:7003,192.168.1.101:7004,192.168.1.102:7005,192.168.1.103:7006    lettuce:      pool:        max-idle: 50        min-idle: 10        max-active: 100        max-wait: 1000

(四)Java 操作流程图

四、Redis 集群原理分析

(一)槽位机制

Redis Cluster 将所有数据划分为 16384 个槽位(slots),每个节点负责一部分槽位。

客户端通过 CRC16 算法对 key 进行哈希,然后对 16384 取模,确定 key 所在的槽位:

HASH_SLOT = CRC16(key) mod 16384

客户端连接集群时会缓存槽位信息,若槽位信息发生变化,客户端会通过跳转指令(ASK 或 MOVED)更新本地缓存。

槽位分配示意图

(二)节点间通信机制

Redis Cluster 采用 Gossip 协议进行节点间通信,维护集群的元数据。Gossip 协议包含以下几种消息:

  1. meet:新节点加入集群时,其他节点通过 meet 消息将其纳入集群。

  2. ping:节点定期发送 ping 消息,包含自身状态和元数据。

  3. pong:对 ping 和 meet 消息的响应,用于信息广播和更新。

  4. fail:节点检测到其他节点故障时,发送 fail 消息通知其他节点。

Gossip 协议通信流程图

(三)网络抖动处理

为避免网络抖动导致的误判,Redis Cluster 引入了 cluster-node-timeout 参数。

当节点在指定时间内持续失联时,才会认定该节点故障并触发主从切换。

网络抖动处理流程图

五、总结

Redis 集群通过槽位机制和 Gossip 协议,实现了高性能、高可用的分布式存储架构。

相比哨兵模式,集群模式在扩展性和并发能力上具有显著优势。