关系型数据库分库分表、水平分和垂直分、客户端实现路由和proxy实现路由
分库分表:
分库
是将数据拆分到多个数据库实例中的技术。每个数据库实例存储部分数据,以减少单个数据库的负载。分库通常用于大规模分布式系统中,以提高系统的扩展性和性能。
分库后的问题:
1.为了性能考虑,分库一般是值将表分到不同的物理机上,这样就没办法跨库查询(如果是一个server上的多个database,部分数据库产品支持跨库联合查,放到一个server上对性能提升不大)
2.事务问题:数据库事务是基于连接的,不同的库不能使用数据库事务。
分表
是将一个大表拆分为多个小表的技术。每个小表存储部分数据,以减少单个表的负载。分表可以在同一个数据库中,也可以在多个数据库中。
分表后的问题:
1.分表不分库:不能实聚合合查询,虽然理论可以用union来实现查询,但是索引会失效,union方案实际应用中根本行不通。
2.分库+分表:不能实聚合合查询,union也用不了。
水平分和垂直分
数据库只有垂直分:比如用户一个单独库, 订单一个单独库。
表-垂直分: 用户表可以根据字段垂直分成多个表,比如用户有ID、姓名、性别、个人介绍等,个人介绍是text类型的,那么为了性能我们可以把个人介绍等大字段单独分到子表里去。
表-水平分:根据某个字段按照某个规则水平分,假如用户表ID是自增的,那么可以100W分一张表。
分库分表带来的技术挑战:
分布式事务问题
在进行复杂操作时,如用户同时领取多张优惠券,可能涉及多个表的分片属性不一致,导致无法在同一数据库内完成事务操作。这种情况使得数据一致性受到威胁,最终业务侧可能不得不做出妥协,采用最终一致性解决方案。然而,这通常意味着牺牲了一部分实时性,以满足系统的整体性能和稳定性需求。
索引查询能力下降
分库分表后,查询特定条件下的数据可能变得复杂。例如,在电商系统中,若订单表基于用户ID分库分表,查询特定商家在特定时间内的所有订单将变得困难。这是因为查询需要跨多个数据库或数据表进行,增加了查询的时间和成本。使用异构数据库或依赖ElasticSearch等工具虽然可以解决部分问题,但可能导致数据一致性降低和系统复杂性增加。
全局主键和唯一约束问题
传统的MySQL自增ID在分库分表后难以满足应用需求。因为自增ID只能保证在单个数据库实例内的唯一性,而无法保证在多个数据库实例间的全局唯一性。因此,必须借助分布式ID生成器,如UUID或雪花算法来生成全局唯一ID。这不仅增加了维护工作,还进一步提升了架构复杂性。
扩容问题
随着业务的发展,系统需要不断扩容。然而,一旦决定实施分库分表,扩容将面临重大挑战。扩容过程往往伴随着系统停机和数据迁移,给业务带来不小的影响。此外,扩容还需要考虑数据的重新分布和分片规则的调整等问题,进一步增加了扩容的复杂性和风险。
运维难度增加
分库分表后,系统的数据库实例数量将大幅增加。这导致企业的运维成本上升,DBA团队面临巨大的压力。他们需要管理数十个甚至上百个数据库实例,并确保这些实例的稳定性和性能。此外,复杂的架构决策也增加了系统维护和故障排查的难度。
业务变更难度大
由于分库分表增加了系统的复杂度,当表结构变更时,需要对所有分片进行修改和调整。这增加了业务变更的难度和风险,可能导致系统不稳定或数据不一致等问题。
数据迁移成本高
在分库分表的场景下,数据的迁移成本很高。迁移过程中需要涉及数据的拆分、合并和迁移等环节,增加了数据迁移的难度和成本。此外,迁移过程中还需要确保数据的一致性和完整性,避免数据丢失或损坏。
分库分表后数据路由定位方案:
分库分表后数据库基本上会丧失了复杂的聚合(联机分析OLAP)查询能力,这个需要用ES 、hadoop等大数据相关技术来解决。
分库分表后基本上数据库就只保留了对单条数据的增删查改能力(联机事务OLTP),单条数据的增删查改就需要对数据的路由定位,技术上有两种方案:
a. 客户端代码里直接路由
b. 增加代理server ,由代理server来完成下游数据库的路由转发,客户端都连代理server.
客户端路由 | proxy server | |
实现复杂性 | 高,需要在客户端实现和维护路由逻辑 | 低,路由逻辑集中在代理层 |
灵活性 | 高,可以根据业务需求灵活调整 | 中等,由代理层决定,灵活性有限 |
性能 | 高,没有额外的代理开销 | 中等,存在代理层的网络和处理开销 |
一致性管理 | 较难,需要同步更新所有客户端 | 容易,由代理层集中管理 |
连接管理 | 复杂,客户端需管理多个数据库连接 | 简单,代理层统一管理数据库连接 |
单点故障 | 无单点故障 | 代理层可能成为单点故障 |
扩展性 | 高,客户端独立扩展 | 高,代理层可水平扩展 |
开发维护成本 | 实现client 路由逻辑相对简单 | 实现一个proxy server 非常复杂的,需要sql解析,上下游数据转发;尤其性能和稳定性挑战非常大 |
分库分表开源方案:
方案有很多种,这里先列举2个:
1. Apache ShardingSphere
简介:Apache ShardingSphere 是一个开源的分布式数据库中间件,支持分库分表、读写分离和数据加密等功能。
特点:
- 支持多种分片策略(范围分片、哈希分片、复合分片等)。
- 支持分布式事务。
- 支持弹性扩展和数据治理。
- 提供 JDBC 和代理两种模式。
2. Vitess
简介:Vitess 是一个开源的分布式数据库解决方案,最初由 YouTube 开发,旨在解决大规模 MySQL 集群管理问题 ,代理模式。
特点:
- 支持分库分表和读写分离。
- 支持自动分片和分片重平衡。
- 提供强大的监控和管理工具。