云原生 | Docker - [Redis 集群搭建]

§1 镜像

docker pull redis:6.0.8

§2 主机目录

目录层级遵循

${prefix}/cluster/host/xx

如:

  • /docker/redis/cluster_01/master_01/conf
  • /docker/redis/cluster_01/master_01/data
  • /docker/redis/cluster_01/slave_01/conf
  • /docker/redis/cluster_01/slave_01/data

§3 集群部署

启动

docker run -d --privileged=true \
  --name redis-node-01 --net host \
   -v /docker/redis/cluster_01/node_01/data:/data \
   redis:6.0.8 \
   --cluster-enabled yes --appendonly yes --port 6381
   
docker run -d --privileged=true \
  --name redis-node-02 --net host \
   -v /docker/redis/cluster_01/node_02/data:/data \
   redis:6.0.8 \
   --cluster-enabled yes --appendonly yes --port 6382
   
docker run -d --privileged=true \
  --name redis-node-03 --net host \
   -v /docker/redis/cluster_01/node_03/data:/data \
   redis:6.0.8 \
   --cluster-enabled yes --appendonly yes --port 6383
   
docker run -d --privileged=true \
  --name redis-node-04 --net host \
   -v /docker/redis/cluster_01/node_04/data:/data \
   redis:6.0.8 \
   --cluster-enabled yes --appendonly yes --port 6384
   
docker run -d --privileged=true \
  --name redis-node-05 --net host \
   -v /docker/redis/cluster_01/node_05/data:/data \
   redis:6.0.8 \
   --cluster-enabled yes --appendonly yes --port 6385
   
docker run -d --privileged=true \
  --name redis-node-06 --net host \
   -v /docker/redis/cluster_01/node_06/data:/data \
   redis:6.0.8 \
   --cluster-enabled yes --appendonly yes --port 6386

参数说明

  • -d
    redis 作为服务后台运行

  • –name
    redis 节点名字

  • net host
    容器网络模式,使用宿主机 IP 和端口
    此模式下不能使用 -p 或 -P 指定端口
    否则会出现下面警告,配置也不会生效

    Published ports are discarded when using host network mode
    
  • –privileged=true
    获取宿主机 root 权限

  • -v
    添加数据卷挂载

  • –cluster-enabled
    开启 redis 集群

  • appendonly yes
    开启 redis 持久化

  • –port
    指定 redis 节点的端口
    配合 -net host 指定端口

主从配置
任选一个 docker 节点,进入容器,通过下面 reids-cli 配置集群

redis-cli --cluster create 192.168.3.11:6381 192.168.3.11:6382 192.168.3.11:6383 192.168.3.11:6384 192.168.3.11:6385 192.168.3.11:6386 --cluster-replicas 1

参数说明

  • –cluster create
    集群中所有 redis 节点的 ip 端口
  • –cluster-replicas
    集群中备份数量
    相当于附属每个 master 的 slave 的数量

集群配置效果如下图
hash 槽 相关说明见连接
在这里插入图片描述
注意 这里有一步确认,需要输入后看到下图红框才算成功
在这里插入图片描述

注意

  • node is not empty

    [ERR] Node 192.168.3.11:6381 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.
    

    说明对应节点的存储位置下有数据,需要删除或移动。
    按上面示例的配置搭建时,可以使用下面指令清理

    rm -rf /docker/redis/cluster_01
    
  • redis-cli --cluster create 时,cluster node 列表务必核对清楚,否则容易莫名其妙少一个节点

  • redis-cli --cluster create 时,中间有一步交互确认,需要键入 yes,否则集群搭建不起来

  • (error) MOVED

    (error) MOVED 15495 192.168.3.11:6383
    

    集群模式下,登录 redis-cli 需要添加 -c 参数,如下所示

    redis-cli -c -p 6381
    

    因为 redis 依赖 hash 槽,对 key 进行操作时会先计算 hash 槽,并移动到此 hash 对应的节点上
    示例中报错信息里的 15495 即 hash 槽位,192.168.3.11:6383 即对应节点
    没有 -c 参数会使移动失败,因此报错

§4 集群容错和扩容缩容

§4.1 容错

参考上面示例中 redis-cli --cluster ckeck 的输出,此时 redis 集群的结构如下图所示
在这里插入图片描述
在上面集群中

  • 若一个 master 挂了,如 6381,则其 slave(即 6385) 顶替其为 master,且持有与原 master 一致的数据
  • 若挂掉的 master 复活,则已经顶替为 master 的 slave 身份不变,复活的 master 身份变为 slave
§4.2 扩容

运行新 redis nodes

docker run -d --privileged=true \
  --name redis-node-07 --net host \
   -v /docker/redis/cluster_01/node_07/data:/data \
   redis:6.0.8 \
   --cluster-enabled yes --appendonly yes --port 6387
   
docker run -d --privileged=true \
  --name redis-node-08 --net host \
   -v /docker/redis/cluster_01/node_08/data:/data \
   redis:6.0.8 \
   --cluster-enabled yes --appendonly yes --port 6388

在这里插入图片描述

进入新节点容器,分别以主从身份将新节点加入集群

docker exec -it 129eb34dcf09 /bin/bash
redis-cli --cluster add-node 192.168.3.11:6387 192.168.3.11:6381
exit

docker exec -it 15e47f2a1bb5 /bin/bash
redis-cli --cluster add-node 192.168.3.11:6388 192.168.3.11:6381 --cluster-slave  --cluster-master-id 14b47d80f327d499820def9bdf286c498f03f653
exit

在这里插入图片描述
在这里插入图片描述

==任意容器中查看集群状态 ==

redis-cli --cluster check 192.168.3.11:6381

在这里插入图片描述

重新分配 hash 槽
此时无法使用 redis-cli --cluster rebalance 重新分配 hash 槽,因为所有节点的 hash 槽占用率都很低
因此使用 redis-cli --cluster reshard 命令

在这里插入图片描述
说明:

  • 可以使用任意集群中的节点进行 hash 槽的重分配
  • 第一步需要确认分配 hash 槽的数量
    通常 16384 / 集群中master个数 即可
  • 第二步输入接受 hash 槽的 node 的 id
  • 第三步确认 hash 槽来源,
    • 输入 all示例中选择
      可以从所有有 hash 槽的 master 节点均匀让渡 hash 槽给新节点,其他节点均分第一步填写的数值
    • 输入 node-id-1、回车、node-id-2、回车……、done
      从键入的 id 的节点让渡第一步填写的数值的 hash 槽给新节点
      可以精准控制每个节点让渡多少 hash 槽给新节点,但通常需要依次对每个原有节点进行操作以完成整个分配过程
      也可以一次输入多个节点,也可以使输入 id 的节点均分第一步中填写的数值
  • 第四步是一个确认,询问是否按分析的结果执行分配,输入 yes 即可

使用下面指令查询分配结果

redis-cli --cluster check 192.168.3.11:6381

可以看到现在是 4 个 master 均分所有 hash 槽,
且每个扩容前的节点在自己的 hash 槽区间上从开头(左侧)截取所需数量的 hash 槽进行让渡
新节点(6387) 持有的 hash 槽由 3 个区间段组成

在这里插入图片描述

§4.3 缩容

以移除集群中 6387/6388 两个节点为例

重新分配 hash 槽

root@msi-linux7:/data# redis-cli --cluster reshard 192.168.3.11:6381

在这里插入图片描述
说明:

  • 可以使用任意集群中的节点进行 hash 槽的重分配

  • 第一步需要确认分配 hash 槽的数量
    示例中是重新分配待移除节点上的所有 hash 槽

  • 第二步输入接受 hash 槽的 node 的 id
    示例中为了演示方便都用 6381 节点接受
    也可以分多次分配

  • 第三步确认 hash 槽来源,
    要移除 6387 上的 hash 槽,所以填写 6387 的 node id
    然后输入 done 完成

  • 第四步是一个确认,询问是否按分析的结果执行分配,输入 yes 即可

检查重新分配结果

redis-cli --cluster check 192.168.3.11:6381

在这里插入图片描述
可见待删除的节点 6387 已经没有 hash 槽了
同时,原本 6387 的 slave 已经过继给了 6381

删除节点

redis-cli --cluster del-node 192.168.3.11:6381 14b47d80f327d499820def9bdf286c498f03f653
redis-cli --cluster del-node 192.168.3.11:6381 886f415bc4d296a7d8794a88f47e7e9f35f7a2a9

在这里插入图片描述
如果有需要,可以重新分配 hash 槽,使三个节点负载均衡
或者在一开始分配时,就考虑此问题

重分配 hash 槽和节点删除的顺序问题
有些教程和帖子上的顺序为

  • 删除从节点 6388
  • 重分配 hash 槽
  • 删除主节点 6387

因作者实践经验有限,不能验证,但考虑
若先删除从节点,在 hash 槽重分配完成前,主节点 6387 挂了的情况时可能存在问题
因此此贴中的顺序是先重新分配 hash 槽

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值