《DistSQL:像数据库一样使用 Apache ShardingSphere》《SCTL 涅槃重生:投入 RAL 的怀抱》中,已经为大家介绍了 DistSQL 的设计初衷和语法体系,并通过实战操作展示了 DistSQL 创建分布式数据库表的强大能力,展现了 Apache ShardingSphere 在新形态下的交互体验。
为了让大家对 DistSQL 有更深入的了解,同时能根据需要定制自己的 DistSQL 语法,本篇将为大家解析 DistSQL 的设计开发流程,同时通过实际的场景案例,带领大家实现一个全新的 DistSQL 语法,完成从需求到设计、开发和测试的完整过程。

兰城翔

SphereEx 中间件研发工程师,Apache ShardingSphere contributor,目前专注于 DistSQL 的设计和研发。

何为 DistSQL

DistSQL(Distributed SQL)是 Apache ShardingSphere 特有的操作语言,它与标准 SQL 的使用方式完全一致,用于提供增量功能的 SQL 级别操作能力,以此达到对资源和规则的管理的目的。关于 DistSQL 更多信息参考《DistSQL:像数据库一样使用 Apache ShardingSphere》

DistSQL 的意义

DistSQL 设计的目的是打破中间件和数据库之间的界限,让开发者像使用数据库一样使用 Apache ShardingSphere。因此 DistSQL 的设计会尽可能契合已有的数据库语法,进而降低学习成本;此外 DistSQL 的作用是对资源和规则进行 SQL 级别的管理,完全替代配置文件也是其优点之一。

开发 DistSQL

准备

* 在开发之前需要对以下工具有所了解
 
1. ANTRL4 作为解析工具是开发 DistSQL 的基础,关于 ANTLR 4 的使用可以参考 【ANTRL4简明教程】:https://wizardforcel.gitbooks.io/antlr4-short-course/content/
 
2. 在 IntelliJ IDEA 开发时还需要使用到插件 ANTLR v4, (https://plugins.jetbrains.com/plugin/7358-antlr-v4)作用是对 ANTRL4 定义的语法规则进行测试,使用方式如下:
 
a. 在对应的规则上选择 Test Rule
 
b. 在 ANTLR preview 中输入需要校验的语句
 
在了解语法和插件的基础之上,还需要对 DistSQL 执行流程有一定认识。但 DistSQL 完整的执行流程较为繁琐,而 ShardingSphere 的良好的架构使得开发者不用关注整个流程也能完成 DistSQL 功能的开发。
 
开发 DistSQL 需要关注的核心流程如下,此处以分片功能为例,不同的功能对应的 Visitor 不同:

实战

在了解 DistSQL 执行流程之后,接下来将实战演示如何开发一条自己的 DistSQL。
 
《DistSQL:像数据库一样使用 Apache ShardingSphere》一文中实战演示了使用 DistSQL 创建分片规则,同时使用 show sharding table rules 对分片规则进行了展示。
 
现在,让我们提出一个新的需求:通过 DistSQL 快速查询各个分片表的分片数量。设计语法如下:
show sharding tables count [from schema] ;
  • 环境准备
  • MySQL 服务,包含用于分片的数据库和表
  • Zookeeper 服务,作为注册中心
  • ShardingSphere-Proxy 5.0.0
  • 实战演示
1. 创建语法定义
src/main/antlr4/imports/sharding/RQLStatement.g4 文件中添加如下的语法定义,添加完成后可以使用 ANTLR v4 对语法定义进行测试。
 
在添加语法定义时需要考虑该语法中的关键字是否已经定义,此处的 COUNT 为未定义的关键字,需要在 src/main/antlr4/imports/sharding/Keyword.g4 中定义。 在语法定义之后还需将其添加到 ShardingDistSQLStatement.g4 文件中,该文件可以理解为解析的路由。
 
在完成以上步骤之后,对 shardingsphere-sharding-distsql-parser 进行编译生成语法对应的上下文对象。
 
2. 完成对语法定义的解析
 
在处理语法之前还需要在 shardingsphere-distsql-statement 添加一个与该语法定义对应的 DistSQLStatement 对象用于保存语句中的变量属性,例如当前语法定义中的 schemaName 需要保存至 DistSQLStatement 对象中。
在 ShardingSphere 中使用的是 ANTLR 的 Visitor 模式,因此对语法定义的处理需要在 ShardingDistSQLStatementVisitor 中重写 visitShowShardingTableCount 方法,该方法的目的为创建 ShowShardingTablesCountStatement 对象,并将语法中的变量属性保存到 DistSQLStatement 对象中。
 
shardingsphere-distsql-statement 存在 shardingsphere-sharding-distsql-parser 依赖关系,因此需要对 shardingsphere-distsql-statement 进行编译。
 
3. 数据处理以及结果返回
 
数据的处理主要由 Handler 或者 Executor 中的 execute 方法处理,结果主要由 getRowData 方法返回,但是对应不同类型的语法定义在侧重点上可能有所差异。其中结果返回的语法定义使用 DistSQLResultSet 作为结果存储的对象,会在 execute 方法中对结果数据进行组装。
 
本示例便是这种处理方式,以下为该示例对应的 DistSQLResultSet
 
ShardingTablesCountResultSetinit 方法负责数据的获取与组装,getRowData 方法负责对行数据的返回。此外不难发现该类中还有 getType 方法,该方法属于 TypedSPI 接口,所以 ShardingTablesCountResultSet 还需要在当前模块的 src/main/resources/META-INF/services 目录下增加 org.apache.shardingsphere.infra.distsql.query.DistSQLResultSet 文件来完成 SPI 的注入才能使用,路径与内容如下:
 
至此该语法定义的功能开发已基本完成。
 
4. 单元测试以及解析测试
 
在完成基本的功能开发之后为了保证其持续的可用性需要对新增的类或者方法添加测试用例,对新增的语法添加解析测试,以下为 ShardingTablesCountResultSet 的单元测试。
除了单元测试以外还需要在 shardingsphere-parser-test 中添加对语法定义的解析测试,将输入的 DistSQL 解析成 DistSQLStatement 然后与预期的 TestCase 对象进行比较, 步骤如下。
 
a. 在 src/main/resources/sql/supported/rql/show.xml 中添加测试的 SQL;
 
b. 在 src/main/resources/case/rql/show.xml 添加测试的 case;
 
c. 添加 TestCase 对象用于保存 case 中定义的预期结果;
 
d. 使用 SQLParserTestCases 类将 TestCase 进行加载;
 
e. 添加对应的 Assert 对象 ,并将其加入到 ShowRulesStatementAssert 判断中;
 
f. 执行 DistSQLParserParameterizedTest 中的测试方法,至此测试告一段落。 最后可以在命令行工具中去执行开发完成的 DistSQL 检验功能。

结语

DistSQL 作为 5.0.0 版本发布的新特性之一,将会在此版本基础上持续发力,也希望更多的社区伙伴加入,构造更加完善的语法体系,提供更强大的功能,真正打破中间件与数据库之间的界限。
最后,DistSQL SIG 近日已成立,致力于 DistSQL 特性持续优化,拓展新的使用场景以及宣传答疑,欢迎大家点击这里链接关注,了解 DistSQL 以及 ShardingSphere 项目最新进展。
欢迎添加社区经理微信(ss_assistant_1)进入交流群,与众多 ShardingSphere 爱好者一同交流进步

如何在 ShardingSphere 中开发自己的 DistSQL的更多相关文章

  1. 如何在Eclipse中开发并调试自己的插件(或者说如何将自己的代码插件化)

    Setting up Eclipse to create and debug plugins for ImageJ 最近在做一个关于卫星遥感全链路仿真的项目,由于项目是基于ImageJ开发,而Imag ...

  2. 如何在Unity中开发Leap Motion桌面版(Non-VR)APP

    最近因需要,翻出几年前的Leapmotion感测器,准备用Unity3D做个互动APP,于是连上官网下载SDK.等下载下来一安装调试,瞬间傻眼,居然要求VR设备.我们Lab倒是不缺VR,有几套VIVE ...

  3. 老李分享:Eclipse中开发性能测试loadrunner脚本

    老李分享:Eclipse中开发性能测试loadrunner脚本 前篇我分享了如何用loadrunner搭建javauser的性能测试脚本环境,本次我来告诉大家如何在eclipse开发loadrunne ...

  4. 服务化改造实践 | 如何在 Dubbo 中支持 REST

    什么是 REST REST 是 Roy Thomas Fielding [[1]](#fn1) 在 2000 年他的博士论文 [[2]](#fn2) “架构风格以及基于网络的软件架构设计” 中提出来的 ...

  5. 如何在Eclipse中写Processing的sketch

    有时候人们需要写更复杂的sketch,此时Processing提供的IDE就略显单薄,下面将介绍如何在eclipse中开发Processing. 一共分4步: 一.搭建环境:安装JRE.JDK.Ecl ...

  6. 如何在Delphi中调用VC6.0开发的COM

    上次写了如何在VC6.0下对Delphi写的COM进行调用,原本想马上写如何在Delphi中调用VC6.0开发的COM时,由于在写事例程序中碰到了个很怪的问题,在我机子上用VC写的接口程序编译能通过. ...

  7. 如何在Ubuntu中使用Eclipse + CDT开发C/C++程序

    在Ubuntu中安装Eclipse和CDT步骤如下: 1. 下载资源(都下载到/home/maxw/Download/Eclipse下)    A. 下载JRE(Java Runtime Enviro ...

  8. 安卓开发_WebView如何在Fragment中使用

    之前学习了如何在activity中使用WebView控件来显示网页. 在我的实际开发中,有需要在Fragment中用到WebView控件的,那么就百度学习了一下 其实很简单,但是当然不是和在Activ ...

  9. CocosCreator游戏开发---菜鸟学习之路(三)如何在CocosCreator中使用Pomelo

    PS(废话): 这段时间都在研究网易的Pomelo框架,作为新手小白,自然遇到了不少坑爹的事情.(当然也有可能是因为自己技术不过关的原因所以导致在很多基础的问题上纠结了很久.)网上也搜索了好久,但是基 ...

随机推荐

  1. 全网详细JAVA知识点干货学习路线目录,值得收藏学习!

    1.Java简介及开发环境配置 2.Java中的注释&关键字&常量&变量&标识符 3.Java中的基本数据类型及其类型转换 4.Java中的运算符及表达式 5.Java ...

  2. NX CAM 读取加工参数

    '取加工几何试图程序组 Function GetGemoGroup_Name(ByVal camObjectTag As NXOpen.Tag) As String Dim theGemoGroupT ...

  3. Visual Studio 安装 C++

    Visual Studio 安装 C++

  4. 永久修改alias

    永久修改alias home目录下ls -a显示隐藏文件 编辑./cshrc

  5. Git: 搭建一个本地私人仓库

    Git: 搭建一个本地私人仓库 寝室放个电脑.实验室也有个电脑 为进行数据同步,充分利用实验室的服务器搭建了个本地私人仓库 1. 安装流程 当然首先保证服务器上与PC机上都已经安装了可用的Git 在P ...

  6. Noip模拟15 2021.7.14

    T1 夜莺与玫瑰 题目越发的变态起来... 这题刚开始看超级像仪仗队,好不容易码完欧拉函数后尝试×2后输出但不对!! 于是选择了跳过.... 正解居然是莫比乌斯函数....我也是醉了 预处理完就剩下$ ...

  7. Noip模拟12 2021.7.12

    T1 interval 亏得昨天晚上改掉了T3并且理解了单调栈,今天一扫这题目就知道要用啥了. 先预处理出以a[i]为最大值的最大左右区间.然后再将a[i]取%!!!是的,要不然会影响单调栈的使用.. ...

  8. 2021.9.7考试总结[NOIP模拟49]

    T1 Reverse $BFS$暴力$O(n^2)$ 过程中重复枚举了很多点,考虑用链表记录当前点后面可到达的第一个未更新点. 搜索时枚举翻转子串的左端点,之后便可以算出翻转后$1$的位置. $cod ...

  9. numpy数组的计算

    1.数组的形状 查看数组的形状: import numpy as np a = np.array([[1, 2, 3, 4, 5], [5, 6, 7, 8, 9]]) print(a.shape) ...

  10. EFCore_环境搭建与简单使用_01

    开发环境搭建 经典步骤:建实体类.建DbContext.生成数据库 本次使用codefirst模式,走下流程,(你也可以先建好数据库,用命令行的形式,直接生成DbContext,而且生成的DbCont ...