亿级大表分库分表实战总结

分库分表的文章网上非常多 , 但是大多内容比较零散 , 以讲解知识点为主 , 没有完整地说明一个大表的切分、新架构设计、上线的完整过程 。
因此 , 我结合去年做的一个大型分库分表项目 , 来复盘一下完整的分库分表从架构设计 到 发布上线的实战总结 。

亿级大表分库分表实战总结

文章插图
 
1.前言为什么需要做分库分表 。这个相信大家多少都有所了解 。
海量数据的存储和访问成为了MySQL数据库的瓶颈问题 , 日益增长的业务数据 , 无疑对MySQL数据库造成了相当大的负载 , 同时对于系统的稳定性和扩展性提出很高的要求 。
而且单台服务器的资源(CPU、磁盘、内存等)总是有限的 , 最终数据库所能承载的数据量、数据处理能力都将遭遇瓶颈 。
目前来说一般有两种方案 。
一种是更换存储 , 不使用MySQL , 比如可以使用HBase、polarDB、TiDB等分布式存储 。
如果出于各种原因考虑 , 还是想继续使用MySQL , 一般会采用第二种方式 , 那就是分库分表 。
 
文章开头就说了 , 网上分库分表文章很多 , 对知识点讲解比较多 , 因此 , 本文将不再过多赘述分库分表方案的范式处理 。
而是专注于梳理分库分表从架构设计 到 发布上线的完整过程 , 同时总结其中的注意事项和最佳实践 。包括:
  • 业务重构
  • 技术架构设计
  • 改造和上线
  • 稳定性保障
  • 项目管理
尤其是各个阶段的最佳实践 , 都是血与泪凝聚的经验教训 。
2.第一阶段:业务重构(可选)
对于微服务划分比较合理的分库分表行为 , 一般只需要关注存储架构的变化 , 或者只需要在个别应用上进行业务改造即可 , 一般不需要着重考虑“业务重构” 这一阶段 , 因此 , 这一阶段属于“可选” 。
本次项目的第一大难点 , 在于业务重构 。
而本次拆分项目涉及到的两张大表A和B , 单表将近八千万的数据 , 是从单体应用时代遗留下来的 , 从一开始就没有很好的领域驱动/MSA架构设计 , 逻辑发散非常严重 , 到现在已经涉及50+个在线服务和20+个离线业务的的直接读写 。
因此 , 如何保证业务改造的彻底性、全面性是重中之重 , 不能出现有遗漏的情况 。
另外 , 表A 和 表B 各自有二、三十个字段 , 两表的主键存在一一对应关系 , 因此 , 本次分库分表项目中 , 还需要将两个表进行重构融合 , 将多余/无用的字段剔除 。
2.1 查询统计在线业务通过分布式链路追踪系统进行查询 , 按照表名作为查询条件 , 然后按照服务维度进行聚合 , 找到所有相关服务 , 写一个文档记录相关团队和服务 。
这里特别注意下 , 很多表不是只有在线应用在使用 , 很多离线算法和数据分析的业务也在使用 , 这里需要一并的梳理好 , 做好线下跨团队的沟通和调研工作 , 以免切换后影响正常的数据分析 。
2.2 查询拆分与迁移创建一个jar包 , 根据2.1的统计结果 , 与服务owner合作将服务中的相关查询都迁移到这个jar包中(本项目的jar包叫projected) , 此处为1.0.0-SNAPSHOT版本 。
然后将原本服务内的xxxMApper.xxxMethod( ) 全部改成projectdb.xxxMethod( )进行调用 。
这样做有两个好处:
  • 方便做后续的查询拆分分析 。
  • 方便后续直接将jar包中的查询替换为改造后 中台服务 的rpc调用 , 业务方只需升级jar包版本 , 即可快速从sql调用改为rpc查询 。
这一步花了几个月的实际 , 务必梳理各个服务做全面的迁移 , 不能遗漏 , 否则可能会导致拆分分析不全面 , 遗漏了相关字段 。
查询的迁移主要由于本次拆分项目涉及到的服务太多 , 需要收拢到一个jar包 , 更方便后期的改造 。如果实际分库分表项目中仅仅涉及一两个服务的 , 这一步是可以不做的 。
2.3 联合查询的拆分分析根据2.2收拢的jar包中的查询 , 结合实际情况将查询进行分类和判断 , 把一些历史遗留的问题 , 和已经废弃的字段做一些整理 。


推荐阅读