记录一次普通且艰难的上线

44 阅读6分钟

一、问题背景

​ 公司有一套采集系统,用于收集一些用户行为来做用户画像之类的应用,但是因为公司的项目较多,而且用到这套采集系统的地方也多,前期对采集字段命名不规范,因此这次的需求就是修改三个采集字段的名称然后再新增一个字段即可。听上去感觉很简单,但是真的这么简单吗?

二、需求

​ 这里说一下需求,就是把采集系统和统计系统中涉及到app_key、device_id和article_id的字段分别修改为site_id、token_id和resource_id,然后再新增一个resource_type字段即可。

下面是采集系统和统计系统的架构设计图

系统架构图.png

没错,之前的人使用mysql去存储这种大数据,感觉不太对,问过leader了,说是之前就是这么设计,不想使用mongoDB啥的增加成本。

三、途中遇到的问题

(1)数据库大表修改字段的问题

​ 首先是track(采集)库,架构上使用了mycat按照月份来存储每个月的数据,这个库中每个月主要存储信息的表为msg20238,A服务器上到月末该表的大小接近200G,刚接触该需求的时候是8月初。而visit(统计)库中也有一张100多G的表,几张几十G的表,而且没有使用mycat进行划分,只是用定时任务删除三个月前的数据,但还是数据量大。因此直接使用sql修改表字段的话肯定会导致锁表影响业务。

(2)涉及到的项目太多

​ 刚开始前一两周因为对采集系统和统计系统不熟悉,以为后端只要修改采集系统和统计系统相关的四个项目即可,后来问之前负责采集、统计系统的同事才得知还有七个后端项目、三个其他的数据库与这次修改字段的需求有关。因此直接全部上线有极大概率会导致系统出问题。

(3)部署问题

​ 这套采集和统计系统需要部署在三个不同的地方,并且三个地方都有自己的开发,因此部署之前还需要很多额外成本与他们那边的人进行沟通。

四、解决方案

(1)关于数据库大表修改字段的解决方案

​ 我在网上找的方案是使用pt-online-schema-change工具进行不锁表修改字段,大致的原理是先新建一张表字段修改后的表,然后再将原来的表数据慢慢拷贝到新表当中,最后全部复制完成之后先将旧表修改名称,然后将新表改成原来的名字,再将改名的旧表删除,这样就实现了不锁表修改字段的目的。

​ leader也给出了另一个建议,在9月初上线,这样的话采集库里的数据全部是落在新表msg20239中,这个时候表数据量小,方便修改。

(2)涉及到的项目太多的解决方案

​ 因为该需求涉及到了十多个项目,一次性上线风险很大,所以leader建议采用兼容的方式分步上线。该需求涉及到的项目可以分为三类,采集系统(2个)、统计系统(2个)、其余与统计系统相关的项目(7个)。

​ 第一步可以先将其余与统计系统相关的项目做兼容处理,也就是在这些项目的kafka消费者消费信息的地方,将原本修改字段后的数据再还原回去,这样就不影响原来的业务了。

​ 第二步则是按照第一步的方式将统计系统中涉及的项目也做这种兼容处理。

​ 第三步就可以直接处理并上线采集系统了。

(3)部署问题

​ 这个问题或许没什么有效的解决办法,就只有和其他地方的人多沟通了。

五、上线步骤以及遇到的坑

(1)在八月份的时候先上线了统计系统(2个)、其余与统计系统相关的项目(7个)的兼容版本,以防止采集系统上线之后对后续的流程造成影响。

(2)在9月1号下午1点,我们先关闭了采集系统里kafka的消费程序,然后使用insert msg20238_bak(....) select ... from msg20238的sql备份8月份的采集数据,此时msg20238表数据量为200G左右,自己预计备份12个小时应该就差不多了,结果运维在9月2号晚上12点告诉我还没备份完成,2号中午12点运维告诉我sql备份失败(其实没有备份失败,还在备份中,但给出了提示,肯能是备份时间太长了),这时已经显示备份到了127G。

(3)2号中午12点在msg20238表确认使用sql备份失败后,我再次检查代码,确认没有程序会使用到该表之后就直接使用pt-online-schema-change修改msg20239表、其余两张大小在7G左右和一张十几条数据的表。但在修改过程中发现修改速度异常缓慢,直接将pt工具的chunk-size自动减少到1,后面我去检查mysql里面的事务,发现(2)中拷贝msg20238的任务还在进行,于是我做出了一个十分蛋疼的决定,让运维关闭这个事务,然后发现这个拷贝的事务进入了回滚状态,直到9月6号晚上才回滚完成。

(4)2号下午1点,关闭拷贝的事务之后pt工具修改速度慢慢变快(虽然也没快多少),直到晚上11点才完成表修改。结果准备上程序的时候才发现A方的运维只在jenkens上配置了A方的测试服务环境,于是又打电话叫另一位运维帮忙配置A方该项目的正式服环境,搞到晚上12点才差不多上线完成。

(5)上面的步骤只是采集系统在A方的上线流程,该流程还需要在B、C两方再走一遍,不过因为B、C两方采集库的数据量不是很大,因此上线比A方块很多,4号和5号就上线完成了B、C两方的采集系统。

六、后续

以上步骤只是本次字段修改工作的后端部分,而且也不是很完整的上线,但也只能先做到这一步。前端部分需要修改涉及到的项目更多,可能也有十几个,在6号的时候就只上线了一个修改好的前端,新老数据也能实现兼容,后续的话就安排我跟进这些前端项目