知识卡片
业务分库分散存储压力,但引入join、事务与成本三重代价
内容
[[读写分离原理及”主从集群”与”主备集群”的本质区别]]只分散了访问压力,没有分散存储压力,当单表数据量达到千万甚至上亿级别时,单台数据库服务器本身会成为瓶颈——具体表现为读写性能随数据量增大而下降(即使有索引,索引本身也会变大导致变慢)、数据文件过大导致备份恢复耗时剧增、以及极端情况下(如机房火灾)单机数据量越大丢失的数据就越多。业务分库正是应对存储压力的第一种手段:按业务模块把数据拆到不同数据库服务器(如电商网站把用户、商品、订单数据分别放在三台不同服务器上),但这个拆分同时引入了三个新问题。第一是join操作失效:原本在同一个数据库内一次join就能完成的查询(比如”查询购买了化妆品的用户中的女性用户”),分库后订单数据和用户数据不在同一个库,只能先查订单库拿到用户ID列表,再拿这批ID去用户库二次查询,实现复杂度明显上升。第二是事务失效:原本同一数据库内多张表可以放在同一个事务里保证一致性(比如下单时扣库存和生成订单要么都成功要么都失败),分库后无法再用数据库原生事务保证跨库一致性,虽然有分布式事务方案(如MySQL的XA),但性能代价太高,与追求高性能存储的初衷相悖,实践中往往只能靠业务程序自己模拟事务语义(先扣库存、扣成功再生成订单、订单失败再把库存加回去),一旦业务程序自身在补偿环节又出异常,就会留下需要人工介入修复的库存不一致。第三是成本上升:原本一台服务器能搞定的事,分库后至少要三台,考虑主备容灾的话可能直接从两台变成六台。
参考来源
- 位置:《从零开始学架构》第15讲《高性能数据库集群:分库分表》"业务分库"(源文件:_epub-src/OEBPS/text00001.html)
- 结论依据:原文说明单机存储瓶颈"数据量太大,读写的性能会下降……数据文件会变得很大,数据库备份和恢复需要耗费很长时间……数据文件越大,极端情况下丢失数据的风险越高",并展开join操作问题"无法使用 SQL 的 join 查询"、事务问题"无法通过事务统一修改……但性能实在太低,与高性能存储的目标是相违背的"、成本问题"本来 1 台服务器搞定的事情,现在要 3 台",直接支撑本卡片结论。
- 原始内容:业务分库指的是按照业务模块将数据分散到不同的数据库服务器……业务分库后,原本在同一个数据库中的表分散到不同数据库中,导致无法使用 SQL 的 join 查询……本来 1 台服务器搞定的事情,现在要 3 台,如果考虑备份,那就是 2 台变成了 6 台。