Redis: 集群高可用之节点与插槽管理

概述

  • Redis Cluster 集群模式,它使用的是分片来存储数据的,数据都存在多个节点上。
  • 而且使用了哈希槽这样的机制,它内部维护了 16384 个插槽
  • 那就是说每一个节点其实都具体的分布了一些槽,如果我们添加一个节点的话,槽总数就就要扩增吗?
  • 当然不是,槽的总数还是 16384,如果我新加一个节点,这个节点如果说想要去处理客户端的命令
  • 就是它如果要能存数据的话,就得有槽,那我们其他的节点已经把槽都分完了,它的槽就得重新分片
  • 比如说我添加一个节点,我要从其他的节点上把一些槽取出来,分配给这个新节点
  • 如果说我要删除一个节点,这个节点如果是从节点,非常简单,如果是个主节点
  • 我们是不是要把这些槽先转移到其他可用的节点上,然后再把它删掉
  • 这里边也会涉及到重新分片,插槽管理

添加主节点并重新分片

1 )集群添加主节点

  • 基于之前集群的环境,就是3个节点,每个节点上面分别装了两个 Redis
  • 我们随意找一台机器检查随意一个Redis实例
    • $ /usr/local/redis/bin/redis-cli -a 123456 --cluster check 192.168.10.101:6371
    • 从这里输出可以看到 主从槽点范围分配等各种信息
  • 现在比如集群实例有6个,按照配置文件来说是从 6371 ~ 6376
  • 现在我们在一个节点上拷贝一份配置并进行修改,启动一个 6377 的 Redis 实例
    • $ /usr/local/redis/bin/redis-server /usr/local/redis/cluster/conf/redis-6377.conf
  • 这个时候,这里的 Redis 实例,和之前集群中的 6个是无相关的
    • 我们可以登录集群看下 $ /usr/local/redis/bin/redis-cli -a 123456 -h 192.168.10.103 -p 6376 cluster nodes
    • 发现只有6个,和刚才的 6377 没有任何关系
  • 下面是添加主节点到集群中的命令语法
    • $ redis-cli --cluster add-node new_host:new_port existing_host:existing_port --cluster-master-id node_id
    • existing_host:existing_port 指集群环境中最后主节点的ip和端口,就是check命令返回的最后一个 M
    • 这里的最后,也是根据槽来判定的,假如我们最后一个ip和端口是: 103和6375
  • $ redis-cli --cluster add-node 192.168.103:6377 192.168.103:6375 --cluster-master-id node_id f3353d11eae2dae1e46cdee9134beea872d1c6e8
    • 之后会正常输出 [OK] New node added correctly.
  • 再次进行 check 发现多了一个 M 主节点,发现新增的 6377 没有从节点,也就是 副本
  • 添加完节点后,就需要重新分片:把当前集群中其他节点里取出一些槽分配给新的节点

2 )重新分片

  • 只有对新加入的主节点重新分配 hash 槽,该主节点才能存储数据
  • 重新分片语法:$ redis-cli --cluster reshard host:post --cluster-from node_id --cluster-to node_id --cluster-slots <args> --cluster-yes
    • 这里 host:post 可以是集群中之前 6371 ~ 6376 随便一个节点,这个是连接集群用的
    • --cluster-from node_id 分配的槽是从哪里来的,这个 node_id 随便找一个 M 主节点的 node_id, 也可以用逗号分隔写多个node_id
    • --cluster-to node_id 把新槽给谁,这里我们会分配给 6377
    • --cluster-slots <args> 表示,要分配多少槽,如果是槽内有数据,数据也一起过去
    • --cluster-yes 不会回显槽的分配情况,直接进行移动
  • 参考示例
    • $ /usr/local/redis/bin/redis-cli -a 123456 --cluster reshard 192.168.10.101:6372 --cluster-from afe0b3936c837a46972055c7b9b691bdd8149b7d --cluster-to 3a083c35074c45d51.3af75e137b3aa9fc3d4b0e2 --cluster-slots 2000 --cluster-yes
  • 这样,主节点被添加进集群,并且给新的主节点重新分了片

添加从节点并构成主从关系

  • 现在要添加从节点,从节点之后把它加入到这个环境里,并且让它和刚才的 6377 构建为一主一从的关系
  • 现在,这个集群里边,相当于现在就是有四组分片,每一个分片都有一个副本,四主四从的环境
  • 现在在一个节点上拷贝一份配置并进行修改,启动一个 6378 的 Redis 实例
  • 目前,6378 没有在集群中,我们要先把 6378 添加到集群中,添加从节点和上面添加主节点稍微不一样

1 )集群添加从节点

  • 添加从节点,要表示它的角色是Slave, 它要复制谁,这是它的一个命令
  • 命令语法:$ redis-cli --cluster add-node new_host:new_port existing_host:existing_port --cluster-slave --cluster-master-id node_id
    • new_host:new_port 表示要添加从节点的ip和端口
    • existing_host:existing_port 要给的哪一个主节点去添加
    • --cluster-slave 表明角色:从节点
    • --cluster-master-id node_id 填入对应主节点的 node_id
  • 示例参考:
    • /usr/local/redis/bin/redis-cli-a 123456 --cluster add-node 192.168.10.103:6378 192.168.10.103:6377 --cluster-slave --cluster-master-id 3a083c35074c45d513af75e137b3aa9fc3d4b0e2
    • 添加完成后,会有绿色文案提示 [OK] New node added correctly.
  • 重新执行 $ /usr/local/redis/bin/redis-cli -a 123456 -h 192.168.10.103 -p 6376 cluster nodes
    • 可看到,新的从节点已经被加入集群了
  • 这样,主从关系也被确立完成了

删除节点

1 ) 删除 从节点

  • 把从节点从集群环境中移除,然后把这个从节点停掉,非常简单就完成了
  • 因为从节点只是主节点的一个副本,所以说对环境的影响不是很大
  • 语法 $ redis-cli --cluster del-node host:port node_id
  • 删除 6378 示例参考
    • /usr/local/redis/bin/redis-cli -a 123456 --cluster del-node 192.168.10.103:6378 c5bd04543b5d96595bdf61135451581ea0363c71
  • 检查环境验证
    • $ /usr/local/redis/bin/redis-cli -a 123456 -h 192.168.10.103 -p 6376 cluster nodes
    • 可见,正常移除了,当然, check 命令也可以看
  • 进入 6378,之后停掉它 $ SHUTDOWN

2 ) 删除主节点

  • 删除主节点时,注意,主节点是处理客户端请求的,而且它上面有插槽有数据
  • 如果说你贸然的把一个主节点删掉,肯定会出问题,要把槽转移到其他可用的节点,然后再去删除它
    • 不然,会丢失数据
  • 当它已经没有槽了,变成一个空的节点的时候,你去删,它就跟删除从节点这个命令是一样的

2.1 先将要删除主节点的槽转移出去

  • 可以使用之前上面的命令,现在我分开来做
    • $ /usr/local/redis/bin/redis-cli -a 123456 --cluster reshard 192.168.10.102:6373
  • 之后会有提示
    • How many slots do you want to move (from 1 to 16384)? 这里可以写 2000
    • What is the receiving node ID? 这里填写接收方id, 对应 --cluster-to 填写 afe0b3936c837a46972055c7b9b691bdd8149b7d
    • Source node #1: 这里要填写槽的来源的id, 对应 --cluster-from 填写 3a083c35074c45d513af75e137b3aa9fc3d4b0e2
    • Source node #2: 这里可以填写多个, 如果槽数凑够了,则可以填入 done
    • 接着输入 yes 开始转移槽
  • 这样,槽就重新分配回去了,之后可以再通过 cluster nodescheck 命令查看节点信息来验证

2.2 移除主节点

  • 移除:$ /usr/local/redis/bin/redis-cli -a 123456 --cluster del-node 192.168.10.103:6377 3a083c35074c45d513af75e137b3aa9fc3d4b0e2
  • 连入并关停 6377 $ SHUTDOWN
相关推荐
赵锦川12 分钟前
css相关:input输入框中加入搜索图标
java·前端·javascript
周周写不完的代码1 小时前
Redis-持久化机制
数据库·redis·缓存
战神刘玉栋1 小时前
《程序猿之Redis缓存实战 · Redis 与数据库一致性》
数据库·redis·缓存
yunduor9093 小时前
从零开始搭建UVM平台(九)-加入reference model
前端
莘薪3 小时前
HTML的修饰(CSS) -- 第三课
前端·css·html·框架
某公司摸鱼前端5 小时前
uniapp 上了原生的 echarts 图表插件了 兼容性还行
前端·uni-app·echarts
2401_857297915 小时前
秋招内推--招联金融2025
java·前端·算法·金融·求职招聘
BHDDGT5 小时前
react-问卷星项目(5)
前端·javascript·react.js
小白求学16 小时前
CSS滚动条
前端·css
与妖为邻7 小时前
房屋水电费记账本:内置的数组数据击按钮不能删除,页面手动添加的可以删除
前端·javascript·css·html·localstorage·房租水电费记账本