《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. 正则表达式: NFA引擎匹配原理

    NFA引擎匹配原理 1       为什么要了解引擎匹配原理 一个个音符杂乱无章的组合在一起,弹奏出的或许就是噪音,同样的音符经过作曲家的手,就可以谱出非常动听的乐曲,一个演奏者同样可以照着乐谱奏出动 ...

  2. 【技术博客】利用handler实现线程之间的消息传递

    [技术博客]利用handler实现线程之间的消息传递 一.handler简介 在Android Studio的开发中,经常需要启动多个线程.比如向远程发送请求时,必须新开一个子线程,否则会造成程序崩溃 ...

  3. Request failed with status code 500以及自引用循环Self referencing loop detected for property ‘xx‘ with type

    错误Error: Request failed with status code 500 ,调试前端没问题,后端也没问题,还报错"连接超时" 在Network中找到错误Self r ...

  4. python3中的bytes和string

    原文链接:https://www.cnblogs.com/abclife/p/7445222.html python 3中最重要的新特性可能就是将文本(text)和二进制数据做了更清晰的区分.文本总是 ...

  5. 洛谷 P5785 [SDOI2012] 任务安排

    链接: P5785 弱化版:P2365 题意: 有 \(n\) 个任务待完成,每个任务有一个完成时间 \(t_i\) 和费用系数 \(f_i\),相邻的任务可以被分成一批.从零时刻开始这些任务会被机器 ...

  6. 深入理解和运用Pandas的GroupBy机制——理解篇

    GroupBy是Pandas提供的强大的数据聚合处理机制,可以对大量级的多维数据进行透视,同时GroupBy还提供强大的apply函数,使得在多维数据中应用复杂函数得到复杂结果成为可能(这也是个人认为 ...

  7. 实验7:基于REST API的SDN北向应用实践

    一.实验目的 1.能够编写程序调用OpenDaylight REST API实现特定网络功能: 2.能够编写程序调用Ryu REST API实现特定网络功能. 二.实验环境 下载虚拟机软件Oracle ...

  8. DeWeb - 物资流转管理系统 - 开发1

    近期一个朋友提到要做一个安卓手机上物资流转管理系统 准备采用deweb练练手! 大致的计划是先做成手机版网页,然后加壳做成APP 一. 登录 界面基本设计如下 用户表设计如下: 待续

  9. 第一篇:《Kubernetes 入门介绍》

    前言:本文是一篇 kubernetes(下文用 k8s 代替)的入门文章,将会涉及 k8s 的技术历史背景.架构.集群搭建.一个 Redis 的例子,以及如何使用 operator-sdk 开发 op ...

  10. 大白话讲解如何解决HttpServletRequest的请求参数只能读取一次的问题

    大家在开发过程中,可能会遇到对请求参数做下处理的场景,比如读取上送的参数中看调用方上送的系统编号是否是白名单里面的(更多的会用request中获取IP地址判断).需要对请求方上送的参数进行大小写转换或 ...