原作者:Sharding-Sphere 转载来源:http://shardingsphere.io/index.html , https://github.com/sharding-sphere/sharding-sphere , https://gitee.com/sharding-sphere/sharding-sphere
Sharding-Sphere是一个开源生态系统,由一组分布式数据库中间件解决方案组成,包括3个独立产品,Sharding-JDBC,Sharding-Proxy和Sharding-Sidecar(todo)。它们都提供数据分片,分布式事务和数据库编排等功能,适用于Java同构,异构语言和云原生等各种情况。
为了合理地充分利用分布式系统中数据库的计算和存储容量,Sharding-Sphere将自己定义为中间件,而不是一种全新的数据库类型。作为众多企业的基石,关系数据库仍占据着巨大的市场份额。因此,在目前阶段,我们更倾向于关注其增量而不是完全推翻。
它们都提供数据分片,分布式事务和数据库编排等功能,适用于Java同构,异构语言和云原生等各种情况。为了合理地充分利用分布式系统中数据库的计算和存储容量,Sharding-Sphere将自己定义为中间件,而不是一种全新的数据库类型。作为众多企业的基石,关系数据库仍占据着巨大的市场份额。因此,在目前阶段,我们更倾向于关注其增量而不是完全推翻。
ShardingSphere是一个开源生态圈,由一组分布式数据库中间件解决方案组成,包括3个独立产品,Sharding-JDBC,Sharding-Proxy和Sharding-Sidecar(todo)。它们都提供数据分片,分布式事务和数据库编排等功能,适用于Java同构,异构语言和云原生等各种情况。为了合理地充分利用分布式系统中数据库的计算和存储容量,ShardingSphere将自己定义为中间件,而不是一种全新的数据库类型。作为众多企业的基石,关系数据库仍占据着巨大的市场份额。因此,在目前阶段,我们更倾向于关注其增量而不是完全推翻。
Sharding-JDBC将自身定义为轻量级Java框架,在Java JDBC层提供额外服务。客户端直接连接到数据库,它以jar的形式提供服务,不需要额外的部署和依赖。它可以被视为增强的JDBC驱动程序,它与JDBC和各种ORM框架完全兼容。
Sharding-Proxy将自身定义为透明数据库代理,提供封装数据库二进制协议的数据库服务器以支持异构语言。DBA的朋友,现在提供的MySQL版本可以使用与MySQL协议兼容的任何类型的客户端访问(例如MySQL Command Client,MySQL Workbench等)来操作数据。
Sharding-Sidecar(TBD)将自己定义为Kubernetes或Mesos环境的云本机数据库代理,负责以DaemonSet形式对数据库的所有访问。通过分散和零成本的解决方案,它提供了与数据库交互的网格层,即Database Mesh,也称为数据库网格。
Database Mesh强调如何将分布式数据库访问应用程序与数据库连接。专注于交互,它有效地组织凌乱的应用程序和数据库之间的交互。使用Database Mesh访问数据库的应用程序和数据库将形成一个大型网格系统,它们只需要相应地放在正确的位置。它们都由网格层控制。
Sharding-JDBC | Sharding-Proxy | Sharding-Sidecar | |
---|---|---|---|
数据库 | 任何 | MySQL | MySQL |
连接成本编号 | 高 | 低 | 高 |
异构语言 | 仅限Java | 任何 | 任何 |
性能 | 低损失 | 损失相对较高 | 低损失 |
分权 | 是 | 没有 | 没有 |
静态录入 | 没有 | 是 | 没有 |
Sharding-JDBC采用分散式架构,适用于Java开发的高性能轻量级OLTP应用; Sharding-Proxy提供静态条目和异构语言支持,适用于OLAP应用程序和分片数据库管理和操作情况。
ShardingSphere是一个由多个端点组成的生态圈。通过一个注册中心混合使用Sharding-JDBC和Sharding-Proxy以及统一的分片策略,ShardingSphere可以构建适用于各种情况的应用系统。架构师可以更自由地将系统架构调整为最适用于当前业务的架构。
为解决关系型数据库面对海量数据由于数据量过大而导致的性能问题,将数据进行分片是行之有效的解决方案,而将集中于单一节点的数据拆分并分别存储到多个数据库或表,称为分库分表。作为分布式数据库中间件,我们的目标是透明化分库分表所带来的影响,让使用方尽量像使用一个数据库一样使用水平拆分之后的数据库。
面对日益增加的系统访问量,数据库的吞吐量面临着巨大瓶颈。 对于同一时间有大量并发读操作和较少写操作类型的应用系统来说,将单一的数据库拆分为主库和从库,主库负责处理事务性的增删改操作,从库负责处理查询操作,能够有效的避免由数据更新导致的行锁,使得整个系统的查询性能得到极大的改善。透明化读写分离所带来的影响,让使用方尽量像使用一个数据库一样使用主从数据库,是读写分离中间件的主要功能。
对于分布式的数据库来说,强一致性分布式事务在性能方面存在明显不足。追求最终一致性的柔性事务,在性能和一致性上则显得更加平衡。 Sharding-Sphere目前支持最大努力送达型柔性事务,未来也将支持TCC柔性事务。若不使用柔性事务,Sharding-Sphere也会自动包含弱XA事务支持。
Sharding-Sphere提供注册中心、配置动态化、数据库熔断禁用、调用链路等治理能力。
Sharding-Proxy MySQL版本上线,支持DML/DDL/DAL/DQL等基本 SQL。屏蔽底层所有分库分表,可像使用单一MySQL数据库一样处理分库分表数据。
新增对OR SQL语句的支持,例如:select * from t_order where (id>10 and id<20) or status=‘init’;
新增对INSERT批量插入的支持,例如 insert into t_order(order_id, user_id, status) values (1, 2, ‘init’), (2, 3, ‘init’), (3, 4, ‘init’);
优化对INSERT SQL语句的支持,主要包括不指定具体列进行INSERT操作,例如:insert into t_order values(1, 2,‘init’);
增加解析引擎对SQL的缓存,进一步提升解析性能。
Sharding-JDBC新增对InlineExpression占位符$->{}的支持。
1.导入maven依赖
io.shardingsphere
sharding-jdbc-core
${latest.release.version}
注意:请将$ {latest.release.version}更改为实际版本。
2.配置分片规则配置
拆分-JDBC支持4种类型的分片规则配置,它们是Java
,YAML
,Spring namespace
和Spring boot starter
。开发人员可以选择任何一种最适合的情况。更多细节请参考配置手册。
3.创建DataSource
使用ShardingDataSourceFactory创建ShardingDataSource,这是一个标准的JDBC DataSource。然后,开发人员可以将其用于原始JDBC,JPA,MyBatis或其他基于JDBC的ORM框架。
1.配置分片规则
编辑%SHARDING_PROXY_HOME%\conf\config-xxx.yaml
。更多细节请参考配置手册。
编辑%SHARDING_PROXY_HOME%\conf\server.yaml
。更多细节请参考配置手册。
2.启动服务器
${sharding-proxy}\bin\start.sh ${port}
${sharding-proxy}\bin\start.sh ${port}
无论在性能,高可用性还是运营成本方面,将所有数据存储在一个集中节点中的传统解决方案很难满足互联网海量数据场景的要求。
从性能方面来看,由于关系数据库使用B +树的索引,当数据量超过阈值时,更深的索引会增加磁盘访问的IO数,从而削弱查询的性能。同时,高并发请求也使集中式数据库成为系统的最大缺陷。
从高可用性的角度来看,无状态服务使得扩展成本相对较低,这可以使所有压力最终落在数据库上。但单一数据节点或简单的主从结构越来越难以承受这些压力。因此,数据库的高可用性已成为整个系统的关键。
从运营成本方面来看,当数据库实例中的数据达到阈值以上时,DBA的压力也会增加。使用不同数据量时,数据备份和恢复的时间成本将更加无法控制。通常,单个数据库情况下的数据在1TB以内是一个相对合理的范围。
在传统关系数据库不能满足Internet要求的情况下,越来越多的尝试将数据存储在本地分布式NoSQL中。但是它与SQL的不兼容性和生态系统中的不完善阻碍了它在竞争中击败关系数据库,因为关系数据库仍然处于不可动摇的地位。
数据分片是指将数据拆分到一个数据库中,并根据某种特定标准将数据存储在多个表和数据库中,从而提高性能和可用性。一种有效的数据分片方法是将关系数据库分成多个表和数据库,这两个表和数据库都可以有效地避免数据超出负担得起的阈值所导致的查询限制。更重要的是,数据库分片还可以有效地分散TPS。表分片虽然无法缓解数据库压力,但可以提供将分布式事务传输到本地事务的可能性,因为一旦涉及跨数据库升级,分布式事务有时会变得相当棘手。
通过数据库分片和表格分割来分割数据是处理高TPS和大量数据系统的有效方法,因为它可以保持数据量低于阈值并分离流量数据。数据分片方法可分为垂直分片和水平分片。
根据业务分片方法,它被称为垂直分片或纵向分片,其核心概念是专门用于不同用途的数据库。在分片之前,数据库由对应于不同业务的许多数据表组成。但是在分片之后,表格根据业务分类到不同的数据库中,并且压力也被分成不同的数据库。下图显示了根据业务需要通过垂直分片将用户表和订单表分配给不同数据库的情况。
垂直分片需要不时地调整体系结构和设计,但通常,处理快速变化的Internet业务需求并且不能真正解决单节点问题是不够的。这种分片可以缓解但不能完全解决高数据量和并发量带来的问题。分片后,如果表中的数据量仍超过单个节点阈值,则应通过水平分片处理。
水平分片也称为横向分片。与根据垂直分片的业务逻辑的分类方法相比,水平分片通过某些字段根据某些特定规则将数据分类到多个数据库或表,每个分片仅包含部分数据。
例如,根据主键分片,甚至将主键放入0数据库(或表)中,并将奇数主键放入1数据库(或表)中,如下图所示。
从理论上讲,水平分片在一台机器上克服了数据处理量的限制,可以相对自由地扩展,因此可以作为数据库分片和表格分片的标准解决方案。
虽然数据分片已经解决了性能,高可用性和单节点备份和恢复等问题,但其分布式架构也带来了一些新的问题,如获取利润。
一个是应用程序开发工程师和数据库管理员的操作在面对这样分散的数据库和表时变得非常费力。他们应该知道哪个精确的数据库表是从中获取数据的表。
另一个挑战是,在单节点数据库中正确运行的SQL可能在分片数据库中不正确。分片后表名的更改,或者由分页,排序或聚合组等操作引起的不当行为就是恰当的例子。
跨数据库事务也是分布式数据库需要处理的棘手问题。当单表数据量减少时,合理使用分片表还可以充分利用本地事务。通过在同一数据库中明智地使用不同的表,可以避免分布式事务带来的麻烦。在无法避免跨数据库事务的情况下,某些企业仍需要事务保持一致。互联网巨头尚未大规模采用基于XA的分布式事务,因为它们无法确保其在高并发情况下的性能。它们通常用最终一致的软状态替换强一致的事务。
ShardingSphere的数据分片模块的主要设计目标是尝试减少数据库分片和表分片的影响,以便让用户像一个数据库一样使用水平分片数据库组。
本章将介绍数据分片的核心概念,包括:
逻辑表
它统称为水平分片的相同类型的数据库(表)。例如,订单数据根据主键的最后一个数字分为10个表,它们来自t_order_0
to t_order_9
,其逻辑名称为t_order
。
实际表
真正存在于分片数据库中的物理表,例如t_order_0
,以t_order_9
上面的实例。
数据节点
数据分片的最小单位,包括源数据名称和表名,例如ds_0.t_order_0
。
绑定表
它指的是具有相同分片规则的主表和joiner表,例如,t_order
表和t_order_item
表都是订单ID分片,因此它们是彼此的绑定表。笛卡尔乘积相关性不会出现在多表关联查询中,因此查询效率会大幅提升。以此为例,如果SQL是:
SELECT i.* FROM t_order o JOIN t_order_item i ON o.order_id=i.order_id WHERE o.order_id in (10, 11);
如果没有绑定表配置,假设分片键将order_id
值10路由到分片0,将值11路由到分片1,在笛卡尔积中路由后将有4个SQL:
SELECT i.* FROM t_order_0 o JOIN t_order_item_0 i ON o.order_id=i.order_id WHERE o.order_id in (10, 11);
SELECT i.* FROM t_order_0 o JOIN t_order_item_1 i ON o.order_id=i.order_id WHERE o.order_id in (10, 11);
SELECT i.* FROM t_order_1 o JOIN t_order_item_0 i ON o.order_id=i.order_id WHERE o.order_id in (10, 11);
SELECT i.* FROM t_order_1 o JOIN t_order_item_1 i ON o.order_id=i.order_id WHERE o.order_id in (10, 11);
使用绑定表配置,路由后应该有2个SQL:
SELECT i.* FROM t_order_0 o JOIN t_order_item_0 i ON o.order_id=i.order_id WHERE o.order_id in (10, 11);
SELECT i.* FROM t_order_1 o JOIN t_order_item_1 i ON o.order_id=i.order_id WHERE o.order_id in (10, 11);
在它们中,
t_order
FROM左端的表将由ShardingSphere作为查询的主表。以类似的方式,ShardingSphere还将
t_order
FROM的左端的表作为整个绑定表的主表。所有路由计算将仅使用主表的分片策略,因此分片计算
t_order_item
表将使用条件
t_order
。因此,绑定表之间的分片键应完全相同。
广播表
它指的是所有数据库实例都具有包含表结构和数据的相同表。广播表的最佳实践是针对小数据量但需要具有大数据量场景的连接器查询,例如:字典表。
逻辑指数
某些数据库(例如PostgreSQL)不允许在同一数据库中存在具有相同名称的索引; 但是,其他数据库(例如MySQL)仅禁止在同一个表中存在具有相同名称的索引。逻辑索引用于前一种情况,它需要在同一数据库中重写索引名称,但不能与索引名称+表名称在同一个表中,并且先前的索引名称变为逻辑索引。
分片中使用的数据库字段是指数据库(表)的水平分片中的关键字段。例如,在订单ID分片的最后一个数量模数中,订单ID被视为分片密钥。在SQL中没有分片字段时执行的完整路由性能较差但支持多个分片字段。
数据的分片可以通过分析算法来实现=
,BETWEEN
和IN
。高度灵活,分片算法需要由开发人员自己实现。
目前,有4种分片算法可供使用。由于分片算法和业务的实现是高度相关的,它不是提供内置的分片算法,而是通过分片策略来提取各种情况,以提供更高的抽象和开发人员自己实现分片算法的接口。
PreciseShardingAlgorithm
要处理,其中单个分片密钥分片的情况下=
和IN
使用时,连同StandardShardingStrategy
。
RangeShardingAlgorithm
是处理BETWEEN AND
使用单个分片键的分片情况,以及StandardShardingStrategy
。
ComplexKeysShardingAlgorithm
是处理使用多个分片键的分片情况,以及ComplexShardingStrategy
。它有一个相对复杂的逻辑,需要开发人员自己处理。
HintShardingAlgorithm
是处理使用提示的分片情况,以及HintShardingStrategy
。
它包括分片键和分片算法,后者因其独立性而被提取出来。只有分片键+分片算法,即分片策略,才能用于分片操作。目前,有5种分片策略可供选择。
StandardShardingStrategy
提供支持的分片运行=
,IN
并BETWEEN AND
在SQL。StandardShardingStrategy
仅支持单个分片键,并提供两个分片算法PreciseShardingAlgorithm
和RangeShardingAlgorithm
。PreciseShardingAlgorithm
是强制性的,并用于操作的分片=
和IN
。RangeShardingAlgorithm
是可选的,用于操作分片BETWEEN AND
。 BETWEEN AND
在SQL中将通过所有数据节点路由操作而无需配置RangeShardingAlgorithm
。
ComplexShardingStrategy
提供支持的分片运行=
,IN
并BETWEEN AND
在SQL。ComplexShardingStrategy
支持多个分片键,但由于它们的关系非常复杂,没有太多的封装,分片键和分片运算符的组合在算法界面中,并由开发人员以最大的灵活性实现。
使用Groovy表达式,InlineShardingStrategy
为SQL 的分片操作=
和IN
SQL 提供单键支持。可以通过简单的配置使用简单的分片算法,以避免费力的Java代码开发。例如,t_user${u_id % 8}
表t_user根据u_id分为8个表,表名从t_user0到t_user7。
HintShardingStrategy
是指Hint而不是SQL解析的分片策略。
NoneShardingStrategy
是指没有分片的策略。
SQL提示
如果ShardingColumn
不是由SQL决定但是其他外部条件,则可以灵活地使用SQL Hint进行注入ShardingColumn
。例如,在内部系统中,数据库根据员工的ID进行划分,但数据库中不存在此列。SQL Hint可以通过两种方式使用,Java API和SQL注释(待完成)。
Sharding规则的主要入口包括数据源,表,绑定表和读写分割的配置。
数据源配置
真实数据源列表。
表配置
逻辑表名称,数据节点和表分片规则的配置。
数据节点配置
它用于逻辑表和实际表之间的映射关系的配置,可以分为两种:统一分布和用户定义分布。
这意味着数据表均匀分布在每个数据源中,例如:
db0
├── t_order0
└── t_order1
db1
├── t_order0
└── t_order1
所以数据节点配置如下:
db0.t_order0, db0.t_order1, db1.t_order0, db1.t_order1
这意味着数据表是按照某些规则分发的,例如:
db0
├── t_order0
└── t_order1
db1
├── t_order2
├── t_order3
└── t_order4
所以数据节点配置如下:
db0.t_order0, db0.t_order1, db1.t_order2, db1.t_order3, db1.t_order4
分片策略配置
分片策略有两个维度,即数据库分片和表格分片。
DatabaseShardingStrategy
用于配置目标数据库中的数据。
TableShardingStrategy
用于配置数据库中存在的目标表中的数据。因此,表分片策略依赖于数据库分片策略的结果。
这两种策略的API完全相同。
自动增量密钥的生成策略
用服务器中生成的密钥替换原始数据库自动增量密钥可以使分布式密钥不重复。
配置地图
从分片数据库和表源配置元数据时,ConfigMapContext.getInstance()
可用于在ConfigMap中获取shardingConfig数据。例如,不同权重的机器可能具有不同的数据流量,并且ConfigMap
可用于设置元数据。
DataSource dataSource = ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfig);
Tips:
io.shardingsphere
sharding-sphere
3.*.*.M*
https://github.com/sharding-sphere/sharding-sphere-doc/raw/master/dist/sharding-proxy-3.0.0.M1.tar.gz
docker pull shardingsphere/sharding-proxy
参考来源:https://blog.csdn.net/qq_35666577/article/details/80431439
社区地址:http://shardingsphere.io/community/
官网文档:http://shardingsphere.io/document/current/en/overview/