一、前言
这篇文章总结了我在多年负责大规模复杂系统重构中的经验。距离我上一次写浅谈这些年做过的千万级系统重构的文章已经过去近两年,回顾这段时间,我也在不断进步、摸索,并对架构进行了优化,同时也参与了一些新的重构项目。本文将再次总结我在这些项目中的经验分享!
二、那些年、重构之路
项目 | 公司 | 时间 | 投入人力 | 技术栈 | 项目亮点 | 相关链接 |
千万级订单重构 | 公司A | 201606~201609 | 10人 | PHP/Redis/RabbitMQ/ MongoDB/MariaDB |
自研PSF框架,分片1024库,订单表重新设计,数据双向同步,接口按流量灰度化,订单表和冗余表的分片设计,数据汇总采用MariaDB多源复制架构 | https://www.admin5.com/article/20160705/673189.shtml |
亿级影像存储重构 | 公司B | 201805~201807 | 3人 | Java/c/Redis/MySQL/ | 存储与活动/赛事分离,分512个库,根据图片MD5 % 512 分片, 数据库集群分为2组(0~255, 256 ~ 511),自研人脸识别引擎,识别精度80% | 可惜这个时候还没有开始写文章,所以没有链接 |
订单分库分表重构 | 公司C | 202107~202108 | 4人 | Java/RocketMQ/MySQL/ES | 分8个库,256张表,按用户 user_id % 256 分片,分为8组(0~31, 32 ~63 …. 224 ~ 255) ,重构后系统可支撑每天2亿订单,写RT约2ms,读RT约1ms, 重构性能提升10倍,实际已突破每天2500万订单,系统整体突破15W/QPS | 浅谈订单重构之路 |
围栏系统重构 | 公司C | 202205 | 2人 | Java/MySQL | 支持水平扩展,性能提升40倍,建设空间索引,大幅减少部署机器数量 | 性能提升40倍——线上真实重构案例分享 |
乘客排队系统重构 | 公司C | 202206 | 2人 | Java/MySQL/Redis | 排名与存储分离,使用MySQL进行分表,支持无限制排队和灵活的挑单策略 | 线上真实排队系统重构案例分享——实战篇 |
关联网络-图数据库系统重构 | 公司D | 202306~202308 | 4人 | Java/Mysql/NebulaGraph /RocketMQ/Kafka/Hbase |
使用NebulaGraph替代OrientDB作为图数据库存储,将原来Scale语言改造为Java,支持图数据库水平扩展,服务具备弹性伸缩能力 | 图数据库系统重构之路:从OrientDB迁移到NebulaGraph 真实案例分享 |
三、什么是重构之道
1、重构的原则
- • 重构不等于重写,而是基于原有业务系统的基础上进行改造,需尽量保持对外接口不变和业务逻辑的稳定性,并且需要平滑过渡。
- • 不要为了重构而重构,需明确重构的目的并且能解决当前问题以及未来可能出现的瓶颈。
- • 重构需要站在前人的肩膀上,尊重历史架构的合理性,同时遇到问题要用开放的态度去解决。
- • 细节决定成败,在重构过程中要对可能出现的问题保持警惕,不要抱有侥幸心理。
2、为什么要重构
- • 性能瓶颈:原有数据库量太大,或服务无法满足当前业务发展的需求,并且可能通过加机器资源都无法解决。
- • 解耦:例如,需要将单体架构拆分为微服务来降低耦合性,系统发版互相影响。
- • 局限性:原有架构存在诸多限制并且当前无法解决等问题。
注:只有明确了痛点所在并且新方案能够全面解决问题,同时考虑到未来潜在的瓶颈,并给出相应的解决方案,才会是最佳的重构策略。
3、重构的套路
在进行重构时,需要考虑以下几个关键因素。之前我也在重构系列文章中介绍过重构的相关内容。
- • 灰度方案:确定何处执行灰度以及如何实施。
- • 双写方案:判断何时需要进行双写操作,如何实现双写(接口层、MQ异步写入、监听binlog等)。
- • 数据同步方案:确定是否需要进行数据同步,全量和增量数据如何实现。
- • 改造方案:确保不会破坏原有的业务流程,解决数据分片(分库分表)后的查询问题。
- • 回滚方案:通过配置中心开关控制,能够快速回滚到之前的版本。
- • 数据对比方案:在数据库层面和接口层面如何进行数据对比。
四、总结
重构的魅力在于它能够挑战技术人员的极限,并且会遇到各种未知的问题,因为老系统往往承载着很多的历史包袱和未知问题。