关系型数据库分库分表、水平分和垂直分、客户端实现路由和proxy实现路由

发布于:2025-02-11 ⋅ 阅读:(80) ⋅ 点赞:(0)

分库分表:

分库 

是将数据拆分到多个数据库实例中的技术。每个数据库实例存储部分数据,以减少单个数据库的负载。分库通常用于大规模分布式系统中,以提高系统的扩展性和性能。

分库后的问题:

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 集群管理问题 ,代理模式。

特点

  • 支持分库分表和读写分离。
  • 支持自动分片和分片重平衡。
  • 提供强大的监控和管理工具。

网站公告

今日签到

点亮在社区的每一天
去签到