MySQL单表数据量超过5000万行、单库磁盘逼近物理上限,读写延迟开始恶化,这是分库分表决策的临界点。拆分方案分垂直与水平两类:垂直按业务域切库,水平按分片键打散数据。分库分表一旦上线,扩容与数据迁移的成本极高,拆分键设计、扩容策略必须在动手前想清楚。
拆分时机判断:什么信号出现才需要拆
不要过早拆分。三个信号同时出现再动手:单表行数持续增长且超过5000万,B+树层级加深导致索引扫描产生大量随机IO;慢查询里深分页与聚合占比上升,读写分离已无法缓解;磁盘与连接数成为容量瓶颈,硬件升级成本超过改造投入。如果只是读压力大,先读写分离、缓存与索引优化;只有单表写入吞吐真的扛不住,才值得走分库分表这条重路线。
分片键设计:决定数据分布均匀度与查询效率
分片键决定行落在哪个库哪个表,选错了高频查询会演变成跨分片广播。原则:高频查询条件字段优先。电商订单表选user_id,保证用户查自己的订单路由到单分片:
# ShardingSphere YAML配置示例
tables:
t_order:
actual-data-nodes: ds_$->$->{0..1}.t_order_$->{0..3}
database-strategy:
standard:
sharding-column: user_id
sharding-algorithm:
inline:
algorithm-expression: ds_$->$->{user_id % 2}
table-strategy:
standard:
sharding-column: user_id
sharding-algorithm:
inline:
algorithm-expression: t_order_$->$->{user_id % 4}
注意路由隐患:管理员按订单号查询,订单号不在分片键里,SQL会广播到全部分片再归并。常用解法是基因法——把user_id的后几位编入订单号,从订单号反解分片路由;或维护一张异构索引表。跨维度的需求(按商户维度统计)交给异构的OLAP库,别让分片库扛分析负载。
ShardingSphere接入:JDBC驱动层的透明分片
ShardingSphere-JDBC作为JDBC增强驱动嵌入应用,无需额外部署代理,适合绝大多数团队:
spring:
shardingsphere:
datasource:
names: ds-0,ds-1
ds-0:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://mysql-0:3306/order_db
rules:
sharding:
sharding-algorithms:
db-mod:
type: MOD
props: { "sharding-count": 2 }
tables:
t_order:
actual-data-nodes: ds-$->{0..1}.t_order_$->{0..3}
应用代码照常写SQL,路由、归并、分布式主键全部由驱动层完成。全局主键用内置雪花算法,避免各分片自增冲突。跨分片查询结果归并发生在内存,ORDER BY分页要控制limit深度,防止归并OOM。
平滑扩容与数据迁移:双写灰度的标准动作
分片数从2扩到4不是改配置重启这么简单。标准流程:新旧集群双写(旧库为主),存量数据按新分片规则迁移并校验(checksum比对),灰度读切换校验一致性,全量切读后停旧库写入。迁移工具用ShardingSphere-Scaling或DataX,校验环节不可省——数据迁移事故几乎都出在校验跳步。分片数初始就规划为2的幂,扩容翻倍时路由算法只需右移一位,避免全量重新分布。
分库分表后的运维代价清单
拆分不是终点而是新起点:跨分片JOIN消失,ER图里的关联要么冗余字段要么异构查询;分布式事务引入Seata等组件;备份从单库mysqldump变成分片逐一备份再汇总校验;监控要按分片维度建延迟与容量视图。所有这些运维成本在做容量规划时一并计入,拆分的收益才能算清账。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/mysql-fen-ku-fen-biao-shi-zhan-shardingsphere-chui-zhi-yu/