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 

  • 相关阅读:
    Maven学习总结(9)——使用Nexus搭建Maven私服
    Maven学习总结(8)——使用Maven构建多模块项目
    Maven学习总结(8)——使用Maven构建多模块项目
    Maven学习总结(8)——使用Maven构建多模块项目
    Maven学习总结(7)——eclipse中使用Maven创建Web项目
    Maven学习总结(7)——eclipse中使用Maven创建Web项目
    Maven学习总结(7)——eclipse中使用Maven创建Web项目
    Maven学习总结(6)——Maven与Eclipse整合
    Maven学习总结(6)——Maven与Eclipse整合
    nmon
  • 原文地址:https://www.cnblogs.com/hugetong/p/12584107.html
Copyright © 2011-2022 走看看