欢迎光临
我们一直在努力

实现分布式读写集群(提升两台服务器的性能,支持分片存储+并行读写),Redis Cluster(Redis集群模式)并附排错过程

实现分布式读写集群(提升两台服务器的性能,支持分片存储+并行读写), Redis Cluster(Redis集群模式),而非哨兵模式。Redis Cluster会自动将数据分片存储在不同节点,同时支持读写分离和故障转移,完美适配两台服务器的需求。

核心架构说明

  • 节点规划:2台服务器(192.168.0.4/7)各部署2个Redis节点(1主1从),共2主2从的Redis Cluster集群(满足最小集群要求,每个主节点负责一部分哈希槽)。
  • 端口映射:业务仅需访问8015端口,通过Nginx反向代理+Redis Cluster客户端实现统一入口+分片访问。
  • 性能提升:数据分片存储在2个主节点,读写请求分散到不同节点,充分利用两台服务器的资源。

一、服务器规划

服务器角色端口(容器内)宿主机映射说明
192.168.0.4 Redis主节点1 6379 6379:6379 负责哈希槽0-8191
192.168.0.4 Redis从节点1(备1) 6380 6380:6379 主节点1的副本
192.168.0.7 Redis主节点2 6379 6379:6379 负责哈希槽8192-16383
192.168.0.7 Redis从节点2(备2) 6380 6380:6379 主节点2的副本
192.168.0.4 Nginx代理 80 8015:80 业务统一访问8015端口

二、配置步骤(服务器A:192.168.0.4)

1. 创建目录结构

mkdir -p /data/redis-cluster/{node1,node2,nginx}
cd /data/redis-cluster

2. 编写docker-compose.yml

version: '3.8'

services:
# Redis主节点1(192.168.0.4:6379)
redis-node1:
image: redis:7.2alpine
container_name: redisnode14
restart: always
ports:
"6379:6379"
"16379:16379" # Cluster总线端口(容器内+10000)
volumes:
./node1/data:/data
./node1/redis.conf:/etc/redis/redis.conf
command: redisserver /etc/redis/redis.conf
environment:
TZ=Asia/Shanghai
networks:
redisnet
sysctls:
net.core.somaxconn=1024

# Redis从节点1(192.168.0.4:6380)
redis-node2:
image: redis:7.2alpine
container_name: redisnode24
restart: always
ports:
"6380:6379"
"16380:16379"
volumes:
./node2/data:/data
./node2/redis.conf:/etc/redis/redis.conf
command: redisserver /etc/redis/redis.conf
environment:
TZ=Asia/Shanghai
networks:
redisnet
depends_on:
redisnode1

# Nginx代理(统一入口8015)
nginx-proxy:
image: nginx:alpine
container_name: redisnginx4
restart: always
ports:
"8015:80"
volumes:
./nginx/nginx.conf:/etc/nginx/nginx.conf
networks:
redisnet

networks:
redis-net:
driver: bridge

3. Redis节点配置(node1/redis.conf、node2/redis.conf)

两个节点配置一致(仅端口和节点ID不同,Cluster自动识别):

# 基础配置
bind 0.0.0.0
port 6379
daemonize no
pidfile /var/run/redis.pid
logfile ""
databases 16
dir /data
requirepass "123456" # 密码
masterauth "123456" # 主从同步密码

# Cluster核心配置
cluster-enabled yes # 开启Cluster模式
cluster-config-file nodes.conf # Cluster节点配置文件
cluster-node-timeout 15000 # 节点超时时间
cluster-announce-ip 192.168.0.4 # 暴露宿主机IP
cluster-announce-port 6379 # node1用6379,node2用6380
cluster-announce-bus-port 16379 # node1用16379,node2用16380

# 持久化
appendonly yes
appendfsync everysec

三、配置步骤(服务器B:192.168.0.7)

1. 创建目录结构

mkdir -p /data/redis-cluster/{node1,node2}
cd /data/redis-cluster

2. 编写docker-compose.yml

version: '3.8'

services:
# Redis主节点2(192.168.0.7:6379)
redis-node1:
image: redis:7.2alpine
container_name: redisnode17
restart: always
ports:
"6379:6379"
"16379:16379"
volumes:
./node1/data:/data
./node1/redis.conf:/etc/redis/redis.conf
command: redisserver /etc/redis/redis.conf
environment:
TZ=Asia/Shanghai
networks:
redisnet
sysctls:
net.core.somaxconn=1024

# Redis从节点2(192.168.0.7:6380)
redis-node2:
image: redis:7.2alpine
container_name: redisnode27
restart: always
ports:
"6380:6379"
"16380:16379"
volumes:
./node2/data:/data
./node2/redis.conf:/etc/redis/redis.conf
command: redisserver /etc/redis/redis.conf
environment:
TZ=Asia/Shanghai
networks:
redisnet
depends_on:
redisnode1

networks:
redis-net:
driver: bridge

3. Redis节点配置(node1/redis.conf、node2/redis.conf)

仅修改cluster-announce-ip为192.168.0.7,其余与服务器A一致:

cluster-announce-ip 192.168.0.7 # 服务器B的IP
cluster-announce-port 6379 # node1用6379,node2用6380
cluster-announce-bus-port 16379 # node1用16379,node2用16380

四、Nginx配置(服务器A:nginx/nginx.conf)

实现8015端口统一代理到Cluster所有主节点:

worker_processes auto;
events {
worker_connections 1024;
}

stream { # Redis是TCP协议,用stream模块代理
upstream redis-cluster {
server 192.168.0.4:6379; # 主节点1
server 192.168.0.7:6379; # 主节点2
}

server {
listen 80; # 映射到宿主机8015
proxy_pass redis-cluster;
proxy_timeout 30s;
proxy_connect_timeout 5s;
}
}

http {
server {
listen 80;
server_name localhost;
return 403; # 防止HTTP访问
}
}

五、启动并初始化Cluster

1. 启动所有节点

# 服务器A
cd /data/redis-cluster && docker-compose up -d

# 服务器B
cd /data/redis-cluster && docker-compose up -d

这里启动的时候我发现我nginx起不来
在这里插入图片描述
经过查看日志排查:
在这里插入图片描述
他说我的80端口被占用,这里需要修改容器的80端口
直接修改nginx配置文件和docker-compose文件中对应的nginx,再启动就正常了
在这里插入图片描述

2. 初始化Cluster集群

在任意服务器执行(需安装Redis客户端,或进入容器执行):

# 进入服务器A的node1容器
docker exec -it redis-node1-4 redis-cli -a 123456

# 创建Cluster(2主2从,主节点为4:6379和7:6379,从节点为4:6380和7:6380)
127.0.0.1:6379> cluster create 192.168.0.4:6379 192.168.0.7:6379 192.168.0.4:6380 192.168.0.7:6380 –cluster-replicas 1 –cluster-yes

3. 验证Cluster状态

redis-cli -h 192.168.0.4 -p 6379 -a 123456 cluster info
# 输出cluster_state:ok表示集群正常

redis-cli -h 192.168.0.4 -p 6379 -a 123456 cluster nodes
# 查看节点角色和哈希槽分配(主节点分别持有0-8191和8192-16383)

六、业务访问方式

1. 通过8015端口访问(推荐)

业务连接192.168.0.4:8015,使用Redis Cluster客户端(自动分片读写):

Python示例(redis-py-cluster)

from rediscluster import RedisCluster

# 配置Cluster节点(通过8015代理)
startup_nodes = [{"host": "192.168.0.4", "port": 8015}]
rc = RedisCluster(
startup_nodes=startup_nodes,
password="123456",
decode_responses=True,
skip_full_coverage_check=True # 跳过全槽位检查(2主节点已覆盖所有槽位)
)

# 测试分片读写
rc.set("key1", "value1") # 自动路由到某主节点
rc.set("key2", "value2")
print(rc.get("key1"))
print(rc.get("key2"))

Java示例(JedisCluster)

Set<HostAndPort> nodes = new HashSet<>();
nodes.add(new HostAndPort("192.168.0.4", 8015));

JedisPoolConfig poolConfig = new JedisPoolConfig();
JedisCluster jedisCluster = new JedisCluster(nodes, Protocol.DEFAULT_TIMEOUT, Protocol.DEFAULT_TIMEOUT, "123456", poolConfig);

jedisCluster.set("key1", "value1");
System.out.println(jedisCluster.get("key1"));

七、核心优势

  • 性能提升:数据分片存储在2个主节点,读写请求并行处理,充分利用两台服务器的CPU/内存。
  • 高可用:每个主节点有从节点备份,主节点故障时自动提升从节点为主,业务无感。
  • 统一入口:业务仅需访问8015端口,无需关心集群内部节点。
  • 弹性扩展:后续可增加服务器,扩容主节点数量,进一步提升性能。
  • 关键注意事项

  • Cluster总线端口:需开放16379/16380端口(容器内总线端口),否则节点间无法通信。
  • 客户端支持:必须使用Redis Cluster专用客户端(如redis-py-cluster、JedisCluster),普通客户端无法分片。
  • 数据分片规则:Redis根据CRC16(key) % 16384分配哈希槽,若需指定key到某节点,可使用key{tag}格式(如user{1001}:name)。
  • 此方案通过Redis Cluster实现分布式读写集群,完美利用两台服务器的性能,同时满足业务仅访问8015端口的需求!

    赞(0)
    未经允许不得转载:171主机测评 » 实现分布式读写集群(提升两台服务器的性能,支持分片存储+并行读写),Redis Cluster(Redis集群模式)并附排错过程
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址