分库分表

143 阅读6分钟

优点:

将原本的单库单表拆分为多个数据库或表,从而分散数据存储和查询压力,提高系统的性能和可扩展性,避免查询瓶颈。

分库还能够用于有效的分散对数据库单点的访问量;分表虽然无法缓解数据库压力,但却能够提供尽量将分布式事务转化为本地事务的可能,一旦涉及到跨库的更新操作,分布式事务往往会使问题变得复杂

缺点:

对开发人员和DBA来说,需要知道数据从哪个具体的数据库的子表中获取(难度提升)。

能够正确的运行在单节点数据库中的 SQL,在分片之后的数据库中并不一定能够正确运行。 例如,分表导致表名称的修改,或者分页、排序、聚合分组等操作的不正确处理。

跨库事务也是分布式的数据库集群要面对的棘手事情

分库分表的两种模式

垂直拆分

比如将一个系统的用户表和订单表存放到不同的数据库里

水平拆分

将用户表拆分成用户表_01,用户表_02 …… 这些表都在同一个数据库里

什么场景下进行分库分表

什么场景下分表?数据量过大或者数据库表对应的磁盘文件过大。

Q:多少数据量进行分表?

A:单表 1000w 是否要分表?回答不够标准。

假设一个表里 15 个字段,没有特别大的值(不包含 text 或其它超长度的列)数据量超过 5000 万了,依然很丝滑,因为走索引。

真正需要考虑的是:业务的增长量以及历史数量。

Q:物理文件过大,会有什么问题?

A:会影响公司对数据库表的一个备份。数据库表文件过大,也间接证明表数据过大,增加或删除字段导致锁表的时间过长。

2)什么场景下分库?

当数据库的连接不够客户端使用时,可以考虑分库或读写分离。

如果说当数据库的 QPS 越来越高以及数据量越来越大的时候,就需要考虑分库分表。

Q:为什么说连接不够用?

A:假设 MySQL Server 能支持 4000 个数据库连接。我们有 10 个服务,40 个节点,一个节点呢数据库连接池最多 10 个。这样就把一个 MySQL Server 的连接数压榨干净了。

当 MySQL 连接不够用时,可能会报错 "Too many connections" 或者类似的错误。这是因为 MySQL 服务器同时可以处理的连接数量是有限制的,当连接数达到这个限制时,服务器就会拒绝新的连接请求,并返回这个错误消息。

3)什么场景下分库又分表?

  • 高并发写入场景:当应用面临高并发的写入请求时,单一数据库可能无法满足写入压力,此时可以将数据按照一定规则拆分到多个数据库中,每个数据库处理部分数据的写入请求,从而提高写入性能。
  • 数据量巨大场景:随着数据量的不断增加,单一数据库的存储和查询性能可能逐渐下降。此时,可以将数据按照一定的规则拆分到多个表中,每个表存储部分数据,从而分散数据的存储压力,提高查询性能。

分库分表组件

1. ShardingSphere-JDBC

定位为轻量级 Java 框架,在 Java 的 JDBC 层提供的额外服务。 它使用客户端直连数据库,以 jar 包形式提供服务,无需额外部署和依赖,可理解为增强版的 JDBC 驱动,完全兼容 JDBC 和各种 ORM 框架。

  • 适用于任何基于 JDBC 的 ORM 框架,如:JPA, Hibernate, Mybatis, Spring JDBC Template 或直接使用 JDBC;
  • 支持任何第三方的数据库连接池,如:DBCP, C3P0, BoneCP, HikariCP 等;
  • 支持任意实现 JDBC 规范的数据库,目前支持 MySQL,PostgreSQL,Oracle,SQLServer 以及任何可使用 JDBC 访问的数据库。

2. ShardingSphere-Proxy

定位为透明化的数据库代理端,通过实现数据库二进制协议,对异构语言提供支持。 目前提供 MySQL 和 PostgreSQL 协议,透明化数据库操作,对 DBA 更加友好。

  • 向应用程序完全透明,可直接当做 MySQL/PostgreSQL 使用;
  • 兼容 MariaDB 等基于 MySQL 协议的数据库,以及 openGauss 等基于 PostgreSQL 协议的数据库;
  • 适用于任何兼容 MySQL/PostgreSQL 协议的的客户端,如:MySQL Command Client, MySQL Workbench, Navicat 等。

3. JDBC 和 Proxy 优劣势

  • JDBC:
    • 优点:性能较高,通过 JDBC 直接向 MySQL 发起请求调用。
    • 优点:使用较为简单,理论上无需修改代码,仅需使用 ShardingSphere 的配置即可。
    • 缺点:需要修改项目配置以及引入 Jar 包。
    • 缺点:对应用的内存有一定影响。
  • Proxy:
    • 优点:无需对现有项目做任何配置或代码变更,将数据库的地址改为 Proxy 的地址即可。
    • 优点:Proxy 对 Java 应用内存没有任何影响。
    • 优点:分片后无法知道一条数据记录到底在那张表,Proxy 是屏蔽了分片逻辑,可直接操作逻辑表。
    • 缺点:JDBC 操作 MySQL 是点对点的,但是 Proxy 多了一层链路。

分片键的选择原理

选择分库分表中的分片键(Sharding Key)是一个关键决策,它直接影响了分库分表的性能和可扩展性。以下是一些选择分片键的关键因素:

  1. 访问频率:选择分片键应考虑数据的访问频率。将经常访问的数据放在同一个分片上,可以提高查询性能和降低跨分片查询的开销。
  2. 数据均匀性:分片键应该保证数据的均匀分布在各个分片上,避免出现热点数据集中在某个分片上的情况。
  3. 业务关联性:分片键应该与业务关联紧密,这样可以避免跨分片查询和跨库事务的复杂性。
  4. 数据不可变:一旦选择了分片键,它应该是不可变的,不能随着业务的变化而频繁修改。