Redis集群搭建

本文涉及的产品
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
简介: Redis主从实现读写分离,提升并发能力;哨兵保障高可用,自动故障恢复;分片集群支持海量数据存储与高并发读写,三者结合构建高性能、高可用分布式缓存架构。

1.Redis主从
单节点Redis的并发能力是有上限的,要进一步提高Redis的并发能力,这里讲一种方案就是搭建主从集群,实现读写分离。
1.1.主从集群结构
下图就是一个简单的Redis主从集群结构:

如图所示,集群中有一个master节点、两个slave节点(现在叫replica)。当我们通过Redis的Java客户端访问主从集群时,应该做好路由:
● 如果是写操作,应该访问master节点,master会自动将数据同步给两个slave节点
● 如果是读操作,建议访问各个slave节点,从而分担并发压力
1.2.搭建主从集群
我们会在同一个虚拟机中利用3个Docker容器来搭建主从集群,容器信息如下:
容器名 角色 IP 映射端口
r1 master 192.168.150.101 7001
r2 slave 192.168.150.101 7002
r3 slave 192.168.150.101 7003
1.2.1.启动多个Redis实例
我们利用课前资料提供的docker-compose文件来构建主从集群:

文件内容如下:
version: "6.2.7"

services:
r1:
image: redis:6.2.7
container_name: r1
network_mode: "host"
entrypoint: ["redis-server", "--port", "7001"]
r2:
image: redis:6.2.7
container_name: r2
network_mode: "host"
entrypoint: ["redis-server", "--port", "7002"]
r3:
image: redis:6.2.7
container_name: r3
network_mode: "host"
entrypoint: ["redis-server", "--port", "7003"]
将其上传至虚拟机的/root/redis目录下:

执行命令,运行集群:
docker-compose up -d
结果:

由于采用的是host模式,我们看不到端口映射。不过能直接在宿主机通过ps命令查看到Redis进程:

1.2.2.建立集群
虽然我们启动了3个Redis实例,但是它们并没有形成主从关系。我们需要通过命令来配置主从关系:

Redis5.0以前

slaveof

Redis5.0以后

replicaof
有临时和永久两种模式:
● 永久生效:在redis.conf文件中利用slaveof命令指定master节点
● 临时生效:直接利用redis-cli控制台输入slaveof命令,指定master节点
我们测试临时模式,首先连接r2,让其以r1为master

连接r2

docker exec -it r2 redis-cli -p 7002

认r1主,也就是7001

slaveof 192.168.150.101 7001
然后连接r3,让其以r1为master

连接r3

docker exec -it r3 redis-cli -p 7003

认r1主,也就是7001

slaveof 192.168.150.101 7001
然后连接r1,查看集群状态:

连接r1

docker exec -it r1 redis-cli -p 7001

查看集群状态

info replication
结果如下:
127.0.0.1:7001> info replication

Replication

role:master
connected_slaves:2
slave0:ip=192.168.150.101,port=7002,state=online,offset=140,lag=1
slave1:ip=192.168.150.101,port=7003,state=online,offset=140,lag=1
master_failover_state:no-failover
master_replid:16d90568498908b322178ca12078114e6c518b86
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:140
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:140
可以看到,当前节点r1:7001的角色是master,有两个slave与其连接:
● slave0:port是7002,也就是r2节点
● slave1:port是7003,也就是r3节点
1.2.3.测试
依次在r1、r2、r3节点上执行下面命令:
set num 123

get num
你会发现,只有在r1这个节点上可以执行set命令(写操作)

其它两个节点只能执行get命令(读操作)。也就是说读写操作已经分离了。

2.Redis哨兵
主从结构中master节点的作用非常重要,一旦故障就会导致集群不可用。那么有什么办法能保证主从集群的高可用性呢?
2.1.哨兵集群介绍
Redis提供了哨兵(Sentinel)机制来监控主从集群监控状态,确保集群的高可用性。
哨兵集群作用原理图:

哨兵的作用如下:
● 状态监控:Sentinel 会不断检查您的master和slave是否按预期工作
● 故障恢复(failover):如果master故障,Sentinel会将一个slave提升为master。当故障实例恢复后会成为slave
● 状态通知:Sentinel充当Redis客户端的服务发现来源,当集群发生failover时,会将最新集群信息推送给Redis的客户端
2.2.搭建哨兵集群
首先,我们停掉之前的redis集群:

老版本DockerCompose

docker-compose down

新版本Docker

docker compose down
然后,我们找到课前资料提供的sentinel.conf文件:

其内容如下:
sentinel announce-ip "192.168.150.101"
sentinel monitor hmaster 192.168.150.101 7001 2
sentinel down-after-milliseconds hmaster 5000
sentinel failover-timeout hmaster 60000
说明:
● sentinel announce-ip "192.168.150.101":声明当前sentinel的ip
● sentinel monitor hmaster 192.168.150.101 7001 2:指定集群的主节点信息
○ hmaster:主节点名称,自定义,任意写
○ 192.168.150.101 7001:主节点的ip和端口
○ 2:认定master下线时的quorum值
● sentinel down-after-milliseconds hmaster 5000:声明master节点超时多久后被标记下线
● sentinel failover-timeout hmaster 60000:在第一次故障转移失败后多久再次重试
我们在虚拟机的/root/redis目录下新建3个文件夹:s1、s2、s3:

将课前资料提供的sentinel.conf文件分别拷贝一份到3个文件夹中。
接着修改docker-compose.yaml文件,内容如下:
version: "6.2.7"

services:
r1:
image: redis:6.2.7
container_name: r1
network_mode: "host"
entrypoint: ["redis-server", "--port", "7001"]
r2:
image: redis:6.2.7
container_name: r2
network_mode: "host"
entrypoint: ["redis-server", "--port", "7002", "--slaveof", "192.168.101.68", "7001"]
r3:
image: redis:6.2.7
container_name: r3
network_mode: "host"
entrypoint: ["redis-server", "--port", "7003", "--slaveof", "192.168.101.68", "7001"]
s1:
image: redis:6.2.7
container_name: s1
volumes:

  - /root/redis/s1:/etc/redis
network_mode: "host"
entrypoint: ["redis-sentinel", "/etc/redis/sentinel.conf", "--port", "27001"]

s2:
image: redis:6.2.7
container_name: s2
volumes:

  - /root/redis/s2:/etc/redis
network_mode: "host"
entrypoint: ["redis-sentinel", "/etc/redis/sentinel.conf", "--port", "27002"]

s3:
image: redis:6.2.7
container_name: s3
volumes:

  - /root/redis/s3:/etc/redis
network_mode: "host"
entrypoint: ["redis-sentinel", "/etc/redis/sentinel.conf", "--port", "27003"]

直接运行命令,启动集群:
docker-compose up -d
运行结果:

我们以s1节点为例,查看其运行日志:

Sentinel ID is 8e91bd24ea8e5eb2aee38f1cf796dcb26bb88acf

+monitor master hmaster 192.168.150.101 7001 quorum 2

  • +slave slave 192.168.150.101:7003 192.168.150.101 7003 @ hmaster 192.168.150.101 7001
  • +sentinel sentinel 5bafeb97fc16a82b431c339f67b015a51dad5e4f 192.168.150.101 27002 @ hmaster 192.168.150.101 7001
  • +sentinel sentinel 56546568a2f7977da36abd3d2d7324c6c3f06b8d 192.168.150.101 27003 @ hmaster 192.168.150.101 7001
  • +slave slave 192.168.150.101:7002 192.168.150.101 7002 @ hmaster 192.168.150.101 7001
    可以看到sentinel已经联系到了7001这个节点,并且与其它几个哨兵也建立了链接。哨兵信息如下:
    ● 27001:Sentinel ID是8e91bd24ea8e5eb2aee38f1cf796dcb26bb88acf
    ● 27002:Sentinel ID是5bafeb97fc16a82b431c339f67b015a51dad5e4f
    ● 27003:Sentinel ID是56546568a2f7977da36abd3d2d7324c6c3f06b8d
    2.3.演示failover
    接下来,我们演示一下当主节点故障时,哨兵是如何完成集群故障恢复(failover)的。
    停止r1
    docker stop r1
    登录r2,查看集群状态:

稍微等待一段时间后,会发现sentinel节点触发了failover:
继续查看集群状态发现主节点为r2

3.Redis分片集群
主从模式可以解决高可用、高并发读的问题。但依然有两个问题没有解决:
● 海量数据存储
● 高并发写
要解决这两个问题就需要用到分片集群了。分片的意思,就是把数据拆分存储到不同节点,这样整个集群的存储数据量就更大了。
Redis分片集群的结构如图:

分片集群特征:
● 集群中有多个master,每个master保存不同分片数据 ,解决海量数据存储问题
● 每个master都可以有多个slave节点 ,确保高可用
● master之间通过ping监测彼此健康状态 ,类似哨兵作用
● 客户端请求可以访问集群任意节点,最终都会被转发到数据所在节点
3.1.搭建分片集群
Redis分片集群最少也需要3个master节点,由于我们的机器性能有限,我们只给每个master配置1个slave,形成最小的分片集群:

计划部署的节点信息如下:
容器名 角色 IP 映射端口
r1 master 192.168.150.101 7001
r2 master 192.168.150.101 7002
r3 master 192.168.150.101 7003
r4 slave 192.168.150.101 7004
r5 slave 192.168.150.101 7005
r6 slave 192.168.150.101 7006
3.1.1.集群配置
分片集群中的Redis节点必须开启集群模式,一般在配置文件中添加下面参数:
port 7000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
其中有3个我们没见过的参数:
● cluster-enabled:是否开启集群模式
● cluster-config-file:集群模式的配置文件名称,无需手动创建,由集群自动维护
● cluster-node-timeout:集群中节点之间心跳超时时间
一般搭建部署集群肯定是给每个节点都配置上述参数,不过考虑到我们计划用docker-compose部署,因此可以直接在启动命令中指定参数,偷个懒。
在虚拟机的/root目录下新建一个redis-cluster目录,然后在其中新建一个docker-compose.yaml文件,内容如下:
version: "3.2"

services:
r1:
image: redis
container_name: r1
network_mode: "host"
entrypoint: ["redis-server", "--port", "7001", "--cluster-enabled", "yes", "--cluster-config-file", "node.conf"]
r2:
image: redis
container_name: r2
network_mode: "host"
entrypoint: ["redis-server", "--port", "7002", "--cluster-enabled", "yes", "--cluster-config-file", "node.conf"]
r3:
image: redis
container_name: r3
network_mode: "host"
entrypoint: ["redis-server", "--port", "7003", "--cluster-enabled", "yes", "--cluster-config-file", "node.conf"]
r4:
image: redis
container_name: r4
network_mode: "host"
entrypoint: ["redis-server", "--port", "7004", "--cluster-enabled", "yes", "--cluster-config-file", "node.conf"]
r5:
image: redis
container_name: r5
network_mode: "host"
entrypoint: ["redis-server", "--port", "7005", "--cluster-enabled", "yes", "--cluster-config-file", "node.conf"]
r6:
image: redis
container_name: r6
network_mode: "host"
entrypoint: ["redis-server", "--port", "7006", "--cluster-enabled", "yes", "--cluster-config-file", "node.conf"]
注意:使用Docker部署Redis集群,network模式必须采用host
3.1.2.启动集群
进入/root/redis-cluster目录,使用命令启动redis:
docker-compose up -d
启动成功,可以通过命令查看启动进程:
ps -ef | grep redis

结果:

root 4822 4743 0 14:29 ? 00:00:02 redis-server :7002 [cluster]
root 4827 4745 0 14:29 ? 00:00:01 redis-server
:7005 [cluster]
root 4897 4778 0 14:29 ? 00:00:01 redis-server :7004 [cluster]
root 4903 4759 0 14:29 ? 00:00:01 redis-server
:7006 [cluster]
root 4905 4775 0 14:29 ? 00:00:02 redis-server :7001 [cluster]
root 4912 4732 0 14:29 ? 00:00:01 redis-server
:7003 [cluster]
可以发现每个redis节点都以cluster模式运行。不过节点与节点之间并未建立连接。
接下来,我们使用命令创建集群:

进入任意节点容器

docker exec -it r1 bash

然后,执行命令

redis-cli --cluster create --cluster-replicas 1 \
192.168.150.101:7001 192.168.150.101:7002 192.168.150.101:7003 \
192.168.150.101:7004 192.168.150.101:7005 192.168.150.101:7006
命令说明:
● redis-cli --cluster:代表集群操作命令
● create:代表是创建集群
● --cluster-replicas 1 :指定集群中每个master的副本个数为1
○ 此时节点总数 ÷ (replicas + 1) 得到的就是master的数量n。因此节点列表中的前n个节点就是master,其它节点都是slave节点,随机分配到不同master
输入命令后控制台会弹出下面的信息:

这里展示了集群中master与slave节点分配情况,并询问你是否同意。节点信息如下:
● 7001是master,节点id后6位是da134f
● 7002是master,节点id后6位是862fa0
● 7003是master,节点id后6位是ad5083
● 7004是slave,节点id后6位是391f8b,认ad5083(7003)为master
● 7005是slave,节点id后6位是e152cd,认da134f(7001)为master
● 7006是slave,节点id后6位是4a018a,认862fa0(7002)为master
输入yes然后回车。会发现集群开始创建,并输出下列信息:

接着,我们可以通过命令查看集群状态:
redis-cli -p 7001 cluster nodes
结果:

3.2.Java客户端连接分片集群
RedisTemplate底层同样基于lettuce实现了分片集群的支持,而使用的步骤与哨兵模式基本一致,参考2.5节:
1)引入redis的starter依赖
引入SpringDataRedis的依赖:


org.springframework.boot
spring-boot-starter-data-redis

2)配置分片集群地址
与传统单点模式不同,需要配置每个redis实例的地址,如下:
spring:
redis:
cluster:
nodes:

    - 192.168.150.101:7001
    - 192.168.150.101:7002
    - 192.168.150.101:7003
    - 192.168.150.101:8001
    - 192.168.150.101:8002
    - 192.168.150.101:8003

3)配置读写分离
还要配置读写分离,让java客户端将写请求发送到master节点,读请求发送到slave节点。定义一个bean即可:
@Bean
public LettuceClientConfigurationBuilderCustomizer clientConfigurationBuilderCustomizer(){
return clientConfigurationBuilder -> clientConfigurationBuilder.readFrom(ReadFrom.REPLICA_PREFERRED);
}
这个bean中配置的就是读写策略,包括四种:
● MASTER:从主节点读取
● MASTER_PREFERRED:优先从master节点读取,master不可用才读取slave
● REPLICA:从slave节点读取
● REPLICA_PREFERRED:优先从slave节点读取,所有的slave都不可用才读取master

相关文章
|
12天前
|
数据采集 人工智能 安全
|
7天前
|
机器学习/深度学习 人工智能 前端开发
构建AI智能体:七十、小树成林,聚沙成塔:随机森林与大模型的协同进化
随机森林是一种基于决策树的集成学习算法,通过构建多棵决策树并结合它们的预测结果来提高准确性和稳定性。其核心思想包括两个随机性:Bootstrap采样(每棵树使用不同的训练子集)和特征随机选择(每棵树分裂时只考虑部分特征)。这种方法能有效处理大规模高维数据,避免过拟合,并评估特征重要性。随机森林的超参数如树的数量、最大深度等可通过网格搜索优化。该算法兼具强大预测能力和工程化优势,是机器学习中的常用基础模型。
344 164
|
6天前
|
机器学习/深度学习 自然语言处理 机器人
阿里云百炼大模型赋能|打造企业级电话智能体与智能呼叫中心完整方案
畅信达基于阿里云百炼大模型推出MVB2000V5智能呼叫中心方案,融合LLM与MRCP+WebSocket技术,实现语音识别率超95%、低延迟交互。通过电话智能体与座席助手协同,自动化处理80%咨询,降本增效显著,适配金融、电商、医疗等多行业场景。
345 155
|
7天前
|
编解码 人工智能 自然语言处理
⚽阿里云百炼通义万相 2.6 视频生成玩法手册
通义万相Wan 2.6是全球首个支持角色扮演的AI视频生成模型,可基于参考视频形象与音色生成多角色合拍、多镜头叙事的15秒长视频,实现声画同步、智能分镜,适用于影视创作、营销展示等场景。
582 4
|
15天前
|
SQL 自然语言处理 调度
Agent Skills 的一次工程实践
**本文采用 Agent Skills 实现整体智能体**,开发框架采用 AgentScope,模型使用 **qwen3-max**。Agent Skills 是 Anthropic 新推出的一种有别于mcp server的一种开发方式,用于为 AI **引入可共享的专业技能**。经验封装到**可发现、可复用的能力单元**中,每个技能以文件夹形式存在,包含特定任务的指导性说明(SKILL.md 文件)、脚本代码和资源等 。大模型可以根据需要动态加载这些技能,从而扩展自身的功能。目前不少国内外的一些框架也开始支持此种的开发方式,详细介绍如下。
1019 7