docker swarm 部署一主两从的redis集群
docker-compose文件准备
- docker-compose-redis-cluster.yml
version: '3.8'
services:
redis-master:
image: redis
command: redis-server --requirepass your_password --appendonly yes --cluster-enabled yes --cluster-config-file /data/nodes.conf
deploy:
replicas: 1
placement:
constraints:
- node.labels.redis.replica == 1
restart_policy:
condition: on-failure
networks:
- redis-net
ports:
- "6379:6379" # 添加端口映射
volumes:
- redis-master-data:/data
redis-slave1:
image: redis
command: redis-server --requirepass your_password --slaveof redis-master 6379 --masterauth your_password
deploy:
replicas: 1
placement:
constraints:
- node.labels.redis.replica == 2
restart_policy:
condition: on-failure
networks:
- redis-net
volumes:
- redis-slave1-data:/data
redis-slave2:
image: redis
command: redis-server --requirepass your_password --slaveof redis-master 6379 --masterauth your_password
deploy:
replicas: 1
placement:
constraints:
- node.labels.redis.replica == 3
restart_policy:
condition: on-failure
networks:
- redis-net
volumes:
- redis-slave2-data:/data
networks:
redis-net:
external: true # 用已经创建好的网络
volumes:
redis-master-data:
redis-slave1-data:
redis-slave2-data:
创建专用Swarm网络
docker network create --driver overlay redis-net
给node打标签
docker node update --label-add redis.replica=1 node1
docker node update --label-add redis.replica=2 node2
docker node update --label-add redis.replica=3 node3
部署
docker stack deploy -c docker-compose-redis-cluster.yml redis
验证
- 在master节点增加key
- 在从节点的redis中查看有没有key
redis-cli -h redis-slave2 -p 6379 -a your_password
keys *
使用Python连接Redis集群
- 安装redis-py-cluster库包
pip install redis-py-cluster
- demo.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Time:2023/12/11 17:11
# @Software:PyCharm
__author__ = "JentZhang"
import random
from rediscluster import RedisCluster
from rediscluster.connection import ClusterConnectionPool
pwd = "pwd"
# Redis 集群的节点配置
startup_nodes = [
{"host": "172.25.114.9", "port": "6379"},
{"host": "172.25.114.114", "port": "6389"},
{"host": "172.25.114.115", "port": "6399"},
]
# 直连
# cluster = RedisCluster(startup_nodes=startup_nodes, password=pwd, decode_responses=True)
# 创建 ClusterConnectionPool
pool = ClusterConnectionPool(startup_nodes=startup_nodes, password=pwd, decode_responses=True)
# 创建 Redis 集群连接
cluster = RedisCluster(connection_pool=pool)
# 示例:在 Redis 主节点上设置一个键值对
cluster.set("example_key", random.randint(0, 999))
# 示例:从 Redis 从节点上获取键的值
value = cluster.get("example_key")
print(f"Value from cluster: {value}")
常见问题解决
- 如果连接redis集群报错:
Redis cluster add node fails with [ERR] Not all 16384 slots are covered by nodes
这个往往是由于主node移除了,但是并没有移除node上面的slot,从而导致了slot总数没有达到16384,其实也就是slots分布不正确。所以在删除节点的时候一定要注意删除的是否是Master主节点。
- 使用命令修复主节点slots
# 检查sloats
# redis-cli --cluster check host:port -a password
redis-cli --cluster check 127.0.0.1:6379
# 修复slots
# redis-cli --cluster fix host:port -a password
redis-cli --cluster fix 127.0.0.1:6379
# 重新分配slot
# redis-cli --cluster reshar host:port -a password
redis-cli --cluster reshard 127.0.0.1:6379
好记性不如烂笔头!