zoukankan      html  css  js  c++  java
  • [redis] redis在线系统热迁移的方案与记录

    一 前言

    如图,是我的环境。

    这里边有三个系统,1 业务系统。2 redis cluster集群。3 redis cluster集群的管理系统。

    系统1,会对redis中进行秒级的数据添加,读取,删除操作。系统3,是redis集群的增加节点减少节点,节点failover功能进行管理。

    如图目前,我的系统里,redis共占用了a1,b1,c1,d1四台物理设备。我的目的是,在不影响业务系统运行的情况下,

    将redis集群迁移到a2,b2,c2,d2四台物理设备上去。

    二 预备知识

    目标系统的redis版本是4.0,之所以强调版本,是因为新版本中,拥有了命令

    redis-cli --cluster。4.0版本中并没有,它的前任是脚本,redis-trib.rb。二者

    大同小异,没有本质区别。

    下面是,进行中使用到的几个操作

    1.  查看当前集群拓扑的方法

    redis-cli -c cluster nodes 
    redis-cli -c cluster slots

    拓扑关系

    a51459f9cf9b5611cefe137dfcfbd9d9fdb03cfe 10.1.3.168:6379@16379 slave c3ac54ffd1efd366fdf70b3ba0e4185bee49840e 0 1584705659599 6 connected
    8ea700c80aa9bebbcd87549cad4538cfeb13dc5f 10.1.4.40:6379@16379 master - 0 1584705662628 1 connected 0-5460
    d1fb28322822546c76800cee00fc08ea30eee3d9 10.1.4.39:6379@16379 slave 38dcb1adf11ca19bc66d2d2e887588fb65537c9e 0 1584705658000 4 connected
    f4f3aa15073de7f6efc0ee104d4b51de8d5e5ff5 10.1.3.165:6379@16379 slave 8ea700c80aa9bebbcd87549cad4538cfeb13dc5f 0 1584705660606 5 connected
    38dcb1adf11ca19bc66d2d2e887588fb65537c9e 10.1.3.170:6379@16379 myself,master - 0 1584705659000 3 connected 10923-16383
    c3ac54ffd1efd366fdf70b3ba0e4185bee49840e 10.1.3.169:6379@16379 master - 0 1584705661622 2 connected 5461-10922

    2  查看数据分布的方法

    redis-trib.rb info 127.0.0.1:6379  

    数据分别是指,那些数据存储在那些节点上。

    我这里的集群组织方式是,一对一对的组织。每一对有一个master,一个slave。slave作为master的数据冗余和failover节点。可以从上一个命令的输出里,见到他们的关系,

    而,数据的分布如下所示,关注keys信息。可以看见,那些那些key,在那些那些地方。当正在进行数据迁移时,我们能看见keys前边的数值在一点点减少。

    [root@redis6st caotong]# redis-trib.rb info 127.0.0.1:6379
    127.0.0.1:6379 (38dcb1ad...) -> 1998 keys | 5461 slots | 1 slaves.
    10.1.4.40:6379 (8ea700c8...) -> 2012 keys | 5461 slots | 1 slaves.
    10.1.3.169:6379 (c3ac54ff...) -> 1999 keys | 5462 slots | 1 slaves.
    [OK] 6009 keys in 3 masters.
    0.37 keys per slot on average.

    3 查看集群实时状态的方法

    redis-trib.rb check 127.0.0.1:6379 

    这个输出,重点关心的是一下额外的信息, 如xxx is migrating 字样

    复制代码
    [root@redis6st caotong]# redis-trib.rb check 127.0.0.1:6379
    >>> Performing Cluster Check (using node 127.0.0.1:6379)
    M: 38dcb1adf11ca19bc66d2d2e887588fb65537c9e 127.0.0.1:6379
       slots:10923-16383 (5461 slots) master
       1 additional replica(s)
    S: a51459f9cf9b5611cefe137dfcfbd9d9fdb03cfe 10.1.3.168:6379
       slots: (0 slots) slave
       replicates c3ac54ffd1efd366fdf70b3ba0e4185bee49840e
    M: 8ea700c80aa9bebbcd87549cad4538cfeb13dc5f 10.1.4.40:6379
       slots:0-5460 (5461 slots) master
       1 additional replica(s)
    S: d1fb28322822546c76800cee00fc08ea30eee3d9 10.1.4.39:6379
       slots: (0 slots) slave
       replicates 38dcb1adf11ca19bc66d2d2e887588fb65537c9e
    S: f4f3aa15073de7f6efc0ee104d4b51de8d5e5ff5 10.1.3.165:6379
       slots: (0 slots) slave
       replicates 8ea700c80aa9bebbcd87549cad4538cfeb13dc5f
    M: c3ac54ffd1efd366fdf70b3ba0e4185bee49840e 10.1.3.169:6379
       slots:5461-10922 (5462 slots) master
       1 additional replica(s)
    [OK] All nodes agree about slots configuration.
    >>> Check for open slots...
    >>> Check slots coverage...
    [OK] All 16384 slots covered.
    复制代码

    三 思路

    两个思路。

    1,把集群节点迁走,集群还是那个集群只不过他们的各种节点都被更新了。

    2,把数据迁走,幸运的是我的业务系统有重连机制,并且支持热修改集群信息。所以只要保证数据的增删改查都能成功并正确。切换一个全新的cluster同样对业务无感知。

    四 方案一

    我这里,采用的迁移方案,是先扩容再缩容。这样是热的,online的。对在线系统无感知的。

    把你想迁入的目标作为扩容资源扩进来,然后再将你想缩容的资源作为迁出目标缩掉,即可。

    我会先增加一对主备节点,然后理由上面提到的两个命令,来观察:

    (1)迁移的过程是否正常,(2)数据是否正常流动,(3)迁移是否已经进行完成

    迁移进行完成指的是数据流动已经完成。

    过程是否正常:1 通过前文的check命令查看runtime状态。2.通过info命名查看数据流动进程。

    最终的状态,可以通过nodes命令观察,是否出现fail的节点。以及是否每个master都结对一个slave,

    包括谁和谁是一对的这种对应关系。

    增减动作通过前文中的管理系统接口完成的,没有命令的细节。 该系统只是对redis -cli和redis-trib.rb的封装,

    附加了他自己的逻辑在里边。

    redis-cli --cluster help可以看见更多细节,包括add node,add slot之类的常用命令。

    删除一个节点的方法:

    redis-trib.rb del-node host:port node_id

    参考: https://www.cnblogs.com/ivictor/p/9768010.html

    然而,该方案并没有实施成功,因为该管理系统的bug,导致其自己进入不可跳出的管理状态里。

    这里不在赘述,进入方案二

    五 方案二

    如前文述,方案二的思路是数据迁移。管理系统在节点变更是存在问题。但是全新创建的话,仍然是可用的。

    于是,现在我们可用绕可它来达到目标。

    需要强调的是,本人是新手,完成100台以下的数据迁移工作只有三天时间,并之前几乎没有好好接触过redis。

    所以整体目标是安全与快速。故选用以下四个方法,并排列优先级:

    可选有四种方法,要求必须满足online的数据无缝热迁移:

    1  python工具:https://github.com/p/redis-dump-load

      该工具简单使用后发现不支持集群,只支持单点设备。工作量大,留做备选。

    2  ruby工具: https://github.com/delano/redis-dump

      该工具测试之后发现有一个bug。用的话,需要修复一下bug。会增加额外工作,留作备选。报错如下

    CROSSSLOT Keys in request don't hash to the same slot redis dump

       另外,这个东西安装有点麻烦,还有安装ruby环境。安装ruby的环境与包管理工具的方法:

    yum install rubygems

    3  C工具:https://github.com/tanruixing88/redis-migrate-tool 

      该方法可以。并最后成功了。后边详述。另,这是唯品会工具的一个fork,说是唯品会的只支持3.0,这个支持高版本,见:

      https://cco.xyz/post/redis-migrae-tool/

    4  RDB与AOF方案:使用bgsave命令,已经修改配置文件等方法。

      这是保底方案,是官方正规方法,并且一点可以成功。但是很显然更花时间。有额外的学习成本,也有额外的时间成本。

    redis-migrate-tool的详细操作步骤

    1  配置文件: 所有节点的IP + Port,包括slave和master

    [source]
    type: redis cluster
    servers:
    - 10.1.0.12:6379
    - 10.1.0.6:6379
    - 10.1.0.24:6379
    - 10.1.0.11:6379
    - 10.1.0.5:6379
    - 10.1.0.9:6379
    - 10.1.0.8:6379
    - 10.1.0.7:6379
    - 10.1.0.13:6379
    - 10.1.0.10:6379
    
    [target]
    type: redis cluster
    servers:
    - 10.1.0.50:6379
    - 10.1.0.46:6379
    - 10.1.0.48:6379
    - 10.1.0.47:6379
    - 10.1.0.45:6379
    - 10.1.0.51:6379
    - 10.1.0.49:6379
    - 10.1.0.19:6379
    
    [common]
    listen: 0.0.0.0:8888

    快速生成以上ip串的小技巧:

    redis-cli -c cluster nodes |awk '{print $2}' |awk -F'@' '{print "- "$1}'

    2   启动方法:

    ./redis-migrate-tool -c migrate.conf -o log -d

    3  停止方法

    使用下面的命令行进入管理界面:

    redis-cli -h 127.0.0.1 -p 8888

    然后执行shutdown命令。

    迁移步骤:

    1  新建一个全新的redis 集群,并确保集群建立成功,集群状态up。

    2  配置 redis-migrate-tool工具的配置文件

    3  启动工具,这个时候能观察到新group中的key书目在不断增加。直到超过旧集群的key总数。

        这里需要说明的时候,因为旧group依然是业务在线的。所以key实际上处于有增有减的动态过程中。而迁移工具实际上做的时候一个不断copy的工作,

       所以,新集群实际上是旧集群里所有key的累加结果。被删掉的旧集群上的key并不会被一起上新集群里删掉。

    4  这里有两个假设,

       1  迁移工具的迁移速度大于旧集群中key的新增速度。

       2  业务系统必须容忍这样一直失败场景:刚存入的key,在小于迁移速度的时间内有可能获取失败。

       在满足以上两个条件的前提下,进行第五步操作:

       迁移业务系统:使用命令解绑旧的业务系统与redis 集群的绑定关系,绑定新的集群。

    6  在第五步完成之后,可以观察到旧集群中的key数量将不在变化,没有新的key增加,也没有旧的key删除。

        再观察迁移工具,发现全部的key迁移已经完成了。

       这块时候可以停止迁移工具了。

    7  删除旧的集群

    8  (4)中提到的那些没有被删除的旧key,会在n天后超时自己删掉自己。

      我的业务系统对每一个key丢进行了超时配置。不过即使没有这个附件条件,依然没有关系,我们可以通过一下方法来达到这个目的,

      以使得我的方案更具有处理一般问题的普适性。

      对所有可以,设置超时的方法:

    redis-cli -c keys '*yourKEYWORD*' |xargs -l -I {} redis-cli -c set {} 123 ex 3

    至此,数据热迁移完成。对业务无感知。

     

    六 完

     [classic_tong @ 20200321  https:////www.cnblogs.com/hugetong/p/12584107.html] 

    完。

    参考:https://yq.aliyun.com/articles/726005 

  • 相关阅读:
    SCAU 9504 面试
    SCAU 9503 懒人选座位
    SCAU 8628 相亲
    SCAU 10691 ACM 光环
    SCAU 8626 原子量计数
    SCAU 10674 等差对
    HDU ACM 1048 The Hardest Problem Ever (水题)
    SCAU 9502 ARDF
    SCAU 10686 DeathGod不知道的事情
    SCAU 8629 热身游戏(高精度)
  • 原文地址:https://www.cnblogs.com/hugetong/p/12584107.html
Copyright © 2011-2022 走看看