从零到一学习中间件之Sharding-JDBC
Apache ShardingSphere 是一款分布式的数据库生态系统, 可以将任意数据库转换为分布式数据库,并通过数据分片、弹性伸缩、加密等能力对原有数据库进行增强。
ShardingSphere 源码地址:https://github.com/apache/shardingsphere
ShardingSphere 官方网站:https://shardingsphere.apache.org
文章描述 ShardingSphere 相关概念和知识,如无特别声明,均是 Apache ShardingSphere 5.3.2 版本。
🔥 SpringBoot Ladder:从零到一学习 SpringBoot 各种组件框架实战的项目,让 Demo 变得简单。咱们文章中的 ShardingSphere 示例也在这个项目。
分库分表背景
传统的将数据集中存储至单一节点的解决方案,在性能、可用性和运维成本这三方面已经难于满足海量数据的场景。
从性能方面来说,由于关系型数据库大多采用 B+ 树类型的索引,在数据量超过阈值的情况下,索引深度的增加也将使得磁盘访问的 IO 次数增加,进而导致查询性能的下降; 同时,高并发访问请求也使得集中式数据库成为系统的最大瓶颈。
从可用性的方面来讲,服务化的无状态性,能够达到较小成本的随意扩容,这必然导致系统的最终压力都落在数据库之上。 而单一的数据节点,或者简单的主从架构,已经越来越难以承担。数据库的可用性,已成为整个系统的关键。
从运维成本方面考虑,当一个数据库实例中的数据达到阈值以上,对于 DBA 的运维压力就会增大。 数据备份和恢复的时间成本都将随着数据量的大小而愈发不可控。一般来讲,单一数据库实例的数据的阈值在 1TB 之内,是比较合理的范围。
在传统的关系型数据库无法满足互联网场景需要的情况下,将数据存储至原生支持分布式的 NoSQL 的尝试越来越多。 但 NoSQL 对 SQL 的不兼容性以及生态圈的不完善,使得它们在与关系型数据库的博弈中始终无法完成致命一击,而关系型数据库的地位却依然不可撼动。
数据分片指按照某个维度将存放在单一数据库中的数据分散地存放至多个数据库或表中以达到提升性能瓶颈以及可用性的效果。 数据分片的有效手段是对关系型数据库进行分库和分表。分库和分表均可以有效的避免由数据量超过可承受阈值而产生的查询瓶颈。 除此之外,分库还能够用于有效的分散对数据库单点的访问量;分表虽然无法缓解数据库压力,但却能够提供尽量将分布式事务转化为本地事务的可能,一旦涉及到跨库的更新操作,分布式事务往往会使问题变得复杂。 使用多主多从的分片方式,可以有效的避免数据单点,从而提升数据架构的可用性。
通过分库和分表进行数据的拆分来使得各个表的数据量保持在阈值以下,以及对流量进行疏导应对高访问量,是应对高并发和海量数据系统的有效手段。 数据分片的拆分方式又分为垂直分片和水平分片。
分库分表介绍
1. 什么是分库分表?
分库分表是一种数据库分片技术,用于解决大规模应用中单一数据库容量不足以支持高并发和大数据量的问题。它将一个大型的数据库拆分成多个小型数据库,每个小型数据库称为一个分片。每个分片存储部分数据,从而降低了单个数据库的负担。
简单来说,分库是将原本的单库拆分为多个库,分表是将原来的单表拆分为多个表。
很多情况下,分库分表并不是从系统设计开始就存在的,而是系统运行过程中,出现数据量庞大或者查询性能慢等问题延伸而来。
如果你在业务功能开发时,已经预知业务数据库量,应提前进行分库或者分表,做好分片规范,避免系统运行时拆分。
1.1 什么是分库?
1)垂直分片
比如:电商库 mall_db,业务拆分后就是 user_db、order_db、pay_db...
按照业务拆分的方式称为垂直分片,又称为纵向拆分,它的核心理念是专库专用。在拆分之前,一个数据库由多个数据表构成,每个表对应着不同的业务。而拆分之后,则是按照业务将表进行归类,分布到不同的数据库中,从而将压力分散至不同的数据库。
优点:
- 可以针对不同业务场景优化数据库,提高性能。
- 提高了数据库的并发能力。
缺点:
- 需要处理分布式事务的问题。
- 增加了系统的复杂度。
2)水平分片
比如:用户库 user_db,分片库后就是 user_db_0、user_db_1、user_db_xx。
水平分片又称为横向拆分。 相对于垂直分片,它不再将数据根据业务逻辑分类,而是通过某个字段(或某几个字段),根据某种规则将数据分散至多个库或表中,每个分片仅包含数据的一部分。 例如:根据主键分片,偶数主键的记录放入 0 库(或表),奇数主键的记录放入 1 库(或表),如下图所示。
优点:
- 提高了单库的读写性能,降低了单库数据量。
- 可以将库存储在不同的物理服务器上,提高了查询效率。
缺点:
- 需要处理跨库查询的问题。
- 对分库规则的设计需要谨慎,避免热点数据集中在某个库中。
1.2 什么是分表?
1)垂直分片
比如:订单表 order_table,拆分后就是 order_table 以及 order_ext_table。
同分库的概念,只不过将数据库维度降低为数据库表维度。
优点:
- 拆分后每个表的数据量变小,查询时涉及的磁盘 I/O 次数相对减少,提高了查询效率。
- 每个小表的并发写入操作相对较少,减少了数据库锁的竞争,提高了并发能力。
缺点:
- 需要在应用层面处理跨表查询的逻辑,增加了开发的复杂性。
- 如果一个事务涉及多个小表,可能需要在应用层面进行事务管理,增加了代码的复杂性。
- 需要额外的措施来保证拆分后的小表之间的数据一致性。
2)水平分片
比如:订单表 order_table,拆分后就是 order_table_0、 order_table_1、order_table_xxx。
同分库的概念,只不过将数据库维度降低为数据库表维度。
优点:
-
可以根据数据量的增长动态地增加分表,从而扩展数据库的存储能力。
-
每个小表的数据量减少,可以提高查询速度,尤其是在频繁查询的场景下。
-
拆分后,每个小表的并发写入操作相对减少,降低了数据库锁的竞争,提高了并发性能。
缺点:
- 对业务存在一定限制,如果没有按照分片键查询,会造成读扩散问题。
- 对分表规则的设计需要谨慎,避免热点数据集中在某个表中。