海量数据分库分表方案(二)技术选型与sharding-jdbc实现
上一章已经讲述分库分表算法选型,本章主要讲述分库分表技术选型
文中关联上一章,若下文出现提及其时,可以点击 分库分表算法方案与技术选型(一)
主要讲述
- 框架比较
- sharding-jdbc、zdal 代码实现样例,如需源码可在后文中查看
- 主键生成策略
可以按需阅读文章
点赞再看,关注公众号:【地藏思维】给大家分享互联网场景设计与架构设计方案
掘金:地藏Kelvin https://juejin.im/user/5d67da8d6fb9a06aff5e85f7
常见框架
除了原生JDBC,网上常见分库分表框架有:
当当网 sharding-jdbc
alibaba.cobar (是阿里巴巴(B2B)部门开发)
MyCAT(基于阿里开源的Cobar产品而研发)
蚂蚁金服 ZDAL (开源)
蘑菇街 TSharding
当然除了这些,还有很多各自公司提出的框架,但是根据用户量较高的为以上几种。
其中自从出现基于cobar的MyCAT,zdal,也很少人用cobar了。ZDAL虽然也是开源,但是很少文章和使用反馈,不支持MongoDb,交流活跃度也比较低。
所以本次文章来比较一下活跃度较高的sharding-jdbc和MyCAT。
扩展阅读:当当网做的不错的,除了sharding-jdbc,还有elastic-job用于定时任务分片
对比概览
| 主要指标 | Sharding-jdbc | Mycat | zdal |
|---|---|---|---|
| ORM支持 | 任意 | 任意 | 任意 |
| 事务 | 自带弱XA、最大努力送达型柔性事务BASE | 自带弱XA | 自带弱XA、最大努力送达型柔性事务BASE |
| 分库 | 支持 | 支持 | 支持 |
| 分库 | 支持 | 不支持单库分表 | 支持 |
| 开发 | 开发成本高,代码入侵大 | 开发成本小,代码入侵小 | 开发成本不算高配置明确 |
| 所属公司 | 当当网 | 基于阿里Cobar二次开发,社区维护 | 蚂蚁金服 |
| 数据库支持 | 任意 | Oracle、 SQL Server、 Mysql、DB2、mongodb | 不支持mongodb |
| 活跃度 | 也有不少的企业在最近几年新项目使用 | 社区活跃度很高,一些公司已在使用 | 活跃度低 |
| 监控 | 无 | 有 | |
| 读写分离 | 支持 | 支持 | |
| 资料 | 资料少、github、官网、网上讨论贴 | 资料多,github、官网、Q群、书籍 | 少 |
| 运维 | 维护成本低 | 维护成本高 | 维护成本低 |
| 限制 | 部分JDBC方法不支持、SQL语句限制 | SQL语句限制 | |
| 连接池 | druid版本 | 无要求 | 无要求 |
| 配置难度 | 一般 | 复杂 | 比较简单,读写分离、分开分表规则设置量少 |
关键指标对比
1.开发与运维成本
sharding-jdbc
- sharding-jdbc是一个轻量级框架,不是独立运行中间件,以工程的依赖jar的形式提供功能,无需额外部署,可以理解为增强版JDBC驱动。
- 对运维、DBA人员无需感知代码与分片策略规则,运维只需要维护执行建立表和数据的迁移。
- 相对Mycat这是sharding-jdbc的优势,减少了部署成本以及DBA学习成本。
- 原理是通过规则改写原sql,如select * from A 根据规则变成select * from A_01,运行执行sql时就会向mysql服务器传select * from A_01指令。
MyCat
- 而MyCat并不是业务系统代码里面的配置,而是独立运行的中间件,所以配置都会交给DBA执行。
- 对于DBA来说,他是一个在mysql Server前,增加一层代理,mycat本身不存数据,数据是在后端的MySQL上存储的,因此数据可靠性以及事务等都是MySQL保证的。
- 为了减少迁移数据的风险,在 上一章推荐的增量迁移算法方案(推荐大家阅读)讲述如何分片达到降低风险。
若用MyCat,DBA需要配置多次的增量分片规则,每配置一次则要重启一次,才能达到一轮的数据迁移。实际上MyCat down掉的时系统都不能对数据库查询,实际依然对所有用户有影响。 - 然而sharding-jdbc都在代码实现路由规则,则可以减少DBA操作次数和系统重启次数,进而减少影响用户数。
推荐阅读第一章的第五节才比较好理解上述3~4点 分库分表算法方案与技术选型(一)
- proxy整合大数据思路,将 OLTP 和 OLAP 分离处理,可能会对大数据处理的系统比较适合,毕竟数据工作不一定有java后端系统。
该点总结:sharding-jdbc增量分片和增量迁移数据效果更佳,mycat比较适合大数据工作
备注:
sharding-jdbc增强了JDBC驱动部分功能,但同时也限制部分原生JDBC接口的使用。具体限制参考:
限制情况:http://dangdangdotcom.github.io/sharding-jdbc/01-start/limitations/ 这个文档现在好像访问不了
附:
官网文档
官网源码
2.分库分表能力
- sharding-jdbc另一个优势是他的分表能力,可以不需要分库的情况下单库分表。
- MyCAT不能单库分多表,必须分库,这样就会造成让DBA增加机器节点,即使不增加机器节点,也会在同一个机器上增加mysql server实例,若使用sharding-jdbc单库分多表,则DBA只需要执行建立表语句即可。
3.事务
首先说说XA, XA 多阶段提交的方式,虽然对分布式数据的完整性有比较好的保障,但会极大的降影响应用性能。
sharding-jdbc和mycat支持弱XA,弱 XA 就是分库之后的数据库各自负责自己事务的提交和回滚,没有统一的调度器集中处理。这样做的好处是天然就支持,对性能也没有影响。但一旦出问题,比如两个库的数据都需要提交,一个提交成功,另一个提交时断网导致失败,则会发生数据不一致的问题,而且这种数据不一致是永久存在的。
柔性事务是对弱 XA 的有效补充。柔性事务类型很多。
Sharding-JDBC 主要实现的是最大努力送达型。即认为事务经过反复尝试一定能够成功。如果每次事务执行失败,则记录至事务库,并通过异步的手段不断的尝试,直至事务成功(可以设置尝试次数,如果尝试太多仍然失败则入库并需要人工干预)。在尝试的途中,数据会有一定时间的不一致,但最终是一致的。通过这种手段可以在性能不受影响的情况下牺牲强一致性,达到数据的最终一致性。最大努力送达型事务的缺点是假定事务一定是成功的,无法回滚,因此不够灵活。
备注:
还有一种柔性事务类型是 TCC,即 Try Confirm Cancel。可以通过事务管理器控制事务的提交或回滚,更加接近原生事务,但仍然是最终一致性。其缺点是需要业务代码自行实现 Try Confirm Cancel 的接口,对现有业务带来一定冲击。Sharding-JDBC 未对 TCC 的支持。
4.监控
为什么要监控,因为上述事务的弱XA、最大努力送达型,其实还是有概率失败。
- MyCat就要监控页面,监控MyCat与Mysql server的心跳,运维人员可以看到
- 而sharding-jdbc没有监控事务是不是最终执行了,可能需要改写源码,如果有个分片没执行成功就发一下短信、钉钉之类的。
MyCat监控配置样例
5.语句限制
- sharding-jdbc分库分表使用 like 查询是有限制的。目前 Shariding-JDBC 不支持 like 语句中包含分片键,但不包含分片键的 like 语句可以正确执行。
至于 like 性能问题,是与数据库相关的,Shariding-JDBC 仅仅是解析 SQL 以及路由至正确的数据源而已。
是否会查询所有的库和表是根据分片键决定的,如果 SQL 中不包括分片键,就会查询所有库和表,这个和是否有 like 没有关系。 - MyCat没有限制
6.比较蚂蚁金服的zdal
相对zdal来说,sharding-jdbc的配置量差不多,但是sharding-jdbc提供了java、springboot、yml、spring命名空间方式,而且有官方网站和gitee网站维护。相对zdal用户更加活跃。
Sharding-jdbc分库分表整合mybatis-plus 开发样例
代码样例具体描述,下述关键的开发点。
具体源码请到我的gitee地址sharding-jdbc-example。
sharding-jdbc分片的开发主要几个关键点:
0. 引入关键依赖 2019.10最新版4.0.0-RC2
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-namespace</artifactId>
<version>4.0.0-RC2</version>
</dependency>
- 在xml中配置基础数据源、分库分表的策略,其中DbShardingAlgorithm,TbShardingAlgorithm需要在java代码里面实现。
<--分库的规则对象类->
<bean id="preciseModuloDatabaseShardingAlgorithm" class="com.dizang.sharding.config.algorithm.DbShardingAlgorithm" />
<--分表规则对象类->
<bean id="preciseModuloTableShardingAlgorithm" class="com.dizang.sharding.config.algorithm.TbShardingAlgorithm" />
<--分库根据的key->
<sharding:standard-strategy id="databaseStrategy" sharding-column="user_id" precise-algorithm-ref="preciseModuloDatabaseShardingAlgorithm" />
<--分库根据的key->
<sharding:standard-strategy id="tableShardingStrategy" sharding-column="user_id" precise-algorithm-ref="preciseModuloTableShardingAlgorithm" />
<sharding:key-generator id="orderKeyGenerator" type="SNOWFLAKE" column="id" />
<sharding:data-source id="shardingDataSource">
<--分表数据源->
<sharding:sharding-rule data-source-names="ds0, ds1">
<sharding:table-rules>
<--逻辑表名->
<sharding:table-rule logic-table="t_user"
actual-data-nodes="ds$->{0..1}.t_user_$->{0..2}"
<--分库分表逻辑bean->
database-strategy-ref="databaseStrategy"
table-strategy-ref="tableShardingStrategy"
key-generator-ref="orderKeyGenerator" />
</sharding:table-rules>
<--配置能适用规则的表->
<sharding:binding-table-rules>
<sharding:binding-table-rule logic-tables="t_user" />
</sharding:binding-table-rules>
<--配置不需要分库分表的表->
<sharding:broadcast-table-rules>
<sharding:broadcast-table-rule table="t_order" />
</sharding:broadcast-table-rules>
</sharding:sharding-rule>
</sharding:data-source>
<--sqlSessionFactory配置shardingDataSource数据源->
<bean id="sqlSessionFactory"
class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
<property name="dataSource" ref="shardingDataSource"/>
<property name="mapperLocations" value="classpath*:mapper/*.xml"/>
</bean>
- java代码编写分库策略
需要继承SingleKeyDatabaseShardingAlgorithm分开规则类,重写equal等于、大于、小于时的路由规则
public class DbShardingAlgorithm implements PreciseShardingAlgorithm<Long>{
@Override
public String doSharding(Collection<String> databaseNames, PreciseShardingValue<Long> shardingValue) {
for (String each : databaseNames) {
if (each.endsWith(shardingValue.getValue() % 2 + "")) {
return each;
}
}
return null;
}
}
- java代码编写分表策略
需要继承SingleKeyTableShardingAlgorithm分开规则类,重写equal等于、大于、小于时的路由规则
public class TbShardingAlgorithm implements PreciseShardingAlgorithm<Long>{
@Override
public String doSharding(Collection<String> tableNames, PreciseShardingValue<Long> shardingValue) {
for (String each : tableNames) {
if (each.endsWith(shardingValue.getValue() % 2 + "")) {
return each;
}
}
// return shardingValue.getLogicTableName()+(shardingValue.getValue() % 2);
throw new UnsupportedOperationException();
}
}
zdal具体代码实现推荐阅读
欢迎关注
我的公众号 :地藏思维
我的Gitee: 地藏Kelvin https://gitee.com/dizang-kelvin
推荐阅读sharding-jdbc源码:
海量数据分库分表方案(二)技术选型与sharding-jdbc实现的更多相关文章
- 【分库、分表】MySQL分库分表方案
一.Mysql分库分表方案 1.为什么要分表: 当一张表的数据达到几千万时,你查询一次所花的时间会变多,如果有联合查询的话,我想有可能会死在那儿了.分表的目的就在于此,减小数据库的负担,缩短查询时间. ...
- 基于Mysql数据库亿级数据下的分库分表方案
移动互联网时代,海量的用户数据每天都在产生,基于用户使用数据的用户行为分析等这样的分析,都需要依靠数据都统计和分析,当数据量小时,问题没有暴露出来,数据库方面的优化显得不太重要,一旦数据量越来越大时, ...
- MySQL 分库分表方案,总结的非常好!
前言 公司最近在搞服务分离,数据切分方面的东西,因为单张包裹表的数据量实在是太大,并且还在以每天60W的量增长. 之前了解过数据库的分库分表,读过几篇博文,但就只知道个模糊概念, 而且现在回想起来什么 ...
- MySQL主从(MySQL proxy Lua读写分离设置,一主多从同步配置,分库分表方案)
Mysql Proxy Lua读写分离设置 一.读写分离说明 读写分离(Read/Write Splitting),基本的原理是让主数据库处理事务性增.改.删操作(INSERT.UPDATE.DELE ...
- 重磅来袭,使用CRL实现大数据分库分表方案
关于分库分表方案详细介绍 http://blog.csdn.net/bluishglc/article/details/7696085 这里就不作详细描述了 分库分表方案基本脱离不了这个结构,受制于实 ...
- Mysql分库分表方案
Mysql分库分表方案 1.为什么要分表: 当一张表的数据达到几千万时,你查询一次所花的时间会变多,如果有联合查询的话,我想有可能会死在那儿了.分表的目的就在于此,减小数据库的负担,缩短查询时间. m ...
- Mysql 之分库分表方案
Mysql分库分表方案 为什么要分表 当一张表的数据达到几千万时,你查询一次所花的时间会变多,如果有联合查询的话,我想有可能会死在那儿了.分表的目的就在于此,减小数据库的负担,缩短查询时间. mysq ...
- Mysql 分库分表方案
0 引言 当一张表的数据达到几千万时,你查询一次所花的时间会变多,如果有联合查询的话,我想有可能会死在那儿了.分表的目的就在于此,减小数据库的负担,缩短查询时间. mysql中有一种机制是表锁定和行锁 ...
- mysql 数据库 分表后 怎么进行分页查询?Mysql分库分表方案?
Mysql分库分表方案 1.为什么要分表: 当一张表的数据达到几千万时,你查询一次所花的时间会变多,如果有联合查询的话,我想有可能会死在那儿了.分表的目的就在于此,减小数据库的负担,缩短查询时间. m ...
随机推荐
- 使用Java8中的Optional类来消除代码中的null检查
简介 Optional类是Java 8新增的一个类,Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException). —— 每个 Java 程序员都非常了解的异常 ...
- ZERO:点击影响的量化 & 分清SEO的不可抗力
http://www.wocaoseo.com/thread-331-1-1.html 这篇文章基于上篇(http://www.wocaoseo.com/thread-332-1-1.html)的理论 ...
- UI 科学
以简书为案例讲述「尼尔森十大可用性原则」 http://www.jianshu.com/p/a45e4ad68e20 你真的懂得尼尔森的十大可用性原则么? http://jy.sccnn.com/po ...
- mysql InnoDB引擎是否支持hash索引
看一下mysql官方文档:https://dev.mysql.com/doc/refman/5.7/en/create-index.html , 从上面的图中可以得知,mysql 是支持hash索引的 ...
- [Java数据结构]使用Stack检查表达式中左右括号是否匹配
Stack是一种先进后出的数据结构后,这个特点决定了它在递归向下的场景中有独到的功效. 以下程序展示了它在检查表达式中括号匹配的有效性: 程序: package com.heyang.util; im ...
- Ubuntu下开启/关闭防火墙及端口
有管理员权限可省略sudo. 1.查看端口开启状态 sudo ufw status 2.开启某个端口(以8866为例) sudo ufw allow 8866 3.开启防火墙 sudo ufw ena ...
- UNIX编程艺术
本文主要是 <UNIX编程艺术>的摘录,摘录的主要是我觉得对从事软件开发有用的一些原则. 对于程序员和开发人员来说,如果完成某项任务所需要付出的努力对他们是个挑战却又恰好还在力所能及的范围 ...
- oracle之二数据字典表和动态性能视图
数据字典表和动态性能视图 Oracle提供了大量的内部表,它们记录了数据库对象的更改和修正.可以将这些内部表划分为两种主要类型:静态的数据字典表和动态的性能表.这些内部表是由oracle维护的,可以说 ...
- 人人框架renren-security |小记(第一篇)
一丶首先介绍一下人人框架: 1.简介 renren-security | 轻量级权限管理系统 采用Spring.MyBatis.Shiro框架,开发的一套权限系统,极低门槛,拿来即用 支持分布式部 ...
- sql.表值类型
表值类型是在sql server 2008中新加入的功能,我个人觉得确实很有用,之前从没用过,自从来到现在的公司后学到很多东西,所以和大家分享一下. ------建表值类型语法------------ ...