起源
在进行架构转型与分库分表之前,我们一直采用非常典型的单体应用架构:主服务是一个 Java WebApp,使用 Nginx 并选择 Session Sticky 分发策略做负载均衡和会话保持;背后是一个 MySQL 主实例,接了若干 Slave 做读写分离。在整个转型开始之前,我们就知道这会是一块难啃的硬骨头:我们要在全线业务飞速地扩张迭代的同时完成架构转型,因为这是实实在在的”给高速行驶的汽车换轮胎”。
为了最大限度地减少服务拆分与分库分表给业务带来的影响(不影响业务开发也是架构转型的前提),我们采用了一种温和的渐进式拆分方案:
-
对于每块需要拆分的领域,首先拆分出子服务,并将所有该领域的数据库操作封装为 RPC 接口;
-
将其它所有服务中对该领域数据表的操作替换为 RPC 调用;
-
拆分该领域的数据表,使用数据同步保证旧库中的表与新表数据一致;
-
将该子服务中的数据库操作逐步迁移到新表,分批上线;
-
全部迁移完成后,切断同步,该服务拆分结束。
这种方案能够做到平滑迁移,但其中却有几个棘手的问题:
-
旧表新表的数据一致性如何保证?