Apache ShardingSphere 实现分库分表及读写分离
本文为博主原创,未经允许不得转载:
项目demo 源码地址:https://gitee.com/xiangbaxiang/apache-shardingjdbc
1. 创建Maven项目,并配置 pom 依赖:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId>
<artifactId>apache-shardingjdbc</artifactId>
<version>1.0-SNAPSHOT</version> <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.11.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent> <properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<!--排除默认的tomcat-jdbc-->
<exclusion>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>4.0.0-RC2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.9</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.22</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.2</version>
</dependency> </dependencies> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<!-- <version>2.1.3.RELEASE</version>-->
</plugin>
</plugins>
</build>
</project>
2.创建实体类
package com.sharding.entity; import lombok.Data; @Data
public class User {
private Long id ;
private Integer age ;
private String name;
private Long cid;
}
3. 创建 mapper 类
package com.sharding.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.sharding.entity.User;
import org.apache.ibatis.annotations.Mapper; @Mapper
public interface UserMapper extends BaseMapper<User> {
}
4. 创建控制层
package com.sharding.controller; import com.sharding.entity.User;
import com.sharding.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import java.util.Random; @RestController
@RequestMapping("sharding")
public class UserController { @Autowired
private UserMapper userMapper; @RequestMapping("saveUser")
public int saveUser(){
User user = new User();
Random random = new Random();
int value = random.nextInt(20);
user.setAge(value);
long longValue = random.nextLong();
user.setCid(longValue);
user.setName("test"+value);
int result = userMapper.insert(user);
return result;
}
}
5. 创建启动类
package com.sharding; import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication
@MapperScan(basePackages = "com.sharding.mapper")
public class ApacheShardingJdbcApplication { public static void main(String[] args) {
SpringApplication.run(ApacheShardingJdbcApplication.class,args);
}
}
6. 创建分库分表的配置文件
#数据库m1,m2
spring.shardingsphere.datasource.names=m1,m2
spring.shardingsphere.datasource.m1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.m1.url=jdbc:mysql://127.0.0.1:3306/userdb?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.m1.username=root
spring.shardingsphere.datasource.m1.password=zengjian spring.shardingsphere.datasource.m2.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m2.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.m2.url=jdbc:mysql://127.0.0.1:3306/userdb2?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.m2.username=root
spring.shardingsphere.datasource.m2.password=zengjian # 分库策略 根据id取模确定数据进哪个数据库
spring.shardingsphere.sharding.default-database-strategy.inline.sharding-column=age
spring.shardingsphere.sharding.default-database-strategy.inline.algorithm-expression=m$->{age % 2+1}
spring.shardingsphere.sharding.binding-tables=user # user表进行分表
spring.shardingsphere.sharding.tables.user.actual-data-nodes=m$->{1..2}.user_$->{1..2} # 分表字段id
spring.shardingsphere.sharding.tables.user.table-strategy.inline.sharding-column=id
# 分表策略 根据id取模,确定数据最终落在那个表中
spring.shardingsphere.sharding.tables.user.table-strategy.inline.algorithm-expression = user_$->{id % 2+1}
#分表列
spring.shardingsphere.sharding.tables.user.key-generator.column=id
#id数据生成算法
spring.shardingsphere.sharding.tables.user.key-generator.type=SNOWFLAKE spring.shardingsphere.props.sql.show=true
spring.main.allow-bean-definition-overriding=true
7. 读写分离的配置文件
#shardingsphere 读写分离,master-slave,可以一主多从
spring.shardingsphere.datasource.names=ds-master,ds-slave0
#主库
spring.shardingsphere.datasource.ds-master.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds-master.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds-master.jdbc-url=jdbc:mysql://112.125.26.63:3306/userdb_master?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
spring.shardingsphere.datasource.ds-master.username=root
spring.shardingsphere.datasource.ds-master.password=root
#从库0
spring.shardingsphere.datasource.ds-slave0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds-slave0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds-slave0.jdbc-url=jdbc:mysql://112.125.26.64:3306/userdb_slave?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
spring.shardingsphere.datasource.ds-slave0.username=root
spring.shardingsphere.datasource.ds-slave0.password=root
#从库1
#spring.shardingsphere.datasource.ds-slave1.type=com.alibaba.druid.pool.DruidDataSource
#spring.shardingsphere.datasource.ds-slave1.type=com.zaxxer.hikari.HikariDataSource
#spring.shardingsphere.datasource.ds-slave1.driver-class-name=com.mysql.cj.jdbc.Driver
#spring.shardingsphere.datasource.ds-slave1.jdbc-url=jdbc:mysql://112.125.26.65:3306/shop_ds_slave1?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
#spring.shardingsphere.datasource.ds-slave1.username=root
#spring.shardingsphere.datasource.ds-slave1.password=root #读写分离主从规则设置,当有2个以上从库时,从库读采用轮询的负载均衡机制
spring.shardingsphere.masterslave.load-balance-algorithm-type=round_robin
spring.shardingsphere.masterslave.name=ms
spring.shardingsphere.masterslave.master-data-source-name=ds-master
spring.shardingsphere.masterslave.slave-data-source-names=ds-slave0 spring.shardingsphere.props.sql.show=true
spring.main.allow-bean-definition-overriding=true
8.创建启动类
package com.sharding; import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication
@MapperScan(basePackages = "com.sharding.mapper")
public class ApacheShardingJdbcApplication { public static void main(String[] args) {
SpringApplication.run(ApacheShardingJdbcApplication.class,args);
}
}
9.创建对应数据库:userdb , userdb2 , 并分别执行以下脚本
-- ----------------------------
-- Table structure for user_1
-- ----------------------------
DROP TABLE IF EXISTS `user_1`;
CREATE TABLE `user_1` (
`id` bigint(20) NOT NULL,
`name` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
`age` int(11) NULL DEFAULT NULL,
`cid` bigint(20) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Compact; -- ----------------------------
-- Table structure for user_2
-- ----------------------------
DROP TABLE IF EXISTS `user_2`;
CREATE TABLE `user_2` (
`id` bigint(20) NOT NULL,
`name` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
`age` int(11) NULL DEFAULT NULL,
`cid` bigint(20) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Compact;
10. 验证
浏览器请求: http://localhost:8080/sharding/saveUser
查看日志:可以看到sql 执行的逻辑过程如下
2021-11-13 23:54:20.056 INFO 186124 --- [nio-8080-exec-2] ShardingSphere-SQL : SQLStatement: InsertStatement(super=DMLStatement(super=AbstractSQLStatement(type=DML, tables=Tables(tables=[Table(name=user, alias=Optional.absent())]), routeConditions=Conditions(orCondition=OrCondition(andConditions=[AndCondition(conditions=[Condition(column=Column(name=id, tableName=user), operator=EQUAL, compareOperator=null, positionValueMap={}, positionIndexMap={0=0}), Condition(column=Column(name=age, tableName=user), operator=EQUAL, compareOperator=null, positionValueMap={}, positionIndexMap={0=1})])])), encryptConditions=Conditions(orCondition=OrCondition(andConditions=[])), sqlTokens=[TableToken(tableName=user, quoteCharacter=NONE, schemaNameLength=0), SQLToken(startIndex=18)], parametersIndex=4, logicSQL=INSERT INTO user ( id,
age,
name,
cid ) VALUES ( ?,
?,
?,
? )), deleteStatement=false, updateTableAlias={}, updateColumnValues={}, whereStartIndex=0, whereStopIndex=0, whereParameterStartIndex=0, whereParameterEndIndex=0), columnNames=[id, age, name, cid], values=[InsertValue(columnValues=[org.apache.shardingsphere.core.parse.old.parser.expression.SQLPlaceholderExpression@62520960, org.apache.shardingsphere.core.parse.old.parser.expression.SQLPlaceholderExpression@14c57902, org.apache.shardingsphere.core.parse.old.parser.expression.SQLPlaceholderExpression@7c661b99, org.apache.shardingsphere.core.parse.old.parser.expression.SQLPlaceholderExpression@6c580fa2])])
2021-11-13 23:54:20.056 INFO 186124 --- [nio-8080-exec-2] ShardingSphere-SQL : Actual SQL: m1 ::: INSERT INTO user_2 (id, age, name, cid) VALUES (?, ?, ?, ?) ::: [1459550199242993665, 14, test14, -2186172803516415750]
Apache ShardingSphere 实现分库分表及读写分离的更多相关文章
- 使用ShardingSphere-JDBC完成Mysql的分库分表和读写分离
1. 概述 老话说的好:选择比努力更重要,如果选错了道路,就很难成功. 言归正传,之前我们聊了使用 MyCat 实现Mysql的分库分表和读写分离,MyCat是服务端的代理,使用MyCat的好处显而易 ...
- Sharding-JDBC基本使用,整合Springboot实现分库分表,读写分离
结合上一篇docker部署的mysql主从, 本篇主要讲解SpringBoot项目结合Sharding-JDBC如何实现分库分表.读写分离. 一.Sharding-JDBC介绍 1.这里引用官网上的介 ...
- 阿里P8架构师谈:数据库分库分表、读写分离的原理实现,使用场景
本文转载自:阿里P8架构师谈:数据库分库分表.读写分离的原理实现,使用场景 为什么要分库分表和读写分离? 类似淘宝网这样的网站,海量数据的存储和访问成为了系统设计的瓶颈问题,日益增长的业务数据,无疑对 ...
- ShardingSphere-proxy-5.0.0企业级分库分表、读写分离、负载均衡、雪花算法、取模算法整合(八)
一.简要说明 以下配置实现了: 1.分库分表 2.每一个分库的读写分离 3.读库负载均衡算法 4.雪花算法,生成唯一id 5.字段取模 二.配置项 # # Licensed to the Apache ...
- Mycat使用--分库分表和读写分离
Mycat分库分表读写分离 1. 模拟多数据库节点 2. 配置文件 具体操作参看: https://blog.csdn.net/vbirdbest/article/details/83448757 写 ...
- 基于ShardingJDBC的分库分表及读写分离整理
ShardingJDBC的核心流程主要分成六个步骤,分别是:SQL解析->SQL优化->SQL路由->SQL改写->SQL执行->结果归并,流程图如下: sharding ...
- 分库分表、读写分离——用Sql和ORM(EF)来实现
分库:将海量数据分成多个库保存,比如:2017年的订单库——Order2017,2018年的订单库——Order2018... 分表:水平分表(Order拆成Order1.....12).垂直分表(O ...
- 分库分表(7)--- SpringBoot+ShardingSphere实现分库分表 + 读写分离
分库分表(7)--- ShardingSphere实现分库分表+读写分离 有关分库分表前面写了六篇博客: 1.分库分表(1) --- 理论 2.分库分表(2) --- ShardingSphere(理 ...
- 分库分表(5) ---SpringBoot + ShardingSphere 实现分库分表
分库分表(5)--- ShardingSphere实现分库分表 有关分库分表前面写了四篇博客: 1.分库分表(1) --- 理论 2.分库分表(2) --- ShardingSphere(理论) 3. ...
- Springboot2.x + ShardingSphere 实现分库分表
之前一篇文章中我们讲了基于Mysql8的读写分离(文末有链接),这次来说说分库分表的实现过程. 概念解析 垂直分片 按照业务拆分的方式称为垂直分片,又称为纵向拆分,它的核心理念是专库专用. 在拆分之前 ...
随机推荐
- Kafka核心逻辑介绍
1.概念 Kafka是最初由Linkedin公司开发,是一个分布式.支持分区的(partition).多副本的(replica)分布式消息系统(kafka2.8.0版本之后接触了对zk的依赖,使用自己 ...
- XILINX HLS 入坑记录 之 写RAM 综合出 读取+写入Ram
最近使用 Xilinx HLS 来开发 算法的IPcore,使用的Vitis 2021,发现光是 EDA 工具就存在很多的bug,比如: 1.经常C综合 停留在 Using flow_target ' ...
- ElasticSearch给索引起"别名"和其重要性
创建别名: https://www.elastic.co/guide/en/elasticsearch/reference/6.8/indices-aliases.html 我们有时候并不能确保索引库 ...
- 文心一言 VS 讯飞星火 VS chatgpt (164)-- 算法导论13.1 4题
四.用go语言,假设将一棵红黑树的每一个红结点"吸收"到它的黑色父结点中,使得红结点的子结点变成黑色父结点的子结点(忽略关键字的变化).当一个黑结点的所有红色子结点都被吸收后,它可 ...
- 架构与思维:如何应对Redis热Key?
★ Redis系列文章 Redis系列1:深刻理解高性能Redis的本质 Redis系列2:数据持久化提高可用性 Redis系列3:高可用之主从架构 Redis系列4:高可用之Sentinel(哨兵模 ...
- 文件不落地上线sliver
接着二开sliver,给他添加一个生成powershell payload上线的功能,生成并复制到剪切板. 准备 首先,先开启监听,不多说直接mtls默认的就行,sliver可以生成配置文件来实现 ...
- 在线录屏-通过Web API接口轻松实现录屏
在线录屏是指在互联网上进行屏幕录制的过程.它允许用户通过网络连接,将自己的屏幕活动记录下来,并可以在需要时进行播放.共享或存档.在线录屏常用于教育.培训.演示.游戏等场景,可以帮助用户展示操作步骤.解 ...
- 如何将没有复制或移动构造函数的对象放入vector容器
正文 直接说答案,这个问题无法实现.原因是因为std::vector容器的插入一定会调用类对象的构造函数或者移动构造函数. 说一下为什么会有这个问题,因为不想用指针,我想直接通过类对象本身的RAII机 ...
- 【DevCloud·敏捷智库】如何利用故事点做估算
背景 在某开发团队辅导的第二天,一个团队负责人咨询道:"领导经常管我要开发计划,我如何能快速的评估出预计开发完成时间呢,我们目前用工时估算,我听说过故事点估算,不知道适合吗?" 问 ...
- 测试攻城狮必备技能点!一文带你解读DevOps下的测试技术
[摘要]本文将从DevOps模式下对测试人员的活动的变化,以及常用的测试技术层面进行解读. 项目的软件开发模式主要经历瀑布模型.敏捷开发和DevOps这几个阶段,其中DevOps主要解决开发和运维.运 ...