分享一次险象迭生的系统迁移【真实案例】

一、背景

因为系统数据量持续性增大,腾讯云的MySQL已经达到瓶颈,无法进行升级操作,如果自己搭建一个分库分表系统,速度和可靠性上面都会很差,综合各方面考虑,最后决定采用阿里云的PolarDB-X分布式数据库。

但是迁移整个系统,工作量和流程不是简简单单就可以搞定,需要系统性的思考,完善的迁移方案,最后才可以实施。在开始今天的文章之前,童靴们可以自己思考一下,假如是你主持这场迁移,你需要考虑哪些内容。

二、挑战

挑战1:

数据库确定了,但是又有一个大问题,因为腾讯云和阿里云不是同一个云服务商,所以只能走外网,那就必须将所有服务一起迁移到阿里云上面才可以。这个过程难点有两个,一个是在迁移完成最后切换的过程,要保证服务可用,不能中断。第二个难点是需要切分新的分支,因为两边的Dockerfile文件是不一样的。

挑战2

阿里云的PolarDB-X虽然兼容原生的MYSQL,但是个别的SQL还是不兼容,需要根据PolarDB-X的规则进行修改。所以我们在全面迁移之前,得兼容PolarDB-X的SQL规则,保证所有的SQL都是可执行的。

挑战3

因为是进行系统迁移,必须要进行回归测试,不仅仅是API服务的还有数据服务,测试流程长且繁琐。

三、当前系统

迁移之前先给大家介绍一下当前系统架构,因为这些模块都是必须的,阿里云平台上面肯定也需要对等的创建这些模块才可以。

技术栈:

  • XXL-JOB(分布式调度系统)

  • RabbitMQ(Linux服务器上面部署,非容器)

  • Java(开发语言)

  • Nginx(Linux服务器上面部署,非容器,前端vue项目就是放在里面)

  • 腾讯云服务平台

  • MYSQL(腾讯云服务)

  • Redis(腾讯云服务)

架构图:

图片

腾讯云的k8s采用的物理节点初始化加入到集群中,所有容器实际是运行在各个物理节点下面。

四、阿里云平台服务筛选

4.1 容器服务选择

阿里云的容器服务有ack和ask两种,他们之间最大的区别就是ack需要购买物理节点,而ask不需要。经过研讨确定之后,我们最终选择了无节点的ask容器服务。

4.2 云盘选择

只要是程序就必然会产生文件,现在因为采用ask无节点的容器服务,那日志就必须通过专门的盘来放置。对这个盘需要有如下几点要求:

  1. 有多种类型可供选择,像日志文件存储,不需要多强的性能,容量够用即可,像MQ的消息就要求吞吐量要足够高才可以。

  2. 可以设置过期自动删除策略,因为像日志文件不需要长时间保留,一般保留最近7天就可以。

  3. 要有完善的监控服务。

针对上诉要求,最终我们选择了NAS云盘服务。

4.3 监控选择

因为没有实际物理节点,很多报警指标都没办法设置,只能借助第三方的服务来进行监控和报警,这边我们选择了Prometheus作为监控和报警。

4.4 RabbitMQ选择

阿里云有MQ队列服务,可以直接购买使用,但是会有很多限制,所以MQ还是只能用原生的。

4.5 Redis选择

Redis直接买阿里云的Redis服务,直接和腾讯云进行对等购买就可以。

五、部署运行

因为阿里云采用ask容器服务,没有实际的物理节点,所以之前部署在节点上面的服务都要进行容器化才可以,例如Nginx、RabbitMQ。

创建镜像容器

第一步我们需要创建各个应用对应的镜像以及容器,这边需要注意的时候,镜像的命名空间最好以公司为主,容器的命名空间以类型为主。

虽然阿里云集成了k8s的功能,但是关键字、功能等还是采用原生的k8s,上面的命名空间就是k8s的命名空间。

导入测试数据

为了解决PolarDB-X的SQL兼容问题,需要将某一用户的数据从腾讯云的MYSQL导入到阿里云的PolarDB-X中,数据导入可以借助阿里云的DTS来实现。

回归测试

PolarDB-X测试数据准备完毕,所有的镜像和容器也都创建之后,就可以开始回归测试了。

如果有测试用例,那测试阶段就可以大大提高测试效率,这也是为什么我们平时最好要写测试用例的原因之一。

六、迁移前准备

PolarDB-X的SQL兼容性修改完毕之后,就可以全面迁移数据了,迁移数据还是采用阿里云的DTS来进行,迁移数据可以分多个组进行,同步进行迁移,这种情况可以避免某些表因为频繁的进行修改,导致bin-log日志数据量突增,导致迁移的速度小于数据产生的速度(生产大于消费模型)。

当数据全部迁移过来之后,就可以开始正式迁移云服务平台了,在迁移之前我们需要做如下准备:

  1. 阿里云对应的分支是否和腾讯云对应分支最新代码一致。

  2. 阿里云的HTTPS SSL证书配置是否正确。1. 阿里云各个容器的配置、JVM参数设置、端口是否和腾讯云一致。

  3. Redis、RabbitMQ脚本是否正确无误。

  4. 容器中各个服务配置(数据库、Redis、MQ等)是否正确。

  5. 腾讯云服务停止和阿里云服务启动顺序。

  6. Nginx配置修改。

我们系统服务可以分为四大类:

  1. API服务

  2. 监控服务

  3. 数据服务

  4. 分布式调度服务

除了API服务,其它三类短时间停止,不会有很大问题。

6.1 停止推送服务

第一步先将腾讯云数据推送服务停止,确定新的数据不会产生,将MQ中不可删除的消息,通过MQ脚本迁移到阿里云MQ中,确保MQ没有消息存在。

在停止服务之前,先要确定哪些服务在运行阶段是不可被打断的,如果被打断就会存在数据缺失的情况,这种任务就得特殊对待,等它执行完再停止。

6.2 迁移Redis

数据服务全部停止之后,迁移腾讯云的Redis数据到阿里云Redis中。

6.3 启动阿里云服务

将阿里云的API服务全部启动,保证阿里云平台的系统可用。

6.4 修改DNS转发

停止阿里云DTS数据迁移任务,将DNS解析修改为阿里云IP,将原本Nginx中转发也转到对应IP中(因为客户端可能存在DNS缓存,还是会走之前的IP)。

6.5 关闭腾讯云服务

关闭腾讯云剩余所有服务,启动阿里云所有服务,并检查各个服务健康状态。

至此腾讯云的服务就全部迁移到阿里云平台中来了,整个切换的过程没有发生很大的问题,但是切换过来之后,问题就频繁出现了。

七、迁移后遗症

7.1 带宽受限

迁移过来之后,系统页面可以打开,但是各个数据服务消费速度异常慢,检查错误发现基本都是网络连接错误,也就是丢包问题。容器本身CPU、内存、IO都是正常的,最终发现是网关连接数超标导致的丢包问题,升级网关配置,数据消费服务就正常了。(HTTP请求的TCP连接数过大,应该是应用程序出问题导致的,因为情况比较紧急,所以先升配置,具体问题后面再检查)。

网关配置升级不仅仅是连接数升级,还需要一起升级带宽,不然带宽达到上限也会导致丢包问题发生。

7.2 慢SQL问题

系统某些页面打开发现特别慢,检查之后发现是慢SQL导致的,有些是没有加分库键导致的,有些是因为复杂SQL连连表问题,这些慢SQL导致连接池的连接无法释放,最终导致连接池被耗尽,用户的请求无法被响应。

7.3 MQ非持久化

之前提到过,将MQ从Linux中变成一个容器服务,但是因为MQ的消息本身需要持久化,因为MQ的容器服务没有配置好持久化,导致容器重启之后队列丢失问题产生。

7.4 Nginx配置不对的

腾讯云的Nginx是Linux上面部署的,所有的环境都是写在同一份文件中,后面因为Nginx需要进行容器化,所以需要将Nginx和前端Vue项目进行结合,这样必不可少的需要对Nginx配置进行修改,如果漏掉其中某一个配置将会导致服务器不可用。

7.5 并发负载问题

测试环境没有进行全量用户的冒烟测试(用户不一样,SQL所涉及的数据量也不一样),导致服务迁移过来之后,流量瞬间上来,导致PolarDB-X的计算节点内存一度溢出,解决办法只能先升级,后面再修改具体的问题SQL。

7.6 文件读取异常

我们系统有一些服务是需要将文件下载到磁盘,然后再进行处理,这样就涉及到IO的下载和读取问题。云平台迁移之后,发现文件读取的速度特别慢,下载的速度赶不上读取的速度,导致文件一直堆积到NAS云盘中。之前腾讯云是采用节点模式集群,每个节点的硬盘都是高性能硬盘,所以IO的读取/写入速度非常快,现在变成NAS之后,IO操作方面相对会慢很多,不过通过NAS的监控显示,NAS的瓶颈并没有到,所以只需要加大读取的线程数就可以解决这个问题。

NAS分为:普通、高性能、超高性能三种,所以购买的时候就需要确定好自己的服务到底需要哪一种配置,一旦确定下来之后,后期需要修改的成本就非常高了,所以在开始阶段一定要调研确定清楚。

7.7 多容器配置修改问题

如果容器多的话,一定要使用在线配置,你想想如果有100个服务,都需要修改配置,这个工作量是多么让人绝望的事情。

7.8 容器limit限制

容器一定设置limit限制,如果没有这个限制,容器会无限申请资源,最终导致容器所在的物理机器失控,最终导致容器不可用。

7.9 未设置监控报警

需要对容器设置内存、CPU、重启次数等各方面的报警,防止出现问题,相关开发人员还不知情。

7.10 就绪/存活检查

容器需要设置就绪检查和存活检查,就绪检查顾名思义,就是检查容器是否启动完成,这个就可以保证旧容器和新容器在切换的时候,可以无延迟快速切换,整个过程基本没有停顿,用户自然也感知不到重启卡顿的过程。存活检查就更简单了,就是每间隔一段时间就去检查一下容器是否正常在运行,如果不正常则进行重启。

Nginx容器必须设置就绪检查,如果一旦Nginx配置出现问题,导致容器启动失败,那将是毁灭性的灾难。

7.11 集群域名请求

服务间请求一定要使用服务名称来请求,不要写具体IP,不然如果IP发生变动,就需要重新修改IP,构建部署项目,如果调用者的数量很多,又没有做动态配置,那就非常麻烦。

八、总结

虽然在迁移系统之前,做了很多前期准备工作,但是在实际迁移过程中还是出现了很多问题,幸亏都一一解决了,也希望通过这次分享,大家可以在类似的迁移过程中,少走一些弯路。

-----------------------

公众号:林老师带你学编程

网站:wolzq.com

代码无非增删改查,关注老师给你Coding

林老师带你学编程https://wolzq.com 

 

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页