曾几何时,“并发高就分库,数据大就分表”已经成了处理 MySQL 数据增长问题的圣经。
面试官喜欢问,博主喜欢写,候选人也喜欢背,似乎已经形成了一个闭环。
但你有没有思考过,分库分表真的适合你的系统吗?
分表
在业务刚刚发展起来的时候,流量全部打到了一个 MySQL 上,用户信息全落到了 user 表。
后来,user 表的数据量越来越大了。
于是,你做了一次垂直拆分,将原来的 user 表拆分成了新的 user 表和 user_details 表。
这样一拆之后,用户的信息分散到两个表,user 表的数据量一下就变小了,user 表数据量过大的问题暂时就解决了。
但随着业务的发展,线上的流量越来越大,单个 MySQL 已经扛不住流量的压力了。
单个库承受不住压力的时候,就需要分库了。
分库
JDBC 代理模式是一种无中心化的架构模式。ShardingSphere-JDBC 就是 JDBC 代理模式的典型实现。
通常以 jar 包形式提供服务,让客户端直连数据库,这种模式无需额外部署和依赖,可理解为增强版的 JDBC 驱动。
JDBC 代理模式虽然简单,但违背了 DB 透明的原则,侵入性比较高,需要针对不同的语言编写不同的 Driver。
美团的 Zebra、MTDDL,阿里 TDDL 都是基于这种模式的实现。
DB 代理模式
DB 代理模式是中心化的架构模式。ShardingSphere-Proxy 就是 DB 代理模式的经典实现。
这种模式旨在实现透明化的数据库代理端,并独立于应用部署,因为独立部署,所以对异构语言没有限制,不会对应用造成侵入。
DB 代理模式比 JDBC 代理模式消耗的连接数会少,相对来说性能也会更好。
但中心化的设计也带来了单点的问题,为了保持高可用和高性能,还需要引入 LVS/F5 等 VIP 来实现流量的负载均衡,如果跨 IDC,还依赖诸如 DNS 进行 IDC 分发,大大拉长了应用到数据库的链路,进而提高了响应时间。
阿里的 MyCat、美团的 Meituan Atlas 和百度 Heisenberg 就是基于 DB 代理模式的实现。
Sharding On MySQL
Sharding On MySQL 相当于屏蔽了分库分表的操作,是运维和中间件结合的沉淀,比较典型例子是阿里的 DRDS。
这种模式让分库分表变得模糊,对应用来说,更像是一个封装了 MySQL 的新型数据库。
虽然用户使用变得更简单了,但简单的背后是运维的沉淀,分库分表该存在的问题它依然存在。
分库分表的成本
实现分库分表的方式有很多,但不同模式的实现似乎都是在弥补 MySQL 不支持分布式的缺陷。
分库分表这种强行让 MySQL 达到一个伪“分布式”的状态,也带来了一些新的问题,比如: