零故障上云全过程再现,PB级数据迁移如何保障一致性?

靳洪兵 2021-04-27 17:42:05
本文根据靳洪兵老师在〖deeplus直播第265期〗线上分享演讲内容整理而成。(文末有获取本期PPT&回放的方式,不要错过)


 

 

一、美图秀秀介绍

 

 

我们通过增加一个VIP来解决域名变更后长连接不断开的问题。

 

切完写之后,流量全部切换到云上,此时IDC没有写入流量,这时候IDC的MySQL主从集群已经不能用了。整个切换操作就完成了。如果方案到这里就结束了,那这只是一个正常的切换操作。

 

 

那再问一个问题,如果这个时候云上服务出现故障,需要回滚怎么办?已经回滚不回去了,数据已经不一致了。

 

那么我们该怎么解决切写之后的回滚问题呢?

 

 

想一想这里回滚不了是因为什么?因为IDC没有完整的数据了。那现在完整的数据在哪里在云上,那如果我把云上的数据同步到IDC一份不就又是一份完整的数据了吗?但是同步的时机肯定不是出问题之后,而是应该在出问题之前。

 

 

顺着这个思路,在一开始的时候,我们就在IDC重新准备了一个备库集群。将公有云上的数据又同步一份到备库集群。这样可以保证在切写之后,IDC还是存在一份完整的数据,可以保证流量的回滚。在回滚后,将数据复制服务的流向变更为从最右边的集群到共有云。然后重复前面的过程。

 

针对MySQL的数据迁移,这里有些小Tips跟大家分享。

 

第一点,是数据迁移需要做数据对比,对比从两方面入手,一个是迁移工具的验证,一个是业务层面的验证。另外要注意迁移源库的内存使用率,因为在做数据对比的时候,源库的内存使用率会上升,如果源库本身内存容量不足,有可能造成源库oom。在实际迁移过程中,我们就遇到了源库oom的情况。

 

第二点,针对一些按年,按月建表的业务,不要忘记了数据库表创建的脚本要同步到云上。

 

第三点是数据库复制服务的限速,一个是复制的过程中不要给源库造成太大的压力,另外迁移过程中有多个应用多种数据迁移,需要协调专线的使用率。

 

第四点是 在做切换操作时,需要将切换操作脚本话,一键切换,只需要执行一条命令。可以减少出错的几率。

 

 

介绍完MySQL的数据迁移,下面介绍Memcached。

 

 

看下作为缓存的memcache是如何迁移的。美图秀秀重度依赖mc作为缓存。mc的同步采用的是双写+就近读的方案。云上和IDC会互相写数据,但是读流量只会读本数据中心的mc。另外在流量切换之前需要有一个预热的过程,预热既可以在业务层面做,也可以通过灰度的流量自动预热,利用灰度预热需要我们实现预估好穿透的量,避免给mysql造成太大的压力。

 

在测试环境使用mc的过程中发现了不少的问题。

 

 

  • 在稳定运行期间,mc容量写满之后性能下降比较明显。而且数据写得越多,性能下降越厉害。

 

通过云上监控发现,容量满后,对应虚机swap开始上涨。发现云上mc实例默认开启了swap。

 

我们使用mc的姿势就是申请一定容量的mc实例,然后一直写数据,写满后依赖mc自身内存管理机制来淘汰数据。有一些业务方跟我们使用姿势不一样,会开启mc的swap。开启swap,当访问到磁盘上的数据时性能就下降的比较厉害。

 

  • mc平稳运行一段时间后会突然挂掉?

 

这个问题跟前面关闭swap有一定关系,因为mc创建在虚机上。比如我们申请的mc实例是8G,那虚机内存8G,因为操作系统会占用一定的内存,所以mc实际使用的内存可能不会超过6.4G,当我们不断写入数据之后,由于关闭了swap没法做数据交换,在内存分配和销毁的过程中不断产生内存碎片。当整个mc的内存+操作系统内存超过8G后,虚机会重启,导致mc挂掉。这里需要的是设置mc的max_memory的值。

 

  • mc的穿透率不平稳,时高时低?

 

穿透率与mc的淘汰策略有关系,虽然业务也会设置mc的过期时间,但是在业务设置的mc过期之前,就存在穿透率不平稳的问题。然后发现云上mc的淘汰策略设置的是随机淘汰。互联网应用大多是读多写少的模式。因为我们首页请求量很大,需要缓存来抗读的量,越热的数据越需要有被缓存住,如果是随机淘汰可能会因为淘汰掉热数据带来一定的穿透量。

 

由于我们重度依赖mc作为缓存,mc的查询性能直接影响到上云后系统的稳定性。因此在上云前会在压测平台上拷贝线上真实环境的流量对云上的mc进行了压测。但是压测的结果显示,mc的读性能跟idc相比有一定的差异,差异大得有点令人诧异。具体现象是压测流量到达某个点后,mc会出现大量的数据淘汰,同时伴随着有大量的新连接创建,CPU利用率升高,ops降低,然后5-10分钟后又自动恢复的现象。

 

 

跟云上工程是沟通发现,云上mc不是原生的mc实现,是使用redis+mc协议实现的。当然云上有自己的考虑,使用redis主要是为了数据持久化以及HA。但是我们知道, redis内存管理基于Jemalloc内存分配器,Jemalloc频繁分配和释放内存会导致内存碎片。而原生的mc使用slab的内存管理,内存满后,淘汰同等大小的slab,直接覆盖数据,不会造成内存碎片。

 

当碎片率到达一定程度会触发内存的主动淘汰,由于主动淘汰时间过长,影响了mc的读写性能。

 

另外一个我们业务上使用的mc客户端,当发现mc时延超过一定阈值后,会重新创建连接。由于服务数过多,导致单个mc上会看到大量的新建连接过来。每一个连接又会占用一定的mc内存,从而进一步恶化整个mc的性能。

 

针对这个问题,云上进行了mc的性能优化攻关,最终将mc的性能提升到跟idc的一个量级。

 

在mc的性能这点,其实前面的参数都不重要,重要的是我们对于云上服务和组件应该保持的一个态度。引用一句当年美苏中程核武器谈判时,美国总统里根对戈尔巴乔夫说的一句话俄语谚语:“Trust,But Verify”。信任,但要核实。

 

有点儿奇怪的一个场景,一个中国人演讲里面引用的是美国人对俄国人说的俄语谚语。

 

媒体文件的迁移。

 

 

特点数据量大,迁移时间长,缓存数据双写同步按天记,数据库同步按周,媒体要按月。数据迁移依然使用云上的obs迁移工具,支持断点续传。同时还需要我们在业务层面进一步做数据对比。全量数据做etag对比,确保数据完整迁移到云上。

 

切读依赖CDN更改域名。域名指向变更后读流量就逐步迁移到云上。

 

切写流量依赖上传SDK组件变更上传域名。我们可以下发需要上传的域名给到sdk组件。但是客户端会有一段时间的缓存,因此始终都会存在一部分客户端将数据上传到IDC,一部分上传到公有云。

 

因此,对于媒体数据的迁移,我们并没有做什么快速切换的方案。过渡态是一定会出现的。因此主要解决过渡状态下,数据访问的问题。

 

 

这里有一个302系统,302系统是干什么用的呢?302的含义来自于HTTP 状态码302,是页面跳转的意思。这里也一样。

 

302系统在这里可以解决什么问题呢?当我们在切换的过程中,首先读肯定是读本数据中心的obs,比如读公有云上的obs,当公有云上的obs返回数据不存在时,经过302系统,将请求跳转到IDC的obs上去查询,如果有就返回,如果没有就返回404。在IDC也一样。有了302系统就不担心流量在切换的过程中找不到媒体文件。

 


 

 
3、把冰箱门关上:流量切换

 

最后我们看一下如何关闭冰箱门。流量是如何切换的。

 

 

从图中可以看到,我们对外的API域名有两种配置,一个是A记录,一个是CDN。A记录流量占比大约30%,CDN70%。我们会将A记录的流量当做灰度流量来操作。先将A记录的一部分流量切到云上,指向云上的LB。

 

 

稳定灰度一段时间,观察服务状态没问题后,然后开始切CDN,一家一家的切。cdn切完,全部流量都到云上。此刻检查,IDC是否还有流量访问。

 

 

大家可能也发现了,这里存在一个问题,切换DNS和CDN的生效时间比较长,同时回滚的话也没办法快速回滚。那应该怎么解决?这时候想起了一个计算机系统设计的经典语录:计算机系统里面的所有问题都可以通过增加一个中间层来解决。通过增加一层LB来解决切换生效时间比较长的问题。

 

前面我们做了应用迁移,数据迁移,当这里流量迁移完成后。整个上云的步骤就结束了。

 

三、云上稳定性建设

Q1:数据迁移会不会导致数据错乱?

 

A2:obs的绝对路径地址并没有保存在数据库中,只会将obs文件的文件名保存在数据库,另外还有一些obs文件对应的bucket等属性。针对obs的迁移,迁移过程中obs文件名不会变化,bucket也不会变化。除非云上已经存在同名的bucket或者bucket名称不符合云上的规范,我们需要变更bucket的时候,需要修改对应的数据库中的bucket的值。其他的不需要修改。变化的只是访问域名,迁移后只需要修改访问域名就可以了。

 

A3:分为两个维度来做一致性校验。一个是利用云上的数据复制服务,在数据迁移过程中,数据复制服务会提供数据的存量以及增量数据的对比,对比包括行数的对比和内容的对比。另一个是在业务层面,针对迁移的数据进行业务校验,可以抽样一批数据进行业务层面的数据校验。

Q4:你们迁云之后,制定了怎样的风险策略?如何规避安全漏洞呢?

 

Q5:请问你们的业务迁云之后,成本是如何控制的?

 

A6: 

  • 数据库迁移要提前启动,因为数据迁移相比应用和流量迁移的时间要更久,出现问题影响面也更大;

  • 数据库迁移需要针对数据做一致性校验;

  • 有一些月表或者年表的创建脚本不要忘记了迁移到云上;

  • 尽量在低峰期执行,操作要页面化,脚本化。
     

    获取本期PPT
    请添加小助手微信:dbachen


 
↓点这里可回看本期直播
阅读原文
最新评论
访客 2021年09月03日

有没有1000多张表

访客 2021年08月28日

metrics =》 metrix 错误

访客 2021年08月25日

只看到如何避免,如何减少书写慢 sql

访客 2021年08月25日

没看到如何治理呀

访客 2021年07月23日

果然k8s不是神!

活动预告