默默学Sharding-Sphere(四)

前三篇对sharding-sphere产品进行了一个入门学习,这篇转自某博客专栏对sharding-sphere作者的一些问题,加强对sharding-sphere进行一个认识。
Q:Sharding-JDBC 的设计初衷是什么?旨在解决什么场景的问题?
Sharding-JDBC 的设计初衷是想提供一个数据库中间层,用于透明的处理分库分表,而无需业务开发人员在业务代码中根据分片键生成 SQL。
第一版的分库分表并不是现有的 Sharding-JDBC,而是当当的一个内部框架 ddframe 的数据库模块,dd-rdb 的其中一项功能就是分库,没有分表功能,当时只是做了简单的 SQL 解析。后来随着 ddframe 被各个团队采用,只分库的需求渐渐不够用了,而 dd-rdb 里面有大量的数据库 ORM 相关的东西,为了使分库分表这一核心需求更加纯粹,我们才将其中的分片的部分单独提炼出来并命名为 Sharding-JDBC,用于在 Java 的 JDBC 层面提供一层驱动,无缝的处理这方面的需求。

Q:Sharding-JDBC 适用于哪些场景,不适用于哪些场景?是否有性能评估?
对于关系型数据库数据量很大的情况,需要进行水平拆库和拆表,这种场景很适合使用 Sharding-JDBC。

举例说明:假设有一亿数据的用户库,放在 MySQL 数据库里查询性能会比较低,而采用水平拆库,将其分为 10 个库,根据用户的 ID 模 10,这样数据就能比较平均的分在 10 个库中,每个库只有 1000w 记录,查询性能会大大提升。分片策略类型非常多,大致分为 Hash + Mod、Range、Tag 等。
Sharding-JDBC 还提供了读写分离的能力,用于减轻写库的压力。
此外,Sharding-JDBC 可以用在 JPA 场景中,如 JPA、Hibernate、Mybatis,Spring JDBC Template 等任何 Java 的 ORM 框架。
Java 的 ORM 框架也都是采用 JDBC 与数据库交互。这也是我们选择在 JDBC 层,而非选择一个 ORM 框架进行开发的原因。我们希望 Sharding-JDBC 可以尽量的兼容所有的 Java 数据库访问层,并且无缝的接入业务应用。
不合适的场景主要是两方面:

  1. 不适合 OLAP 的场景。虽然 Sharding-JDBC 也能做聚合分组查询,但大量的 OLAP 场景,仍然会比较慢,而且复杂的 SQL(如子查询等)目前还没有支持。这种查询不太适合大数据和高并发的互联网 online 数据库,建议使用合理的 OLTP 查询。
  2. 不适合事务强一致的要求。目前 Sharding-JDBC 的事务支持两种,一种是弱 XA,另一种是柔性事务(BASE)。因为 XA 的两阶段或三阶段提交其性能较低,因此互联网公司基本不会采用。而无论是弱 XA 还是柔性事务,都无法保证事务在任意时间段完全保证一致,其中柔性事务能保证数据的最终一致性,但达到最终一致性的时间仍然不可控。因此对于对跨库事务强一致要求很高的场景,需要从设计方面去考虑数据库 schema 的合理性。
    对于 JTA 事务,目前 Shariding-JDBC 没有实现 JTA 的标准。而且由于在互联网场景下使用 JTA 比较少见,因此暂时不支持 JIA 事务。
    在 osgit 上有性能测试文档。单库的场景下,由于需要进行 SQL 解析以及路由,器性能损失是 0.02%。双库的场景下,采用了分布式的方式存取数据,性能提升越 94%。

Q:Sharding-JDBC 和其他同类产品有什么区别?能不能集成到 SparkSQL 或者 Hive?
目前和 Sharding-JDBC 这种基于 JDBC 层架构类似的,据我所知只有 TDDL,而 TDDL 并未将分库分表这块开源。基于 JDBC 层进行分片的好处是轻量、简单、兼容性好以及无需额外的运维工作。缺点是无法跨语言,目前仅支持 Java。
现在暂时未考虑集成 SparkSQL 或者 Hive。因为 Sharding-JDBC 的定位还是关系型数据库中间层,为了稳定性的考虑,不会改变数据库的存储引擎。未来我们会做基于 Proxy 版本的 Sharding-JDBC-Server,会渐渐的考虑将 Spark 等大数据的查询方式引入进来。

Q:Sharding-JDBC 与 Mycat 有一定的相似性,区别点在于对于 SQL 语句的自解析上,是否可以这么理解?
从设计理念上看确实有一定的相似性。主要流程都是 SQL 解析 -> SQL 改写 -> SQL 路由 -> SQL 执行 -> 结果归并。但架构设计上是不同的。Mycat 是基于 Proxy,它复写了 MySQL 协议,将 Mycat Server 伪装成一个 MySQL 数据库,而 Sharding-JDBC 是基于 JDBC 接口的扩展,是以 jar 包的形式提供轻量级服务的。
SQL 解析这块,现在的 Shariding-JDBC 和 Mycat 也比较相似,都是使用 Druid 作为 SQL 解析的基础类库。但 Sharding-JDBC 正在重写 SQL 解析这块,是去掉 Duird 的完全自研版本。不可否认 Druid 是一个优秀的连接池,而且 SQL 解析这块做得也很强,但它毕竟不是一个专门为了 Sharding 而做的 SQL 解析器,它的大致解析流程是 Lexer -> Parser -> AST -> Vistor,使用者需要实现它的 Vistor 接口,将自己的业务逻辑在 Vistor 中实现,因此需要通过 Vistor 再生成 SharidingContext,而抽象语法树 AST,也需要对 SQL 完全理解。Sharding-JDBC 自研的 SQL 解析器,对于 Sharding 不相关的关键词采用跳过的方法,整体解析流程简化为 Lexer -> Parser -> SharidingContext,在性能以及实现复杂度上都有所突破。

Q:Sharding-JDBC 是否支持读写分离?
Sharding-JDBC 从 1.3.0 开始支持读写分离。其功能包括:

  1. 根据配置区分写库和多个读库,目前暂时只有轮训策略选取读库,可以配合分库分表使用。
  2. 通过 Hint 强制指定某次查询走写库。
  3. 如果在同一线程且同一数据库连接中有发现 DML 语句,则该 DML 之后的查询都从写库查询,DML 之前的 DQL 语句不受影响,仍然查询读库。其目的是保持同一用户线程的数据一致性。

但限于 Sharding-JDBC 本身设计的考虑,数据库层面的主从切换以及主从数据同步,Sharding-JDBC 并不负责。Sharding-JDBC 定位仍然是轻量级的增强版数据库驱动。因此由于主库和从库同步延迟导致的数据不一致,并不是 Sharding-JDBC 的处理范畴。
另外由于 Sharding-JDBC 本身是分库分表中间件,读写分离也是后加入的功能,因此可以支持分库分表+读写分离,但是仅读写分离目前还不容易配置,未来也会将读写分离提炼出来作为独立的 API 使用。

Q:在现有的系统架构的基础上,Sharding-JDBC 能否与第三方数据库连接池(如:C3P0,Druid 等)集成,实现分库分表+读写分离?
是的,可以支持。Shariding-JDBC 本意就是只做分片 + 读写分离,连接池应该交由连接池去处理,各做各的互不影响。

Q:分库分表使用 like 查询,是否能查询出来?性能如何?会去查询所有的库和表吗?
● 分库分表使用 like 查询是有限制的。目前 Shariding-JDBC 不支持 like 语句中包含分片键,但不包含分片键的 like 语句可以正确执行。
● 至于 like 性能问题,是与数据库相关的,Shariding-JDBC 仅仅是解析 SQL 以及路由至正确的数据源而已。
● 是否会查询所有的库和表是根据分片键决定的,如果 SQL 中不包括分片键,就会查询所有库和表,这个和是否有 like 没有关系。

Q:Sharding-JDBC 是否有完善的管理配置界面?
目前 Sharding-JDBC 还没来得及做配置界面。目前主要集中于以 jar 包的形式提供服务,和业务应用一起发布,旨在简化开发,对 DBA 无影响,因此 DBA 看到的还是分库后的零散的数据库。
未来会做配置中心,用于动态的修改分片数据源,也会配套的提供管理界面。未来还会将数据库的 Metadata 统一管理起来,为 DBA 提供更加友好的服务。

Q:Sharding-JDBC 如何强制查询走主库?
大致使用方式如下:
HintManager hintManager = HintManager.getInstance();
hintManager.setMasterRouteOnly();
// 继续JDBC操作

Q:Sharding-JDBC 是如何解决系统鲁棒性的问题的?我们的后台对服务的可靠性要求比较高,目前还在考虑异地灾备的情况。如使用 Sharding-JDBC 的话,碎片化的库表结构是否会增加运维难度?
因为 Sharding-JDBC 是一个 jar,它与业务应用的生命周期是一致的,同生同死。因此只要解决好使用 Sharding-JDBC 的业务系统的鲁棒性就可以了。
碎片化库表的问题,即使不用 Shariding-JDBC 分库分表,也会同样存在的,Shariding-JDBC 确实没处理这块,不过也不会更加恶化。
等核心稳定后,未来会考虑为 DBA 做运维工具。

Q:请问 Sharding-JDBC 自研的 SQL 解析器开源否?性能能否有大的提升?另外,现在当当的业务中,数据库的分库分表迁移可否自动化?
Sharding-JDBC 自研的 parser 是开源的,目前在 parser 这个分支,但是还未做完,仍然在快速的迭代中。
SQL 解析原理和 Druid 基本相同,但是简化了一些流程。Duird 的初衷是对 SQL 进行监控、分析以及规范化,因此它的 SQL 解析场景需要对 SQL 进行完全的理解。采用 Druid 的作为基础解析器的 Sharding-JDBC 解析流程为:(Lexer -> Parser -> AST -> Vistor) -> SharidingContext,其中括号内是 Duird 框架的流程,无法修改。而 Sharding-JDBC 仅需理解与 Sharding 相关的关键字,无关内容则采取跳过的方式,因此将直接生成分片上下文,无需再通过抽象语法树的访问器再获取。
New Parser 的解析流程简化为:Lexer -> Parser -> SharidingContext。因此在性能以及实现复杂度上都有所突破。具体的性能测试报告目前还未做,会随着 New Parser 分支完全一起发布。
关于分库分表自动迁移的事,当当还没有做到自动化。由于数据迁移更加贴近于数据库运维工具,和 JDBC关系不大,因此 Shariding-JDBC 也暂时未将数据迁移纳入范围。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值