欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

记一次redis-trib reblance动态扩容的坑

程序员文章站 2024-01-25 20:10:58
...

一、背景

  • 业务用户的增长,redis集群内存使用越来越大
  • 集群单节点的内存限额已经很大了(17GB),不能单纯的通过调整节点内存限额来扩容
  • 不能纵向扩容,那就横向扩容

二、坑点

  • 因为海外网络的原因,导致使用redis-trib reblance进行动态扩容时很慢
  • 本地机房10分钟迁完一个节点的槽位,海外跨机房10个小时才能迁完一个节点
  • 又不敢中断,怕中断后槽位分配出现问题,之后很难调整

从早上10点迁到晚上8点才迁完一个节点的,实在是慢的不行;还考虑到万一夜里进程挂掉了,那时候处理起来更麻烦了。

所以决定主动出击,把问题尽快解决,为业务减少点损失,也给自己找条生路…

三、难点

这个问题主要是有两个难点:

  • 怎么在海外机器上离线搭建redis-trib.rb环境(生产环境中的服务器不能连外网,不好直接下载东西)
  • 中断redis-trib rebalance命令后,槽位分配万一出现问题,要怎么修复

四、解决

4.1 离线安装redis-trib环境

离线安装环境的主要参考如下:

https://www.cnblogs.com/xuliangxing/p/7132656.html

https://www.cnblogs.com/xuliangxing/p/7133544.html

还有一个的难点就是传文件,我这边的办法是:

  • 先将需要的安装包下载到本地
  • 然后通过终端,直接将文件拖动上传到内网办公的服务器
  • 在服务器上使用nc命令将安装包发送到海外的服务器上

4.2 解决中断redis-trib rebalance命令后槽位的修复问题

要解决redis-trib rebalance中断后的问题,首先得知道动态扩容涉及到的过程,以及redis-trib的执行原理。

4.2.1 动态扩容的过程

  • 准备新节点
    • 提前准备好新节点并运行在集群模式下
    • 建议使用相同的配置文件,便于管理
  • 加入集群
    • 可用cluster meet命令
    • 也可用redis-trib.rb add-node命令
    • 线上环境建议使用redis-trib.rb add-node命令添加,避免将新节点加入到其他集群,造成集群‘融合’,导致数据丢失
  • 迁移槽和数据
    • 槽迁移计划
    • 迁移数据
      • 对目标节点发送cluster setslot{slot}importing{sourceNodeId}命令,让目标节点准备导入槽的数据
      • 对源节点发送cluster setslot{slot}migrating{targetNodeId}命令,让源节点准备迁出槽的数据
      • 源节点循环执行cluster getkeysinslot{slot}{count}命令,获取count个属于槽{slot}的键
      • 在源节点上执行migrate{targetIp}{targetPort}""0{timeout}keys{keys…}命令,把获取的键通过流水线(pipeline)机制批量迁移到目标节点,批量迁移版本的migrate命令在Redis3.0.6以上版本提供,之前的migrate命令只能单个键迁移。对于大量key的场景,批量键迁移将极大降低节点之间网络IO次数
      • 重复执行上述两个步骤,直到槽下所有的键值数据迁移到目标节点
      • 向集群内所有主节点发送cluster setslot{slot}node{targetNodeId}命令,通知槽分配给目标节点。为了保证槽节点映射变更及时传播,需要遍历发送给所有主节点更新被迁移的槽指向新节点
  • 添加从节点
    • 使用cluster replicate{masterNodeId}命令为主节点添加对应从节点

4.2.2 redis-trib的执行原理

主要参考如下:

https://blog.csdn.net/damanchen/article/details/103858103

4.2.3 实战记录

在了解了redis集群的动态扩容原理以及redis-trib的具体实现过程后,先在测试集群上做了实验,发现redis-trib.rb fix ip:port是能修复rebalance中断导致的槽位问题,所以就开始在线上开始操作。

  • 按下Ctrl+c中断redis-trib.rb rebalance进程

  • 使用redis-triib.rb check检查集群的状态(发现23号槽位还在处理开放的状态)

    ...
    [OK] All nodes agree about slots configuration.
    >>> Check for open slots...
    [WARNING] Node 10.172.18.26:34564 has slots in migrating state (23).
    [WARNING] Node 10.172.18.24:37571 has slots in importing state (23).
    [WARNING] The following slots are open: 23
    >>> Check slots coverage...
    [OK] All 16384 slots covered.
    
  • 使用redis-triib.rb fix修复集群的状态(把正在处于migrating和importing的那个槽位(23)接着处理完)

    ...
    [OK] All nodes agree about slots configuration.
    >>> Check for open slots...
    [WARNING] Node 10.172.18.26:34564 has slots in migrating state (23).
    [WARNING] Node 10.172.18.24:37571 has slots in importing state (23).
    [WARNING] The following slots are open: 23
    >>> Fixing open slot 23
    Set as migrating in: 10.172.18.26:34564
    Set as importing in: 10.172.18.24:37571
    Moving slot 23 from 10.172.18.26:34564 to 10.172.18.24:37571: ...........................................................
    >>> Check slots coverage...
    [OK] All 16384 slots covered.
    
  • 再使用redis-triib.rb check检查集群的状态(这时候集群状态就正常,没有异常槽位)

    [OK] All nodes agree about slots configuration.
    >>> Check for open slots...
    >>> Check slots coverage...
    [OK] All 16384 slots covered.
    
    

    注意:有时候执行一遍redis-trib fix之后,集群check之后发现有提示

    Redis [ERR] Nodes don’t agree about configuration!
    

    这应该是由于各个节点的槽位信息不一致导致的,需要调整各个节点槽位记录,让其保持一致。

    最简单的方法是再执行一遍redis-trib fix,让其自动校验调整下集群的槽位信息。

  • 确认集群状态正常后,到海外的机器上再次执行redis-trib.rb rebalance命令,让其开始做槽位迁移

五、后续

之后在海外机器上做迁移果然快多了。。。

下次一定得注意r`edis-trib.rb命令的跨机房使用,不光慢不说,还可能中断后槽位信息不一致导致集群不可用,那就GGL了。

还好提前处理了,不然又得写故障报告了@[email protected]

相关标签: 采坑记