百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

Redis Cluster:分布式缓存的进阶指南

mhr18 2025-08-01 18:50 4 浏览 0 评论

在高并发、大数据量的业务场景中,单机 Redis 早已力不从心。Redis Cluster作为 Redis 官方提供的分布式解决方案,通过数据分片、主从复制和自动故障转移,完美解决了单机 Redis 的性能瓶颈和可用性问题。本文将从基础概念到实战部署,全面解析 Redis Cluster,并重点介绍在 Spring Boot 项目中的具体应用。

Redis Cluster 是什么?

Redis Cluster是 Redis 官方推出的分布式集群解决方案,专为解决单机 Redis 在存储容量、并发处理能力和高可用性上的局限性而设计。它将数据分散存储在多个节点上,每个节点负责一部分数据,同时通过主从复制机制为每个主节点配备从节点,实现了数据的分布式存储和高可用保障。



简单来说,Redis Cluster 就像一个 "数据仓库集群":多个节点分工合作,既各自保管一部分数据,又相互监督,一旦某个节点出问题,立刻有 "备用节点" 顶上,确保整个集群持续稳定运行。

为什么需要 Redis Cluster?

单机 Redis 的局限性在业务增长到一定规模后会集中爆发,而 Redis Cluster 正是为解决这些问题而生:



单机 Redis 的痛点

Redis Cluster 的解决方案

存储容量有限(受单台服务器内存限制)

数据分片到多个节点,总容量随节点数量线性增长

并发处理能力上限低

多节点分担请求,吞吐量随节点数量提升

单点故障风险高

主从复制 + 自动故障转移,节点故障不影响集群可用

扩展成本高(需停机迁移数据)

支持在线扩容,新增节点自动分担哈希槽

Redis Cluster 的工作原理

数据分片与哈希槽:数据如何分配?

Redis Cluster 采用哈希槽(Hash Slot) 机制实现数据分片,核心逻辑如下:



  • 集群预先分配 16384 个哈希槽(0-16383),每个哈希槽对应一部分数据。
  • 当存储数据时,通过公式CRC16(key) % 16384计算键对应的哈希槽,再将数据存储到负责该哈希槽的节点上。
  • 每个节点负责一部分哈希槽(如 3 个主节点可各分配 5461、5461、5462 个槽)。



这种机制的优势在于:数据分配规则简单清晰,节点增减时只需迁移哈希槽,无需重新计算所有键的位置。

节点通信与 Gossip 协议:集群如何 "沟通"?

集群中的节点通过Gossip 协议定期交换信息,包括:



  • 节点状态(在线 / 离线)
  • 节点负责的哈希槽
  • 主从节点映射关系



每个节点会随机选择几个节点发送信息,信息通过 "一传十、十传百" 的方式在集群中扩散,最终所有节点达成状态共识。

故障检测与自动故障转移:节点挂了怎么办?

  1. 故障检测:每个节点会定期向其他节点发送 PING 命令,若多次未收到 PONG 响应,则标记该节点为 "疑似下线"。当集群中超过半数的主节点认为某节点 "疑似下线" 时,该节点会被标记为 "确定下线"。
  2. 自动故障转移:被标记为下线的主节点的所有从节点会发起选举,通过 Raft 算法竞争成为新主节点。获胜的从节点升级为主节点,接管原主节点的所有哈希槽,集群自动恢复正常。

Redis Cluster 的优势

优势

具体说明

高可用性

主从复制 + 自动故障转移,单个节点故障不影响服务,可用性可达 99.99% 以上

可扩展性

支持在线扩容,从 3 节点扩展到 100 节点,无需停机,性能线性提升

高性能

数据分片到多节点,读写请求并行处理,吞吐量远超单机 Redis

数据均衡

哈希槽均匀分配,避免单节点数据过载(除非出现大量相同哈希槽的键)

Redis Cluster 的应用场景

  • 大规模缓存:电商平台的商品详情、用户信息等高频访问数据,通过 Redis Cluster 缓存,降低数据库压力。
  • 分布式会话:在微服务架构中,用 Redis Cluster 存储用户会话,实现多服务实例间的会话共享。
  • 实时计数器:如直播平台的在线人数、短视频的点赞数,通过 Redis Cluster 的原子操作实现高并发计数。
  • 消息队列:基于 Redis 的 List 结构,实现简单的分布式消息队列,处理高并发消息生产和消费。

Redis Cluster 的部署与运维(基于 Docker)

快速部署 3 主 3 从集群

步骤

操作命令

说明

1. 创建目录

mkdir -p /redis/cluster/{7001,7002,7003,7004,7005,7006}

7001-7003 为主节点,7004-7006 为从节点

2. 编写配置文件

每个目录下创建 redis.conf,关键配置:
port 7001
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes

开启集群模式,设置节点超时时间

3. 启动容器

for port in {7001..7006}; do docker run -d --name redis-$port -p $port:$port -v /redis/cluster/$port:/data redis:7.0 redis-server /data/redis.conf; done

拉取 Redis 7.0 镜像,启动 6 个容器

4. 创建集群

docker exec -it redis-7001 redis-cli --cluster create 172.17.0.2:7001 172.17.0.3:7002 172.17.0.4:7003 172.17.0.5:7004 172.17.0.6:7005 172.17.0.7:7006 --cluster-replicas 1

--cluster-replicas 1表示每个主节点配 1 个从节点

5. 验证集群

docker exec -it redis-7001 redis-cli -p 7001 cluster info

查看集群状态,确保cluster_state:ok

运维注意事项

  • 节点扩容:新增节点后,通过redis-cli --cluster reshard命令迁移哈希槽,无需停机。
  • 数据备份:定期通过bgsave命令在主节点生成 RDB 文件,或开启 AOF 持久化(性能略低但数据更安全)。
  • 故障处理:若自动故障转移失败,可手动执行cluster failover命令触发从节点升级。
  • 监控:使用 Redis Insight 或 Prometheus+Grafana 监控集群节点状态、内存使用和哈希槽分布。

Spring Boot 项目集成 Redis Cluster

1. 引入依赖

在pom.xml中添加 Redis Starter:



xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2. 配置集群信息

在application.yml中配置 Redis Cluster 节点和连接参数:



yaml

spring:
  redis:
    cluster:
      nodes:  # 集群所有节点的IP:端口
        - 192.168.1.100:7001
        - 192.168.1.100:7002
        - 192.168.1.100:7003
        - 192.168.1.100:7004
        - 192.168.1.100:7005
        - 192.168.1.100:7006
      max-redirects: 3  # 最大重定向次数(哈希槽迁移时)
    lettuce:  # 使用lettuce客户端(默认)
      pool:
        max-active: 16  # 最大连接数
        max-idle: 8     # 最大空闲连接
        min-idle: 4     # 最小空闲连接
    timeout: 3000ms    # 连接超时时间

3. 编写 Redis 工具类

java

运行

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

@Component
public class RedisClusterUtil {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    // 存值(无过期时间)
    public void set(String key, Object value) {
        redisTemplate.opsForValue().set(key, value);
    }

    // 存值(带过期时间)
    public void set(String key, Object value, long timeout, TimeUnit unit) {
        redisTemplate.opsForValue().set(key, value, timeout, unit);
    }

    // 取值
    public Object get(String key) {
        return redisTemplate.opsForValue().get(key);
    }

    // 删除键
    public Boolean delete(String key) {
        return redisTemplate.delete(key);
    }

    // 自增(计数器场景)
    public Long increment(String key, long delta) {
        return redisTemplate.opsForValue().increment(key, delta);
    }
}

4. 实战使用示例

java

运行

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;

@RestController
public class UserController {

    @Resource
    private RedisClusterUtil redisClusterUtil;

    // 缓存用户信息
    @GetMapping("/user/{id}")
    public String getUser(@PathVariable Long id) {
        // 先查缓存
        String cacheKey = "user:" + id;
        Object user = redisClusterUtil.get(cacheKey);
        if (user != null) {
            return "从缓存获取:" + user.toString();
        }
        
        // 缓存未命中,查数据库(此处模拟)
        String userName = "用户" + id;
        
        // 存入缓存,设置30分钟过期
        redisClusterUtil.set(cacheKey, userName, 30, TimeUnit.MINUTES);
        return "从数据库获取:" + userName;
    }
}

5. 注意事项

  • 键的设计:避免大量键落在同一个哈希槽(如不要用固定前缀 + 自增 ID,可通过{hashTag}强制指定哈希槽,如user:{100}:name和user:{100}:age会存在同一槽位)。
  • 批量操作:mget、mset等批量命令仅支持同一哈希槽的键,跨槽批量操作需手动分片处理。
  • 事务与 Lua:Redis Cluster 支持事务和 Lua 脚本,但需确保所有操作的键在同一哈希槽。

总结:Redis Cluster 的核心价值

Redis Cluster 通过哈希槽分片实现了数据的分布式存储,通过主从复制 + 自动故障转移保障了高可用性,完美解决了单机 Redis 的性能和扩展瓶颈。在 Spring Boot 项目中,只需简单配置即可集成,大幅降低了分布式缓存的使用门槛。



无论是中小项目的未来扩展预留,还是大型系统的高并发需求,Redis Cluster 都是值得优先选择的分布式缓存方案。关键是在实际使用中注意键的设计和批量操作的限制,充分发挥其分布式特性。

相关推荐

Java面试题及答案总结(2025版)

大家好,我是Java面试陪考员最近很多小伙伴在忙着找工作,给大家整理了一份非常全面的Java面试题及答案。涉及的内容非常全面,包含:Redis、Linux、SpringBoot、Spring、MySQ...

Java面试题及答案最全总结(2025春招版)

大家好,我是Java面试分享最近很多小伙伴在忙着找工作,给大家整理了一份非常全面的Java面试题及答案。涉及的内容非常全面,包含:Spring、MySQL、JVM、Redis、Linux、Spring...

Java面试题及答案最全总结(2025版持续更新)

大家好,我是Java面试陪考员最近很多小伙伴在忙着找工作,给大家整理了一份非常全面的Java面试题及答案。涉及的内容非常全面,包含:Spring、MySQL、JVM、Redis、Linux、Sprin...

蚂蚁金服面试题(附答案)建议收藏:经典面试题解析

前言最近编程讨论群有位小伙伴去蚂蚁金服面试了,以下是面试的真题,跟大家一起来讨论怎么回答。点击上方“捡田螺的小男孩”,选择“设为星标”,干货不断满满1.用到分布式事务嘛?为什么用这种方案,有其他方案...

测试工程师面试必问的十道题目!全答上来的直接免试

最近参加运维工程师岗位的面试,笔者把自己遇到的和网友分享的一些常见的面试问答收集整理出来了,希望能对自己和对正在准备面试的同学提供一些参考。一、Mongodb熟悉吗,一般部署几台?部署过,没有深入研究...

10次面试9次被刷?吃透这500道大厂Java高频面试题后,怒斩offer

很多Java工程师的技术不错,但是一面试就头疼,10次面试9次都是被刷,过的那次还是去了家不知名的小公司。问题就在于:面试有技巧,而你不会把自己的能力表达给面试官。应届生:你该如何准备简历,面试项目和...

java高频面试题整理

【高频常见问题】1、事务的特性原子性:即不可分割性,事务要么全部被执行,要么就全部不被执行。一致性或可串性:事务的执行使得数据库从一种正确状态转换成另一种正确状态隔离性:在事务正确提交之前,不允许把该...

2025 年最全 Java 面试题,京东后端面试面经合集,答案整理

最近京东搞了个TGT计划,针对顶尖青年技术天才,直接宣布不设薪资上限。TGT计划面向范围包括2023年10月1日到2026年9月30日毕业的海内外本硕博毕业生。时间范围还...

idGenerator测评

工作中遇到需要生成随机数的需求,看了一个个人开发的基于雪花算法的工具,今天进行了一下测评(测试)。idGenerator项目地址见:https://github.com/yitter/IdGenera...

2024年开发者必备:MacBook Pro M1 Max深度体验与高效工作流

工作机器我使用的是一台16英寸的MacBookProM1Max。这台电脑的表现堪称惊人!它是我用过的最好的MacBook,短期内我不打算更换它。性能依然出色,即使在执行任务时也几乎听不到风扇的...

StackOverflow 2022 年度调查报告

一个月前,StackOverflow开启了2022年度开发者调查,历时一个半月,在6月22日,StackOverflow正式发布了2022年度开发者调查报告。本次报告StackO...

这可能是最全面的SpringDataMongoDB开发笔记

MongoDB数据库,在最近使用越来越广泛,在这里和Java的开发者一起分享一下在Java中使用Mongodb的相关笔记。希望大家喜欢。关于MongoDB查询指令,请看我的上一篇文章。SpringD...

Mac M2 本地部署ragflow

修改配置文件Dockerfile文件ARGNEED_MIRROR=1//开启国内镜像代理docker/.envREDIS_PORT=6380//本地redis端口冲突RAGFLOW_IMA...

别再傻傻分不清!localhost、127.0.0.1、本机IP,原来大有讲究!

调试接口死活连不上?部署服务队友访问不了?八成是localhost、127.0.0.1、本机IP用混了!这三个看似都指向“自己”的东西,差之毫厘谬以千里。搞不清它们,轻则调试抓狂,重则服务裸奔。loc...

我把 Mac mini 托管到机房了:一套打败云服务器的终极方案

我把我积灰的Macmini托管到机房了,有图有真相。没想到吧?一台在家吃灰的苹果电脑,帮我省了大钱!对,就是控制了自己的服务器,省了租用云服务器的钱,重要数据还全捏在自己手里,这感觉真爽。你可...

取消回复欢迎 发表评论: