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}")

常见问题解决

  1. 如果连接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

posted on 2023-12-11 16:58  JentZhang  阅读(120)  评论(0编辑  收藏  举报