目 录CONTENT

文章目录

分库分表所面临的挑战

Administrator
2024-12-01 / 0 评论 / 0 点赞 / 9 阅读 / 0 字
温馨提示:
本文最后更新于2024-12-01,若内容或图片失效,请留言反馈。 部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

当MySQL等数据库单库单表能支撑的系统并发量和数据存储量存在瓶颈,在以往我们就不得不考虑使用分库分表技术。

但是引入分不分表技术之后不得不面对,系统复杂性以及数据一致性等问题。下面就介绍引入分库分表技术之后所带来的一些挑战。

分布式事务问题

在前面的剖析分布式事务的那些事儿一文中我们详细介绍了,分布式事务目前所有的实现方案。无论是使用CP还是AP模式下的实现方案都会给业务上带来不少的复杂性。我们先来介绍一下分库分表场景下是怎么遇到分布式事务问题的:

如用户领券场景,用户一次领取 3 张优惠券,系统写入 3 条优惠券记录和一条领券流水,使用 UserId 进行分库分表,可以保证同一个用户的 4 条记录路由到同一数据库,可使用 MySQL 本地事务即可保证数据一致性。

然而当同一个事务中多张表的分片属性不同时,难以保证这些表在同一个数据库内完成事务操作,势必会出现难以解决的分布式事务难题

如优惠券存在库存,在发券时需同时扣减券库存,库存粒度为券模版ID,用户可同时领取多个券模版的券。如何保证库存扣减、用户发券、领取流水等在同一个数据库内完成呢?优惠券和领券流水,基于 UserId 拆分数据库,但库存表无用户属性,只能使用券模版 ID分库。然而不同的分片属性,无法保证在同一个数据库完成事务操作,难以保证数据强一致性。

非分片属性的索引查询能力

电商交易场景一般使用 UserId 作为分片属性,联合索引的前缀都是UserId,但这并不绝对,交易场景中存在品牌、门店、司机、配送等其他维度。

如订单表使用UserId 作为分片属性进行分库分表,查询商家在最近 1 小时的订单如何实现呢?由于使用 UserId 分库分表,当使用商家 ID 查询时,需要查询所有的分库分表,这显然不现实。

业务侧有几种实现方案,1)使用商家 ID分库分表,异构另一份 MySQL存储 2)基于 ElasticSearch,异构另一种存储支撑其他维度的检索场景。

无论哪一种方案都会导致,数据一致性降低,但系统复杂度增加。

全局主键问题

MySQL 主键支持自增 ID,但是这一特性在分库分表后沦为鸡肋功能,系统需要分布式方式的 ID 生成器。如优惠券系统在分库分表后,优惠券 ID 需要借助分布式ID生成器生成全局唯一 ID。常见的实现方式包括 UUID、雪花算法、美团 Leaf、百度 UidGenerator等。除维护业务系统外,还需要维护其他纯技术类系统。

扩容问题

在系统建设之初,一个合格的架构师必须考虑到:未来数据量庞大后的存储扩容问题。这往往让人很难抉择,因为要权衡当下的硬件成本和未来扩容成本。

使用分库分表后,扩容非常困难。如8 个数据库,想继续拆分为 16 个数据库,一定会对业务造成影响,停机迁移是难以避免的问题,需要极多的运维工具保障扩容过程的安全性和快速性,做到对业务影响程度最低。因此扩容成本和风险都极高。

如果在系统建设初期就拆分为 16 个库,又会面临硬件和运维成本过高的问题。如果每一个业务在系统建设初期都如此铺张浪费,那么公司的硬件成本将极高。

分库分表需要持续造轮子

选择分库分表后,需要业务系统开发和接入很多轮子,包括

ShardingSphere、mycat等方便客户端接入分库分表。如果使用 ShardingSphere需考虑多种语言多套轮子,使用 Mycat代理层方案又会面临性能风险。

  • 分布式 ID 生成器生成全局 ID

  • 为了支持非分片查询,需要 DTS 消费binlog,异构存储For 查询。

  • 使用 ElasticSearch用于其他维度检索。

  • 分库分表管理后台支持查询数据、修改数据

  • 分库分表管理工具支持高效建表、修改表、加索引等 DDL 操作。(1000 张表后,手动建表不现实)

  • 。。。。

0
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin

评论区