200张表,单表记录过亿,10多年核心老系统的重构之旅

简介: 200张表,单表记录过亿,10多年核心老系统的重构之旅

一、什么时候需要重构老系统

老系统重构,让大家又喜又悲,喜的是程序员,悲的是业务。
程序员为啥“喜”:多年前的老技术,以及各种历史原因导致的遗留代码、不需要的业务代码混杂在一起,维护起来,那个酸爽,我相信老司机都懂的。
业务为啥“悲”:业务会觉得一堆技术人重心都去发明新轮子,新需求迭代必然受挫。
那什么时候可以进行重构?本着技术需要领先业务“一小步”,综合成本和收益、boss意愿、业务的淡旺季、团队对新框架的掌握熟练度等因素,考虑清楚,方可计划和实施。
为了追赶业务的发展,笔者有幸成功主导过公司几个历史大系统的重构,接下来将讲述一个核心系统的重构之旅。
二、被重构系统的现状

此次重构的系统是10多年前的老系统,简单描述,有如下特征:

  • 单体应用,200多张表,千万级别记录的表上百个,部分表记录已上亿;

  • 要的和不要的业务功能都参杂其中,毕竟那个时候互联网群雄逐鹿,讲究天下功夫,唯快不破,没有严格实施“童子军规”,着实理解;

  • 作为核心系统,外部系统千丝万缕,给人麻麻的感觉。


三、期望达到的目标

  • 不影响业务的正常使用
  • 不影响其他系统的正常调用和运行
  • 技术架构从单体架构升级到微服务架构


因为微服务需要拆分数据库,即从一个大数据库里面,将本系统的表拆到新库,而且此次涉及跨机房(运维哥哥要求的)。


所以,技术上涉及数据迁移并升级,以及系统架构和代码升级两部分。


四、如何去重构为了达到目标,我的方法如下:


1. 不影响业务的正常使用即使用新架构,全新开发一个系统,数据库也使用新的(即将数据迁移并表结构升级),老系统和老数据库正常运行,等新系统开发部署好,再直接通过运维切换到新域名即可


2. 不影响其他系统的正常调用老系统之间交互方式梳理清楚,有两种方式:1)老接口不变,新系统继续兼容老系统的接口调用,比如是HTTP,Hession,RMI等;2)其他系统和本系统交互的部分,他们也愿意一起升级,就使用新接口方式,那是最好的,具体看场景


3. 技术架构从单体架构升级到微服务架构1)数据迁移并升级由于跨机房,源数据库数据量比较大(几百G),并且新库我们做了部分表结构调整,在保证老数据库不停机的情况下,我们使用了zookeeper+kafka+canal+otter等组件集群方式搭建,分两个阶段完成数据迁移,即存量数据和增量数据两阶段处理。

具体操作的流程图如下:


image.png


a:通过dump表打包,节约网络带宽,同时记录dump的位点A,方便后续作为增量的起始点;
b:中间备份库作为一个临时库,和新数据库在同一个服务器,这样DBA在临时库改造大表,不影响业务,改造好了,可以直接剪切到新数据库;如果涉及表拆分和复杂业务逻辑,就需要程序来做存量同步;
c:在存量都搞定后,再做老数据库从位点A到新数据库的同步,无业务逻辑,并且可以直接字段对应进行数据同步,使用otter解决,而有业务逻辑等,则使用canal解析bonlog,将数据存到kafka,再通过程序来消费kafka数据,将处理后的数据写入新数据库;
d:待新老数据库数据保持一致后,上线新应用系统,通过配置中心切数据库,并确保切数据后,数据表无“双写”存在。
值得提醒的是:
a:一般建议重构时,没有绝对把握,尽量不做表结构修改,因为这样需要搭建对系统本身的运转和业务的理解足够深入,至少各个字段的生命周期;
b:需要充分做好源字段和目标字段的仔细梳理和测试,这里有巨大的工作量;
c:有些表数据会有依赖,所以需要注意同步时表的先后顺序;
d:不要低估在大表上加新索引的时间(当然,如果能够提前做数据归档那是最好的)。
2)系统架构和代码升级
微服务我们按照业务功能竖切,以及通用非业务功能的横切,建议初期不要切太细,掌握一个度。
由于我们使用Spring Cloud这一套,网上相关资料都比较齐全,我就不详述了。
在这里,需要重点给大家分享做好系统功能分析,可以按内部和外部两个维度分析:
a:内部分析

  • 内部功能的代码分析
  • 梳理出在使用的表清单和业务逻辑
  • 内部Job,含job调度中心和线上服务器各个用户下的cron job等
  • 中间件的使用:MQ,Redis等
  • 调用第三方的内容:外部翻译接口,支付接口等


b:外部调用分析

  • 日志分析:access log等追踪访问的IP,追溯对应调用方
  • 老数据库表访问来源分析:数据库上加日志分析JDBC直连
  • 其他系统对调用API接口的追踪和梳理等


五、感想
重构老系统,犹如在高速公路上开车换胎:


image.png


所以,为了安全起见,建议大家做好以下内容:

  • 事先尽量想明白重构的边界,是部分独立功能重构,还是整个系统重构;
  • 并提前给业务打好预防针,争取上级领导们的大力支持;
  • 并团队自身做好充分准备工作,分析工作,以及其他软技能,比如上下游系统沟通和协调等工作,都尽量做细,正如《孙子兵法》说:知己知彼,百战不殆。



相关文章
|
21天前
|
存储 监控 测试技术
|
6天前
|
SQL 缓存 监控
SQL性能提升指南:五大优化策略与十个实战案例
在数据库性能优化的世界里,SQL优化是提升查询效率的关键。一个高效的SQL查询可以显著减少数据库的负载,提高应用响应速度,甚至影响整个系统的稳定性和扩展性。本文将介绍SQL优化的五大步骤,并结合十个实战案例,为你提供一份详尽的性能提升指南。
18 0
|
3月前
|
存储 SQL 关系型数据库
(二十三)MySQL分表篇:该如何将月增上亿条数据的单表处理方案优雅落地?
前面《分库分表的正确姿势》、《分库分表的后患问题》两篇中,对数据库的分库分表技术进行了全面阐述,但前两篇大多属于方法论,并不存在具体的实战实操,而只有理论没有实践的技术永远都属纸上谈兵,所以接下来会再开几个单章对分库分表各类方案进行落地。
319 3
|
6月前
|
存储 关系型数据库 MySQL
表设计的10条军规
本文主要介绍了数据库建表的18个小技巧,包括:名字的命名规范、字段类型的选取、字段长度的控制、外键的使用、索引的创建、主键的选择、字段个数的限制、存储引擎的选择、时间字段的处理、金额字段的保存、冗余字段的使用以及注释的添加。作者强调了命名的重要性,如使用小写字母、避免全大写、使用下划线分隔等,并提倡使用NOT NULL和默认值,合理选择字段类型如datetime、decimal等,以及避免使用过多的字段和索引。此外,还提到了字符集和排序规则的选择,以及大字段和冗余字段的处理。
189 1
|
存储 监控 关系型数据库
传统库分表麻烦查询慢?TDengine 如何解决“搜狐基金”的应用难题
搜狐基金团队使用的 MySQL 数据库在面对海量数据时存在能力瓶颈,在此背景下,其决定基于 TDengine 尝试一下全新的方案。
135 0
|
存储 关系型数据库 MySQL
108分布式电商项目 - MySQL优化(插入数据优化)
108分布式电商项目 - MySQL优化(插入数据优化)
52 0
|
存储 JavaScript Java
亿级别大表拆分 —— 记一次分表工作的心路历程
亿级别大表拆分 —— 记一次分表工作的心路历程
|
canal 中间件 Java
阿里终面:业务主表读写缓慢如何优化?
阿里终面:业务主表读写缓慢如何优化?
百亿数据分库分表核心流程详解
前言 俗话说:面试造火箭,入职拧螺丝。尽管99.99%的业务都不需要用到分库分表,但是分库分表还是频繁出现在大厂的面试中。 分库分表涉及到的内容非常多,有很多细节,如果在面试中被问到了,既是挑战,也是机会,如果你能回答好的话,会给你的面试加很多分。 由于业务量的关系,绝大部分同学都很难有实际分库分表的机会,因此很多同学在碰到这个问题时很容易懵逼。 因此今天跟大家分享一下分库分表的相关知识,本文内容源于实际高并发+海量数据业务下的实战和个人的思考总结。
|
存储 算法 NoSQL
想要实现在时序场景下“远超”通用数据库,需要做到哪几点?
近年来,随着物联网技术和市场的快速发展、企业业务的加速扩张,时序数据的处理难题也越来越受到行业和企业的重视,时序场景下通用型数据库步履维艰,各种时序数据库产品应运而起。但是,做一个优质的时序数据库真的很容易吗?本篇文章将从数据库开发者的角度,解剖时序场景下的数据处理需求、分析时序数据库设计思路,给到读者一些硬核技术思考。
173 0
下一篇
无影云桌面