十几年前我刚入行时,公司项目用的是台破旧的单机MySQL,每天半夜跑批处理,数据库CPU直接飙到99%,老板急得在办公室转圈。那时候没谁跟你提什么分布式,能凑合用一台机器跑完业务就是谢天谢地。可到了今天,随便一个电商大促,几百万用户同时点“购买”,单库单表根本扛不住。数据库架构的演进,说白了就是被业务逼出来的。你没法指望一台机器永远够用,也没法指望一个表结构永远适配所有场景。从单库到分布式,这条路不是谁想走,是不得不走。

单库时代,一切都很简单。一个数据库实例,一张表,一个连接池,业务逻辑直接往里怼。增删改查,JOIN查询,事务提交,全都依赖数据库自身的能力。但简单背后藏着大坑。一旦数据量突破千万级,查询开始变慢,索引再不灵光,慢查询日志里全是红色警告。更可怕的是单点故障,数据库挂掉,整个业务瘫痪。我见过一个做电商的朋友,双十一凌晨,数据库直接宕机,运维手忙脚乱重启,结果数据不一致,订单丢了上百条。老板气得拍桌子,技术人员连夜写数据恢复脚本,折腾到天亮。单库架构最大的问题,就是它把所有鸡蛋放在一个篮子里,篮子破了,蛋全碎。
为了解决单点故障和性能瓶颈,读写分离应运而生。主库负责写,从库负责读,数据通过异步复制同步。这个方案听着简单,实际坑不少。主从延迟是头号难题,你刚在主库写入一条订单,用户刷新页面,从库还没同步,页面显示“订单不存在”,用户直接爆粗口。另一个问题,是主库仍然是写瓶颈。一旦写入量暴增,主库CPU飙升,从库复制也跟着延迟,整个系统陷入恶性循环。我参与过一个项目,单表日增百万条数据,主库磁盘IO直接打满,运维只能半夜扩容硬件。读写分离只能解决读压力,写压力依然是悬在头上的刀。
当读写分离也撑不住,分库分表就来了。最常见的做法是按用户ID或者订单ID做分片,把数据分散到多个库多个表里。这样每个库的表数据量可控,查询和写入压力分散。但分库分表不是万能药。跨库跨表的JOIN查询几乎没法用,必须业务层做联表查询或者做数据冗余。分布式事务更是头疼,一个订单操作涉及库存、积分、物流三个库,要么用两阶段提交,要么用TCC补偿。两阶段提交性能差,TCC实现复杂。我见过一个项目,分库分表后,业务代码里到处都是分片键判断逻辑,一个简单的列表查询,要写几十行代码判断数据落在哪个库。开发效率直线下降,bug多到修不过来。
分库分表搞到一定规模,你会发现,光靠业务层硬编码分片规则,迟早要崩溃。这时候,分布式数据库中间件登场了。MyCAT、ShardingSphere、Vitess这些工具,帮你屏蔽分片逻辑,业务代码看起来还在操作单库,实际数据已经分布在几十台服务器上。中间件负责路由、合并结果、处理分布式事务。但中间件不是银弹。路由算法一旦设计不合理,数据倾斜严重,有的库闲得发慌,有的库忙到宕机。而且中间件本身也是单点风险,一旦挂了,整个数据库集群瘫痪。我亲历过一个事故,ShardingSphere的配置错了,分片键写成了时间戳,结果所有数据都路由到同一个库,其他库空转。当天晚上,那个库的磁盘直接爆满,业务停摆两小时。
真正成熟的分布式数据库架构,是分布式数据库原生系统。比如TiDB、CockroachDB、OceanBase这些,它们从底层设计就是分布式的,数据自动分片、自动复制、自动故障恢复。你不需要手动配置分片规则,不需要操心主从切换,不需要写复杂的补偿事务。这些系统把分布式细节完全封装起来,让开发者像用单库一样用分布式数据库。我有个朋友在金融公司做架构升级,从MySQL迁移到OceanBase,数据量从几十TB增长到PB级,查询延迟反而降了30%。分布式数据库原生的好处是,你不需要在业务代码里写分片逻辑,不需要操心数据倾斜,不需要手动扩容。但代价是学习成本高,运维复杂,硬件资源消耗大。
从实战角度看,没有完美的架构,只有合适的架构。小公司初创期,单库足以支撑,别上来就搞分布式,那是给自己找麻烦。用户量百万级,读写分离加缓存能解决大部分问题。用户量千万级,分库分表加中间件是性价比最高的方案。用户量亿级,或者数据一致性要求极高,分布式数据库原生系统才是最终选择。我见过太多公司,业务还没跑稳,就花大价钱上分布式数据库,结果运维搞不定,性能反而更差。数据库架构演进的核心,不是追求技术最先进,而是让技术匹配业务发展的节奏。从单库到分布式,每一步都是被逼出来的,但每一步也都有它的代价。
说句掏心窝子的话,数据库架构没有终点。今天你用了分布式原生数据库,明天可能又要面对云原生、Serverless、无服务器数据库。技术永远在变,但底层逻辑不变:数据要可靠,查询要快,扩容要灵活。与其追逐时髦架构,不如把现阶段的业务吃透,把数据模型设计好,把索引建对,把慢查询优化掉。很多问题根本轮不到分布式来解决,单库优化到位,照样能扛千万级流量。分布式架构是武器,不是第一选择。从单库到分布式,不是技术炫耀,是业务倒逼。记住这点,你的数据库架构演进之路,才不会走歪。


