喝茶聊方案:分库分表之开源组件一览

2,883 阅读6分钟

开源分库分表组件概览

先看下市面常提到的分库分表中间件:
注:排名不分先后

  • 开源社区的Sharding-JDBC
  • 民间组织的MyCAT
  • 阿里的 Cobar
  • 360的Atlas
  • 美团点评DBProxy
  • 美团点评的Zebra
  • 携程DAL

看了这么多中间件,心里会嘀咕这么多中间件,我们应该用哪个,具体哪个有优势,劣势是什么. 别着急,我们先了解下具体实现层面,有了基础实现层面的基础知识我们再比对下优势劣势.

分库分表组件实现层面

分库分表可以有哪些实现

实现分库分表可以有以下层面来实现

graph TD
编码层 --> 框架层 --> 驱动层 -->代理层 --> 实现层

① 编码层 比如通过Spring中动态切换数据源的抽象类实现,具体参见AbstractRoutingDataSource。

这种实现方式目前并没有通用的解决方案.

② 框架层 在ORM框架层面实现,主要是修改或增强现有ORM框架的功能,在SQL中增加一些自定义语法或者hint来实现。比如说携程DAL

③ 驱动层 根据JDBC 协议,做一套实现, 上层业务代码无需改动。比如说 Sharding-JDBC

④ 代理层 介于业务应用于DB实例之间,通过代理业务应用的请求,然后拆分实际sql请求,分发到不同后端DB实例后,对返回结果进行处理。比如说民间组织的MyCAT

⑤ 实现层 是指数据库本身实现。如TiDB

能简单点分嘛?

上面看了些实现层面以及具体组件,就感觉分库分表组件有点杂了
杂了?-> 复杂了
简单点来分的话,分库分表组件可以分为俩大类

  • Client模式
  • Proxy模式

这里借用下图来看一下

Client模式

image.png
Client 模式就是说分库分表的实现随同你的应用代码一起,调用直接访问底层实际数据库。比如上文说到的编码层,框架层,驱动层都算是Client模式

Proxy模式

image.png
Proxy模式就是说分库分表组件在应用和实际数据库之间。接受应用请求根据分片规则分发到具体的数据库实例。 上文说的代理层就算是Proxy模式。

那么我们再看下具体模式关系是:

  • 开源社区的Sharding-JDBC(client 模式,ps:新版本也有proxy模式)
  • 美团点评的Zebra (client 模式)
  • 民间组织的MyCAT (proxy模式,基于cobar演变)
  • 美团点评DBProxy(proxy模式,基于360Atlas,目前只支持mysql5.5和5.6)
  • 360的Atlas (proxy模式,基于mysql官方mysql proxy)
  • 阿里的 Cobar (proxy 模式)

组件对比

那么Client模式组件和Proxy组件有什么优缺点?

拿一个Client 模式组件:Sharding-JDBC和一个Proxy 模式组件:民间组织的MyCAT,来对比下,这里整理了个表格

Sharding-JDBC(client 模式)MyCat(proxy 模式)
ShardingSphere-JDBC(client 模式)MyCat(proxy 模式)
数据库任意MySQL、Oracle、DB2、SQL Server、PostgreSQL
连接消耗数
异构语言仅 Java任意
性能损耗损耗低损耗略高
多表join是(符合条件的分片进行笛卡尔积,然后对每个分片组合发送一个join sql)仅支持2个表join
全局表join
ER join是(前提ER关系分片)(也就是主表和子表处于相同分片)是(前提ER关系分片)(也就是主表和子表处于相同分片)
分页支持,额外性能消耗,内部有优化方案,实际效果不确定支持,额外性能消耗大,无明显优化方案
分库分表支持支持
分片算法精确,范围,复合分片(多key),hint分片(分片键不在sql内),行表达式常见的,hash分片,取模,时间,都支持.
聚合函数支持 sum,count,max,min,avgMyCat的一些自带函数 sum,min,max等可以正确使用,但多分片执行的avg有bug,执行的结果是错误的
支持的关键字group by,order by ,limit ,join,usinggroup by,order by ,limit ,join,using
不支持使用的sql关键字1 SQL语句中针对所有字段使用OR 、DISTINCT、UNION、having2 between and 中有子查询3 同时使用普通聚合函数和DISTINCT聚合函数1 跨分片(实体库)的交叉查询2 跨节点的联合查询 (如用户库的表和平台库的表做联合查询)3 复制插入Insert into…select4 多行插入 insert into tab_a(c1,c2) values(v1,v2),(v11,v21)5 Order by字段必须出现在select中6 Group by务必使用标准语法select count(1),type from tab_a group by type
事务支持本地事务模式:支持单库事务,跨库事务弱支持,完全支持因逻辑异常导致的跨库事务,不支持因网络、硬件异常导致的跨库事务XA模式:支持跨库事务单库事务支持,跨库事务弱支持
后端mysql实例平滑扩容实际应用,目前处于alpha 开发阶段仅一致性 hash 规则分片支持迁移或扩容

注:对比表格调研时间2020年6月

组件对比表中问题点讨论

  • 为什么Proxy模式比Client模式连接数消耗低 Proxy模式只有少量proxy服务器与物理db连接,假设 proxy服务器是10台,db物理机器是10, 则有10*10=100个连接. 这100个连接,无论多少个客户端都是用这100个连接 Client模式只要有几个应用客户端就会与db建立多少连接, 假设 客户端应用服务器是10台,db物理机器是10,则只有10个客户端可以用,如果客户端是20个,则连接是200个
  • 什么是全局表 全局表是一些不经常变动的基础数据. 全局表是一张字典表,在每个分片存一份. 每次修改向各个表同步
  • 什么是ER关系分片 子表的记录与所关联的父表记录存放在同一个数据分片上
  • 什么是ER join 子表的记录与所关联的父表记录存放在同一个数据分片上,每个分片进行局部join,然后所有分片合并
  • 什么是Hint分片策略 对于分片字段非 SQL 决定,而由其他外置条件决定的场景

参考

美团点评 Zebra
奇虎360 Atlas
Mycat github地址
alibaba cobar
分库分表中间件对比
“分库分表" ?选型和流程要慎重,否则会失控