您好!
欢迎来到京东云开发者社区
登录
首页
博文
课程
大赛
工具
用户中心
开源
首页
博文
课程
大赛
工具
开源
更多
用户中心
开发者社区
>
博文
>
数据分片内核剖析——路由引擎
分享
打开微信扫码分享
点击前往QQ分享
点击前往微博分享
点击复制链接
数据分片内核剖析——路由引擎
Apache ShardingSphere
2021-01-15
IP归属:未知
26320浏览
根据解析上下文匹配数据库和表的分片策略,并生成路由路径。 对于携带分片键的 SQL,根据分片键的不同可以划分为单片路由(分片键的操作符是等号)、多片路由(分片键的操作符是 IN)和范围路由(分片键的操作符是 BETWEEN)。 不携带分片键的 SQL 则采用广播路由。 分片策略通常可以采用由数据库内置或由用户方配置。 数据库内置的方案较为简单,内置的分片策略大致可分为尾数取模、哈希、范围、标签、时间等。 由用户方配置的分片策略则更加灵活,可以根据使用方需求定制复合分片策略。 如果配合数据自动迁移来使用,可以做到无需用户关注分片策略,自动由数据库中间层分片和平衡数据即可,进而做到使分布式数据库具有的弹性伸缩的能力。 在 ShardingSphere 的线路规划中,弹性伸缩将于 4.x 开启。 # 分片路由 用于根据分片键进行路由的场景,又细分为直接路由、标准路由和笛卡尔积路由这 3 种类型。 ## 直接路由 满足直接路由的条件相对苛刻,它需要通过 Hint(使用 HintAPI 直接指定路由至库表)方式分片,并且是只分库不分表的前提下,则可以避免 SQL 解析和之后的结果归并。 因此它的兼容性最好,可以执行包括子查询、自定义函数等复杂情况的任意 SQL。直接路由还可以用于分片键不在 SQL 中的场景。例如,设置用于数据库分片的键为 `3`, ```java hintManager.setDatabaseShardingValue(3); ``` 假如路由算法为 `value % 2`,当一个逻辑库 `t_order` 对应 2 个真实库 `t_order_0` 和 `t_order_1` 时,路由后 SQL 将在 `t_order_1` 上执行。下方是使用 API 的代码样例: ```java String sql = "SELECT * FROM t_order"; try ( HintManager hintManager = HintManager.getInstance(); Connection conn = dataSource.getConnection(); PreparedStatement pstmt = conn.prepareStatement(sql)) { hintManager.setDatabaseShardingValue(3); try (ResultSet rs = pstmt.executeQuery()) { while (rs.next()) { //... } } } ``` ## 标准路由 标准路由是 ShardingSphere 最为推荐使用的分片方式,它的适用范围是不包含关联查询或仅包含绑定表之间关联查询的 SQL。 当分片运算符是等于号时,路由结果将落入单库(表),当分片运算符是 BETWEEN 或 IN 时,则路由结果不一定落入唯一的库(表),因此一条逻辑 SQL 最终可能被拆分为多条用于执行的真实 SQL。 举例说明,如果按照 `order_id` 的奇数和偶数进行数据分片,一个单表查询的 SQL 如下: ```sql SELECT * FROM t_order WHERE order_id IN (1, 2); ``` 那么路由的结果应为: ```sql SELECT * FROM t_order_0 WHERE order_id IN (1, 2); SELECT * FROM t_order_1 WHERE order_id IN (1, 2); ``` 绑定表的关联查询与单表查询复杂度和性能相当。举例说明,如果一个包含绑定表的关联查询的 SQL 如下: ```sql SELECT * FROM t_order o JOIN t_order_item i ON o.order_id=i.order_id WHERE order_id IN (1, 2); ``` 那么路由的结果应为: ```sql SELECT * FROM t_order_0 o JOIN t_order_item_0 i ON o.order_id=i.order_id WHERE order_id IN (1, 2); SELECT * FROM t_order_1 o JOIN t_order_item_1 i ON o.order_id=i.order_id WHERE order_id IN (1, 2); ``` 可以看到,SQL 拆分的数目与单表是一致的。 ## 笛卡尔路由 笛卡尔路由是最复杂的情况,它无法根据绑定表的关系定位分片规则,因此非绑定表之间的关联查询需要拆解为笛卡尔积组合执行。 如果上个示例中的 SQL 并未配置绑定表关系,那么路由的结果应为: ```sql SELECT * FROM t_order_0 o JOIN t_order_item_0 i ON o.order_id=i.order_id WHERE order_id IN (1, 2); SELECT * FROM t_order_0 o JOIN t_order_item_1 i ON o.order_id=i.order_id WHERE order_id IN (1, 2); SELECT * FROM t_order_1 o JOIN t_order_item_0 i ON o.order_id=i.order_id WHERE order_id IN (1, 2); SELECT * FROM t_order_1 o JOIN t_order_item_1 i ON o.order_id=i.order_id WHERE order_id IN (1, 2); ``` 笛卡尔路由查询性能较低,需谨慎使用。 # 广播路由 对于不携带分片键的 SQL,则采取广播路由的方式。根据 SQL 类型又可以划分为全库表路由、全库路由、全实例路由、单播路由和阻断路由这 5 种类型。 ## 全库表路由 全库表路由用于处理对数据库中与其逻辑表相关的所有真实表的操作,主要包括不带分片键的 DQL 和 DML,以及 DDL 等。例如: ```sql SELECT * FROM t_order WHERE good_prority IN (1, 10); ``` 则会遍历所有数据库中的所有表,逐一匹配逻辑表和真实表名,能够匹配得上则执行。路由后成为 ```sql SELECT * FROM t_order_0 WHERE good_prority IN (1, 10); SELECT * FROM t_order_1 WHERE good_prority IN (1, 10); SELECT * FROM t_order_2 WHERE good_prority IN (1, 10); SELECT * FROM t_order_3 WHERE good_prority IN (1, 10); ``` ## 全库路由 全库路由用于处理对数据库的操作,包括用于库设置的 SET 类型的数据库管理命令,以及 TCL 这样的事务控制语句。 在这种情况下,会根据逻辑库的名字遍历所有符合名字匹配的真实库,并在真实库中执行该命令,例如: ```sql SET autocommit=0; ``` 在 `t_order` 中执行,`t_order` 有 2 个真实库。则实际会在 `t_order_0` 和 `t_order_1` 上都执行这个命令。 # 全实例路由 全实例路由用于 DCL 操作,授权语句针对的是数据库的实例。无论一个实例中包含多少个 Schema,每个数据库的实例只执行一次。例如: ```sql CREATE USER customer@127.0.0.1 identified BY '123'; ``` 这个命令将在所有的真实数据库实例中执行,以确保 customer 用户可以访问每一个实例。 ## 单播路由 单播路由用于获取某一真实表信息的场景,它仅需要从任意库中的任意真实表中获取数据即可。例如: ```sql DESCRIBE t_order; ``` t_order 的两个真实表 t_order_0,t_order_1 的描述结构相同,所以这个命令在任意真实表上选择执行一次。 ## 阻断路由 阻断路由用于屏蔽 SQL 对数据库的操作,例如: ```sql USE order_db; ``` 这个命令不会在真实数据库中执行,因为 ShardingSphere 采用的是逻辑 Schema 的方式,无需将切换数据库 Schema 的命令发送至数据库中。 路由引擎的整体结构划分如下图。 ![](//img1.jcloudcs.com/developer.jdcloud.com/0a77c065-ec4c-4152-a529-54d93df2c26420210115110534.jpg)
原创文章,需联系作者,授权转载
上一篇:运维大规模ES集群的思考和实践
下一篇:OpenJDK8编译调试
Apache ShardingSphere
文章数
96
阅读量
231327
作者其他文章
01
突破关系型数据库桎梏:云原生数据库中间件核心剖析
数据库技术的发展与变革方兴未艾,NewSQL的出现,只是将各种所需技术组合在一起,而这些技术组合在一起所实现的核心功能,推动着云原生数据库的发展。 NewSQL的三种分类中,新架构和云数据库涉及了太多与数据库相关的底层实现,为了保证本文的范围不至太过发散,我们重点介绍透明化分片数据库中间件的核心功能与实现原理,另外两种类型的NewSQL在核心功能上类似,但实现原理会有所差别。
01
Apache ShardingSphere数据脱敏全解决方案详解(上)
Apache ShardingSphere针对新业务上线、旧业务改造分别提供了相应的全套脱敏解决方案。
01
Shardingsphere整合Narayana对XA分布式事务的支持(4)
ShardingSphere对于XA方案,提供了一套SPI解决方案,对Narayana进行了整合,Narayana初始化流程,开始事务流程,获取连接流程,提交事务流程,回滚事务流程。
01
从中间件到分布式数据库生态,ShardingSphere 5.x革新变旧
5.x 是 Apache ShardingSphere从分库分表中间件向分布式数据库生态转化的里程碑,从 4.x 版本后期开始打磨的可插拔架构在 5.x 版本已逐渐成型,项目的设计理念和 API 都进行了大幅提升。欢迎大家测试使用!
最新回复
丨
点赞排行
共0条评论
Apache ShardingSphere
文章数
96
阅读量
231327
作者其他文章
01
突破关系型数据库桎梏:云原生数据库中间件核心剖析
01
Apache ShardingSphere数据脱敏全解决方案详解(上)
01
Shardingsphere整合Narayana对XA分布式事务的支持(4)
01
从中间件到分布式数据库生态,ShardingSphere 5.x革新变旧
添加企业微信
获取1V1专业服务
扫码关注
京东云开发者公众号