016 Sharding JDBC组件

官方网站:http://shardingsphere.apache.org/index_zh.html

        Sharding JDBC是Apache ShardingSphere(Incubator) 的一套开源的分布式数据库中间件解决方案组成的生态圈,它由Sharding-JDBC、Sharding-Proxy和Sharding-Sidecar(规划中)这3款相互独立,却又能够混合部署配合使用的产品组成。

MyCat与Sharding JDBC的实现方式对比图:

一、Sharding JDBC架构

二、Sharding JDBC核心概念

1.数据分片

数据分片分为垂直分片和水平分片。

2.SQL

  • 逻辑表

    水平拆分的数据库(表)的相同逻辑和数据结构表的总称。

  • 真实表

    在分片的数据库中真实存在的物理表。

  • 数据节点 数据分片的最小单元。由数据源名称和数据表组成。

  • 绑定表 指分片规则一致的主表和子表。例如: t_order 表和t_order_item 表,均按照order_id 分片,则此两张表互为绑定表关系。绑定表之间的多表关联查询不会出现笛卡尔积关联,关联查询效率将大大提升。

  • 广播表 指所有的分片数据源中都存在的表,表结构和表中的数据在每个数据库中均完全一致。适用于数据量不大且需要与海量数据的表进行关联查询的场景,例如:字典表。

3.分片策略

包含分片键(用于分片的字段)和分片算法;分片键是用于分片的数据库字段,是将数据库(表)水平拆分的关键字段。

3.1分片算法

包含精确分片算法、范围分片算法、复合分片算法、Hint分片算法;

  • 精确分片算法(PreciseShardingAlgorithm)用于处理使用单一键作为分片键的=与IN进行分片的场景。需要配合StandardShardingStrategy使用。

  • 范围分片算法(RangeShardingAlgorithm)用于处理使用单一键作为分片键BETWEEN AND进行分片场景。需要配合StandardShardingStrategy使用。

  • 复合分片算法(ComplexKeysShardingAlgorithm)用于处理使用多键作为分片键进行分片的场景,包含多个分片键的逻辑较复杂,需要应用开发者自行处理其中的复杂度。需要配合ComplexShardingStrategy使用。复合分片示例:

    先范围再取模 1-500 奇数 1 3 .. 499 偶数 24 501-1000 奇数 501 偶数

  • Hint分片算法(HintShardingAlgorithm)用于处理使用Hint行分片的场景。需要配合HintShardingStrategy使用。

3.2 分片策略

包含标准分片策略、复合分片策略、行表达式分片策略、Hint分片策略;

  • 标准分片策略(StandardShardingStrategy)提供对SQL语句中的=, IN和BETWEEN AND的分片操作支持。StandardShardingStrategy只支持单分片键,提供PreciseShardingAlgorithm和RangeShardingAlgorithm两个分片算法。PreciseShardingAlgorithm是必选的,用于处理=和IN的分片。RangeShardingAlgorithm是可选的,用于处理BETWEEN AND分片,如果不配置RangeShardingAlgorithm,SQL中的BETWEEN AND将按照全库路由处理。

  • 复合分片策略(ComplexShardingStrategy)提供对SQL语句中的=, IN和BETWEEN AND的分片操作支持。ComplexShardingStrategy支持多分片键,由于多分片键之间的关系复杂,因此并未进行过多的封装,而是直接将分片键值组合以及分片操作符透传至分片算法,完全由应用开发者实现,提供最大的灵活度。

  • 行表达式分片策略【实际场景常用】(InlineShardingStrategy)使用Groovy的表达式,提供对SQL语句中的=和IN的分片操作支持,只支持单分片键。对于简单的分片算法,可以通过简单的配置使用,从而避免繁琐的Java代码开发。行表达式的使用非常直观,只需要在配置中使用${ expression } 或$->{ expression } 标识行表达式即可。 目前支持数据节点和分片算法这两个部分的配置。行表达式的内容使用的是Groovy的语法,Groovy能够支持的所有操作,行表达式均能够支持。

  • Hint分片策略(HintShardingStrategy)通过Hint而非SQL解析的方式分片的策略。对于分片字段非SQL决定,而由其他外置条件决定的场景,可使用SQL Hint灵活的注入分片字段。

4.配置

分片规则:分片规则配置的总入口。包含数据源配置、表配置、绑定表配置以及读写分离配置等。数据源配置:真实数据源列表,结合数据库连接池使用 表配置:逻辑表名称、数据节点与分表规则的配置。

数据节点配置:用于配置逻辑表与真实表的映射关系。可分为均匀分布和自定义分布两种形式数据源分片策略对应于DatabaseShardingStrategy。用于配置数据被分配的目标数据源。

表分片策略 对应于TableShardingStrategy。用于配置数据被分配的目标表,该目标表存在与该数据的目标数据源内。故表分片策略是依赖与数据源分片策略的结果的。

自增主键生成策略,通过在客户端生成自增主键替换以数据库原生自增主键的方式,做到分布式主键无重复。(UUID和雪花算法)

三、Sharding JDBC安装使用

1.多数据库支持

 

2.Sharding JDBC安装

引入Maven依赖,调用API编程实现,最新的是shardingJDBC4.0RC;

<!--引入shardingJDBC -->
<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>sharding-jdbc-core</artifactId>
    <version>3.0.0</version>
</dependency>

3.Sharding JDBC核心组件

解析引擎:做词法解析及语法解析,然后形成语法树,之后交给路由引擎;

路由引擎

        标准路由是ShardingSphere最为推荐使用的分片方式,它的适用范围是不包含关联查询或仅包含绑定表之间关联查询的SQL。 当分片运算符是等于号时,路由结果将落入单库(表),当分片运算符是BETWEEN或IN时,则路由结果不一定落入唯一的库(表),因此一条逻辑SQL最终可能被拆分为多条用于执行的真实SQL。

step1 JAVA_Demo

  • 表结构
DROP TABLE IF EXISTS `t_order_0`;
CREATE TABLE `t_order_0` (
`oid` int(11) NOT NULL,
`uid` int(11) DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`oid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  • pom.xml
<dependency>
<groupId>io.shardingsphere</groupId>
<artifactId>sharding-jdbc-core</artifactId>
<version>3.0.0</version>
</dependency>
<!-- mysql 数据库驱动. -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!-- 数据源 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.26</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.6</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.6</version>
</dependency>
  • sharding.java
Map<String, DataSource> map=new HashMap<>();
map.put("kkb_ds_0",
createDataSource("root","root","jdbc:mysql://192.168.24.128:3306/kkb_ds_0"));
map.put("kkb_ds_1",
createDataSource("root","root","jdbc:mysql://192.168.24.128:3306/kkb_ds_1"));
ShardingRuleConfiguration config=new ShardingRuleConfiguration();
// 配置Order表规则
TableRuleConfiguration orderTableRuleConfig = new
TableRuleConfiguration();
orderTableRuleConfig.setLogicTable("t_order");//设置逻辑表.
orderTableRuleConfig.setActualDataNodes("kkb_ds_${0..1}.t_order_${0..1}");//设置
实际数据节点.
orderTableRuleConfig.setKeyGeneratorColumnName("oid");//设置主键列名称.
// 配置Order表规则:配置分库 + 分表策略(这个也可以在ShardingRuleConfiguration进
行统一设置)
orderTableRuleConfig.setDatabaseShardingStrategyConfig(new
InlineShardingStrategyConfiguration("uid", "kkb_ds_${uid % 2}"));
orderTableRuleConfig.setTableShardingStrategyConfig(new
InlineShardingStrategyConfiguration("oid", "t_order_${oid % 2}"));
config.getTableRuleConfigs().add(orderTableRuleConfig);
try {
DataSource ds=ShardingDataSourceFactory.createDataSource(map,
config, new HashMap(), new Properties());
for(int i=1;i<=10;i++) {
String sql="insert into t_order(uid,name) values(?,?)";
execute(ds,sql,i,i+"aaa");
}
System.out.println("数据插入完成。。。");
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

step2 案例Springboot2+mybatisplus+shardingJDBC3 实现数据分片、读写分离、广播表、主键自增、绑定表

  • user tel E-R
  • code 全局表
  • store 读写分离
  • 表结构
  • 分库分表
--用户表
CREATE TABLE `user_0` (
`uid` int(11) NOT NULL DEFAULT '0',
`name` varchar(255) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
PRIMARY KEY (`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--地址表
CREATE TABLE `address_0` (
`aid` int(11) NOT NULL,
`name` varchar(255) DEFAULT NULL,
`uid` int(11) DEFAULT NULL,
PRIMARY KEY (`aid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--字典表
CREATE TABLE `code` (
`id` bigint(20) NOT NULL,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
# 数据源 ds0,ds1
sharding.jdbc.datasource.names=ds0,ds1
# 第一个数据库
sharding.jdbc.datasource.ds0.type=com.zaxxer.hikari.HikariDataSource
sharding.jdbc.datasource.ds0.driver-class-name=com.mysql.jdbc.Driver
sharding.jdbc.datasource.ds0.jdbc-url=jdbc:mysql://192.168.24.128:3306/ds0?
characterEncoding=utf-8
sharding.jdbc.datasource.ds0.username=root
sharding.jdbc.datasource.ds0.password=root
# 第二个数据库
sharding.jdbc.datasource.ds1.type=com.zaxxer.hikari.HikariDataSource
sharding.jdbc.datasource.ds1.driver-class-name=com.mysql.jdbc.Driver
sharding.jdbc.datasource.ds1.jdbc-url=jdbc:mysql://192.168.24.129:3306/ds1?
characterEncoding=utf-8
sharding.jdbc.datasource.ds1.username=root
sharding.jdbc.datasource.ds1.password=root
# 水平拆分的数据库(表) 配置分库 + 分表策略 行表达式分片策略
# 分库策略 user表和address表都用uid作为分库键
sharding.jdbc.config.sharding.default-database-strategy.inline.shardingcolumn=
uid
sharding.jdbc.config.sharding.default-database-strategy.inline.algorithmexpression=
ds$->{uid % 2}
# 分表策略 其中user为逻辑表 分表主要取决于age行
sharding.jdbc.config.sharding.tables.user.actual-data-nodes=ds$->{0..1}.user_$->
{0..1}
sharding.jdbc.config.sharding.tables.user.table-strategy.inline.shardingcolumn=
age
#分表策略
sharding.jdbc.config.sharding.tables.address.actual-data-nodes=ds$->
{0..1}.address_$->{0..1}
sharding.jdbc.config.sharding.tables.address.table-strategy.inline.shardingcolumn=
aid
# 分片算法表达式
sharding.jdbc.config.sharding.tables.user.table-strategy.inline.algorithmexpression=
user_$->{age % 2}
sharding.jdbc.config.sharding.tables.address.table-strategy.inline.algorithmexpression=
address_$->{aid % 2}
#广播表配置
sharding.jdbc.config.sharding.broadcast-tables=code
# 主键 SNOWFLAKE 18位数 如果是分布式还要进行一个设置 防止主键重复
sharding.jdbc.config.sharding.tables.code.key-generator-column-name=id
#绑定表
sharding.jdbc.config.sharding.binding-tables=user,address
# 打印执行的数据库以及语句
sharding.jdbc.config.sharding.props.sql.show=true
spring.main.allow-bean-definition-overriding=true

读写分离 :

CREATE TABLE `tstore` (
`id` int(11) NOT NULL,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

先让数据库主从复制 :

# 数据源 ds0,ds1
sharding.jdbc.datasource.names=ds-master,ds-slave
#主库
sharding.jdbc.datasource.ds-master.type=com.zaxxer.hikari.HikariDataSource
sharding.jdbc.datasource.ds-master.driver-class-name=com.mysql.jdbc.Driver
sharding.jdbc.datasource.ds-master.jdbcurl=
jdbc:mysql://192.168.24.128:3306/db_store?characterEncoding=utf-8
sharding.jdbc.datasource.ds-master.username=root
sharding.jdbc.datasource.ds-master.password=root
#从库
sharding.jdbc.datasource.ds-slave.type=com.zaxxer.hikari.HikariDataSource
sharding.jdbc.datasource.ds-slave.driver-class-name=com.mysql.jdbc.Driver
sharding.jdbc.datasource.ds-slave.jdbcurl=
jdbc:mysql://192.168.24.129:3306/db_store?characterEncoding=utf-8
sharding.jdbc.datasource.ds-slave.username=root
sharding.jdbc.datasource.ds-slave.password=root
#名字
sharding.jdbc.config.masterslave.name=ds_ms
#主库
sharding.jdbc.config.masterslave.master-data-source-name=ds-master
#从库
sharding.jdbc.config.masterslave.slave-data-source-names=ds-slave
# 打印执行的数据库以及语句
sharding.jdbc.config.sharding.props.sql.show=true
spring.main.allow-bean-definition-overriding=true

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值