Codis不停机迁移

背景

当时从别的部门接手了一套服务,里面使用了一套豌豆荚开源的Codis2.0版本的缓存集群。但是由于历史原因,现行的架构不是很合理。集群的dashboard,proxy以及codis-server都集中复用在主要几台主机上。其中共有四台主机,每台主机角色都有proxy,ZookeeperServer以及codis-server。并且每台机器存在6个主实例,对于生产系统,这样的结构存在极大的安全隐患。于是考虑做一次迁移,将角色分散开来,降低风险。由于是生产系统,本次迁移必须是以不影响线上服务为前提,下面来叙述基本过程。

迁移过程

这里其实分成了两部分,一部分是组件迁移,另一部分是数据迁移。

组件迁移

新的规划是3台codis-proxy和zookeeper(复用在一起),dashboard一台,codis-server数台。组件迁移的目标是将旧机器上的组件按规划迁移到新机器上。下面描述详细过程。

Step-1

因为原来有4台zk,那么我们先新增3台,令集群保持奇数。做法是在原来4台zk的server列表里面添加进新的3台,同时新的3台zk的server列表也是预先写好了7个server。这时候选择原有的4台zk每次两台进行重启(测试过程中发现一次重启两台集群会比较稳定)。这里描述一下里面的原理。其实zk只要集群里面的节点超过半数是存活的,集群就是稳定的。那么被重启后的两台机器认为现在存活的是4台(新的3台没有启动),超过半数,集群稳定。 那么这时候我们再启动后面的3台,这时候zk集群就变成了7台。

Step-2

这时候我们将新的3台codis-proxy上线(proxy里面的zk server列表是新的3台zk),修改LVS入口调度策略,将流量引到新的proxy上。然后将旧的4台zk任选3台停止上面的zk进程(这里为了让集群没有停顿,最好选择非leader节点)。然后类似Step-1的操作,修改余下4台zk的server列表,从中剔除已停止的3台,并每次选两台进行重启,此时zk集群变成4个节点。

Step-3

迅速将旧的dashboard停掉,启动新的dashboard。然后将旧的4台codis-proxy中的zk server列表变成新的3台zk,然后逐个重启。这时候就完成了90%的工作了。

Step-4

停掉原来剩下的1台zk,并更新zk集群的server列表,每次任选两台进行重启。此时zk集群成功变成了3个节点,proxy此时有7个(原有的4个和新上的3个)并且其中的zk列表都是新的3个zk节点。

到这里,我们就完成了迁移的第一步:组件迁移。其实这里面步骤有点复杂,但是都是围绕着zk集群不能超过半数宕机以及平滑地将zk里的数据同步到新zk节点上。
接下来我们继续下一步。

数据迁移

当前是有四台codis-server,每台有6个6G的实例。每个实例都是一个组的主实例。现在的目的是将数据迁移到14台codis-server中,每台codis-server只有一个6G实例,其中数据的清除规则设置的是Allkeys-LRU。由于之前执行了auto-rebalance操作,全部都打散了,故迁移过程主要是首先扫描集群的slot,取出需要组的slot_id,然后进行迁移。细心的您可能会发现这个数据迁移前后的数据量不一致。是的,我们不只是做迁移,还清理了一些垃圾数据。

总结

到此整个不停机迁移的过程结束。做完这个过程确实收益不少,其中最重要的我认为是八个字:认真准备,胆大心细。由于这次操作的缓存是生产环境的,一出现差错会直接影响线上服务。所以操作之前进行了各种测试,做好了风险评估。实施的时候严格按照施工文档操作,步步为营,如履薄冰。

参考

https://github.com/CodisLabs/codis
https://cwiki.apache.org/confluence/display/ZOOKEEPER/Index

您的支持将鼓励我继续创作!
0%