ShardingSphere
Apache ShardingSphere 是一套開源的分佈式數據庫中間件解決方案組成的生態圈,它由 JDBC、Proxy 和 Sidecar(規劃中)這 3 款相互獨立,卻又能夠混合部署配合使用的產品組成。 它們均提供標準化的數據分片、分佈式事務和數據庫治理功能,可適用於如 Java 同構、異構語言、雲原生等各種多樣化的應用場景。
Apache ShardingSphere 定位爲關係型數據庫中間件,旨在充分合理地在分佈式的場景下利用關係型數據庫的計算和存儲能力,而並非實現一個全新的關係型數據庫。 它通過關注不變,進而抓住事物本質。關係型數據庫當今依然佔有巨大市場,是各個公司核心業務的基石,未來也難於撼動,我們目前階段更加關注在原有基礎上的增量,而非顛覆。
Apache ShardingSphere 5.x 版本開始致力於可插拔架構,項目的功能組件能夠靈活的以可插拔的方式進行擴展。 目前,數據分片、讀寫分離、多數據副本、數據加密、影子庫壓測等功能,以及 MySQL、PostgreSQL、SQLServer、Oracle 等 SQL 與協議的支持,均通過插件的方式織入項目。 開發者能夠像使用積木一樣定製屬於自己的獨特系統。Apache ShardingSphere 目前已提供數十個 SPI 作爲系統的擴展點,仍在不斷增加中。
Sharding-JDBC
定位爲輕量級 Java 框架,在 Java 的 JDBC 層提供的額外服務。 它使用客戶端直連數據庫,以 jar 包形式提供服務,無需額外部署和依賴,可理解爲增強版的 JDBC 驅動,完全兼容 JDBC 和各種 ORM 框架。
- 適用於任何基於 JDBC 的 ORM 框架,如:JPA, Hibernate, Mybatis, Spring JDBC Template 或直接使用 JDBC。
- 支持任何第三方的數據庫連接池,如:DBCP, C3P0, BoneCP, Druid, HikariCP 等。
- 支持任意實現JDBC規範的數據庫。目前支持 MySQL,Oracle,SQLServer,PostgreSQL 以及任何遵循 SQL92 標準的數據庫。
Sharding-JDBC 實現水平分表
約定規則:如果添加課程 id 是偶數把數據添加 course_0,如果奇數添加到 course_1
- pom依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.22</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>4.0.0-RC1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
- 按照水平分表的方式,創建數據庫和數據庫表
CREATE TABLE `course_0` (
`cid` bigint NOT NULL,
`cname` varchar(50) COLLATE utf8mb4_general_ci NOT NULL,
`user_id` bigint NOT NULL,
`status` varchar(10) NOT NULL,
PRIMARY KEY (`cid`)
) ENGINE=InnoDB;
CREATE TABLE `course_1` (
`cid` bigint NOT NULL,
`cname` varchar(50) COLLATE utf8mb4_general_ci NOT NULL,
`user_id` bigint NOT NULL,
`status` varchar(10) NOT NULL,
PRIMARY KEY (`cid`)
) ENGINE=InnoDB;
- 配置application.properties
# shardingjdbc分片策略
# 配置數據源,給數據源起名稱
spring.shardingsphere.datasource.names=m1
# 一個實體類對應兩張表,覆蓋
spring.main.allow-bean-definition-overriding=true
#配置第一個數據源具體內容,包含連接池,驅動,地址,用戶名和密碼
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://192.168.2.128:3306/sharding_jdbc?serverTimezone=GMT%2B8&characterEncoding=UTF-8
spring.shardingsphere.datasource.m1.username=root
spring.shardingsphere.datasource.m1.password=root
#指定course表分佈情況,配置表在哪個數據庫裏面,表名稱都是什麼 m1.course_0 m1.course_1
spring.shardingsphere.sharding.tables.course.actual-data-nodes=m1.course_${0..1}
# 指定course表裏面主鍵cid 生成策略 SNOWFLAKE(雪花算法)
spring.shardingsphere.sharding.tables.course.key-generator.column=cid
spring.shardingsphere.sharding.tables.course.key-generator.type=SNOWFLAKE
# 指定表分片策略 約定cid值偶數添加到course_1表,如果cid是奇數添加到course_2表
spring.shardingsphere.sharding.tables.course.table-strategy.inline.sharding-column=cid
spring.shardingsphere.sharding.tables.course.table-strategy.inline.algorithm-expression=course_${ cid %2 }
# 打開sql輸出日誌
spring.shardingsphere.props.sql.show=true
- 編寫代碼
實體類
@Data
@Accessors(chain = true)
public class Course {
private Long cid;
private String cname;
private Long userId;
private String status;
}
mapper類
public interface CourseMapper extends BaseMapper<Course> {
}
啓動類上加 @MapperScan("com.cgp.shardingjdbc.mapper")
- 編寫測試類
@Resource
private CourseMapper courseMapper;
@Test
void addCourse() {
for (int i = 1; i <= 10; i++) {
Course course = new Course();
course.setCname("Java").setUserId(100L + i).setStatus("Normal" + i);
courseMapper.insert(course);
}
}
@Test
void findCourse() {
Course course = courseMapper.selectOne(new QueryWrapper<Course>().eq("cid", 476417513358360577L));
System.out.println(course);
}
//刪改略...
Sharding-JDBC 實現水平分庫
指定表分片策略 約定cid值偶數添加到course_0表,如果cid是奇數添加到course_1表
指定數據庫分片策略 約定user_id是偶數添加m0,是奇數添加m1
根據以上代碼修改 properties 文件
# shardingjdbc分片策略
# 配置數據源,給數據源起名稱,
# 水平分庫,配置兩個數據源
spring.shardingsphere.datasource.names=m0,m1
# 一個實體類對應兩張表,覆蓋
spring.main.allow-bean-definition-overriding=true
#配置第一個數據源具體內容,包含連接池,驅動,地址,用戶名和密碼
spring.shardingsphere.datasource.m0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.m0.url=jdbc:mysql://192.168.2.128:3306/sharding_jdbc_1?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.m0.username=root
spring.shardingsphere.datasource.m0.password=root
#配置第二個數據源具體內容,包含連接池,驅動,地址,用戶名和密碼
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://192.168.2.128:3306/sharding_jdbc_2?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.m1.username=root
spring.shardingsphere.datasource.m1.password=root
#指定數據庫分佈情況,數據庫裏面表分佈情況
# m1 m2 course_0 course_1
spring.shardingsphere.sharding.tables.course.actual-data-nodes=m$->{0..1}.course_$->{0..1}
# 指定course表裏面主鍵cid 生成策略 SNOWFLAKE
spring.shardingsphere.sharding.tables.course.key-generator.column=cid
spring.shardingsphere.sharding.tables.course.key-generator.type=SNOWFLAKE
# 指定表分片策略 約定cid值偶數添加到course_0表,如果cid是奇數添加到course_1表
spring.shardingsphere.sharding.tables.course.table-strategy.inline.sharding-column=cid
spring.shardingsphere.sharding.tables.course.table-strategy.inline.algorithm-expression=course_$->{cid % 2}
# 指定數據庫分片策略 約定user_id是偶數添加m0,是奇數添加m1
#spring.shardingsphere.sharding.default-database-strategy.inline.sharding-column=user_id
#spring.shardingsphere.sharding.default-database-strategy.inline.algorithm-expression=m$->{user_id % 2}
spring.shardingsphere.sharding.tables.course.database-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.tables.course.database-strategy.inline.algorithm-expression=m$->{user_id % 2}
# 打開sql輸出日誌
spring.shardingsphere.props.sql.show=true
建表語句同上
編寫測試類
@Test
void addCourseDb() {
for (int i = 1; i <= 10; i++) {
Course course = new Course();
course.setCname("JavaDB").setUserId(100L).setStatus("Normal");
courseMapper.insert(course);
}
for (int i = 1; i <= 10; i++) {
Course course = new Course();
course.setCname("JavaDB").setUserId(101L).setStatus("Normal");
courseMapper.insert(course);
}
}
//刪改查略...
運行後發現2個庫中共四張表都有5條數據
Sharding-JDBC 實現垂直分庫
修改 properties 文件,增加垂直分庫配置
# shardingjdbc分片策略
# 配置數據源,給數據源起名稱,
# 垂直分庫,新增m2數據源
spring.shardingsphere.datasource.names=m0,m1,m2
# 一個實體類對應兩張表,覆蓋
spring.main.allow-bean-definition-overriding=true
#========================垂直分庫配置開始===================================
#配置第三個數據源具體內容,垂直分庫
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://192.168.2.128:3306/sharding_jdbc_user?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.m2.username=root
spring.shardingsphere.datasource.m2.password=root
# 配置user_db數據庫裏面t_user 專庫專表
spring.shardingsphere.sharding.tables.t_user.actual-data-nodes=m2.t_user
# 指定t_user表裏面主鍵user_id 生成策略 SNOWFLAKE
spring.shardingsphere.sharding.tables.t_user.key-generator.column=user_id
spring.shardingsphere.sharding.tables.t_user.key-generator.type=SNOWFLAKE
# 指定垂直分庫 表分片策略
spring.shardingsphere.sharding.tables.t_user.table-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.tables.t_user.table-strategy.inline.algorithm-expression=t_user
#========================垂直分庫配置結束===================================
#配置第一個數據源具體內容,包含連接池,驅動,地址,用戶名和密碼
spring.shardingsphere.datasource.m0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.m0.url=jdbc:mysql://192.168.2.128:3306/sharding_jdbc_1?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.m0.username=root
spring.shardingsphere.datasource.m0.password=root
#配置第二個數據源具體內容,包含連接池,驅動,地址,用戶名和密碼
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://192.168.2.128:3306/sharding_jdbc_2?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.m1.username=root
spring.shardingsphere.datasource.m1.password=root
#指定數據庫分佈情況,數據庫裏面表分佈情況
# m1 m2 course_0 course_1
spring.shardingsphere.sharding.tables.course.actual-data-nodes=m$->{0..1}.course_$->{0..1}
# 指定course表裏面主鍵cid 生成策略 SNOWFLAKE
spring.shardingsphere.sharding.tables.course.key-generator.column=cid
spring.shardingsphere.sharding.tables.course.key-generator.type=SNOWFLAKE
# 指定表分片策略 約定cid值偶數添加到course_0表,如果cid是奇數添加到course_1表
spring.shardingsphere.sharding.tables.course.table-strategy.inline.sharding-column=cid
spring.shardingsphere.sharding.tables.course.table-strategy.inline.algorithm-expression=course_$->{cid % 2}
# 指定數據庫分片策略 約定user_id是偶數添加m0,是奇數添加m1
#spring.shardingsphere.sharding.default-database-strategy.inline.sharding-column=user_id
#spring.shardingsphere.sharding.default-database-strategy.inline.algorithm-expression=m$->{user_id % 2}
spring.shardingsphere.sharding.tables.course.database-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.tables.course.database-strategy.inline.algorithm-expression=m$->{user_id % 2}
# 打開sql輸出日誌
spring.shardingsphere.props.sql.show=true
建表語句
CREATE TABLE `t_user` (
`user_id` bigint NOT NULL,
`username` varchar(50) COLLATE utf8mb4_general_ci NOT NULL,
`age` int NOT NULL,
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB;
實體類和Mapper類
@Data
@TableName("t_user")
@Accessors(chain = true)
public class User {
private Long userId;
private String username;
private Integer age;
}
public interface UserMapper extends BaseMapper<User> {
}
測試類
@Resource
private UserMapper userMapper;
@Test
void addUser() {
User user = new User();
user.setUsername("Manaphy").setAge(18);
userMapper.insert(user);
}
//刪改查略...
Sharding-JDBC 操作公共表
作用
(1) 存儲固定數據的表,表數據很少發生變化,查詢時候經常進行關聯
(2) 在每個數據庫中創建出相同結構公共表
修改 properties 文件,增加公共表配置
# shardingjdbc分片策略
# 配置數據源,給數據源起名稱,
# 垂直分庫,新增m2數據源
spring.shardingsphere.datasource.names=m0,m1,m2
# 一個實體類對應兩張表,覆蓋
spring.main.allow-bean-definition-overriding=true
#========================配置公共表開始===================================
#配置公共表
spring.shardingsphere.sharding.broadcast-tables=t_dict
# 指定公共表裏面主鍵dict_id 生成策略 SNOWFLAKE
spring.shardingsphere.sharding.tables.t_dict.key-generator.column=dict_id
spring.shardingsphere.sharding.tables.t_dict.key-generator.type=SNOWFLAKE
#========================配置公共表結束===================================
#========================垂直分庫配置開始===================================
#配置第三個數據源具體內容,垂直分庫
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://192.168.2.128:3306/sharding_jdbc_user?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.m2.username=root
spring.shardingsphere.datasource.m2.password=root
# 配置user_db數據庫裏面 t_user 專庫專表
spring.shardingsphere.sharding.tables.t_user.actual-data-nodes=m2.t_user
# 指定t_user表裏面主鍵user_id 生成策略 SNOWFLAKE
spring.shardingsphere.sharding.tables.t_user.key-generator.column=user_id
spring.shardingsphere.sharding.tables.t_user.key-generator.type=SNOWFLAKE
# 指定垂直分庫 表分片策略
spring.shardingsphere.sharding.tables.t_user.table-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.tables.t_user.table-strategy.inline.algorithm-expression=t_user
#========================垂直分庫配置結束===================================
#配置第一個數據源具體內容,包含連接池,驅動,地址,用戶名和密碼
spring.shardingsphere.datasource.m0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.m0.url=jdbc:mysql://192.168.2.128:3306/sharding_jdbc_1?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.m0.username=root
spring.shardingsphere.datasource.m0.password=root
#配置第二個數據源具體內容,包含連接池,驅動,地址,用戶名和密碼
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://192.168.2.128:3306/sharding_jdbc_2?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.m1.username=root
spring.shardingsphere.datasource.m1.password=root
#指定數據庫分佈情況,數據庫裏面表分佈情況
# m1 m2 course_0 course_1
spring.shardingsphere.sharding.tables.course.actual-data-nodes=m$->{0..1}.course_$->{0..1}
# 指定course表裏面主鍵cid 生成策略 SNOWFLAKE
spring.shardingsphere.sharding.tables.course.key-generator.column=cid
spring.shardingsphere.sharding.tables.course.key-generator.type=SNOWFLAKE
# 指定表分片策略 約定cid值偶數添加到course_0表,如果cid是奇數添加到course_1表
spring.shardingsphere.sharding.tables.course.table-strategy.inline.sharding-column=cid
spring.shardingsphere.sharding.tables.course.table-strategy.inline.algorithm-expression=course_$->{cid % 2}
# 指定數據庫分片策略 約定user_id是偶數添加m0,是奇數添加m1
#spring.shardingsphere.sharding.default-database-strategy.inline.sharding-column=user_id
#spring.shardingsphere.sharding.default-database-strategy.inline.algorithm-expression=m$->{user_id % 2}
spring.shardingsphere.sharding.tables.course.database-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.tables.course.database-strategy.inline.algorithm-expression=m$->{user_id % 2}
# 打開sql輸出日誌
spring.shardingsphere.props.sql.show=true
在sharding_jdbc_user
sharding_jdbc_1
和 sharding_jdbc_2
表中新增t_dict
表
CREATE TABLE `t_dict` (
`dict_id` bigint NOT NULL,
`dict_name` varchar(100) NOT NULL,
`dict_value` varchar(100) NOT NULL,
PRIMARY KEY (`dict_id`)
) ENGINE=InnoDB;
實體類和Mapper類
@Data
@TableName("t_dict")
@Accessors(chain = true)
public class Dict {
private Long dictId;
private String dictName;
private String dictValue;
}
public interface DictMapper extends BaseMapper<Dict> {
}
測試類
@Resource
private DictMapper dictMapper;
@Test
void addDict() {
Dict dict = new Dict();
dict.setDictName("測試").setDictValue("啓用");
dictMapper.insert(dict);
}
//刪改查略...
運行後發現三個庫中的t_dict
表中都有一條一樣的數據
Sharding-JDBC 實現讀寫分離
基於 docker 搭建 mysql 主從複製 參考https://blog.csdn.net/weixin_45631876/article/details/104048362
配置application.properties
# shardingjdbc分片策略
# 配置數據源,給數據源起名稱
spring.shardingsphere.datasource.names=master,slave
# 一個實體類對應兩張表,覆蓋
spring.main.allow-bean-definition-overriding=true
#配置主數據源具體內容,包含連接池,驅動,地址,用戶名和密碼
spring.shardingsphere.datasource.master.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.master.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.master.url=jdbc:mysql://192.168.2.128:3307/sharding_jdbc?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.master.username=root
spring.shardingsphere.datasource.master.password=123456
#配置從數據源具體內容,包含連接池,驅動,地址,用戶名和密碼
spring.shardingsphere.datasource.slave.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.slave.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.slave.url=jdbc:mysql://192.168.2.128:3308/sharding_jdbc?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.slave.username=root
spring.shardingsphere.datasource.slave.password=123456
# t_user分表策略,固定分配至ds0的 sharding_jdbc真實表
spring.shardingsphere.sharding.tables.t_user.actual-data-nodes=ds0.course
# 主庫從庫邏輯數據源定義 ds0爲 sharding_jdbc
spring.shardingsphere.sharding.master-slave-rules.ds0.master-data-source-name=master
spring.shardingsphere.sharding.master-slave-rules.ds0.slave-data-source-names=slave
# 指定course表裏面主鍵cid 生成策略 SNOWFLAKE(雪花算法)
spring.shardingsphere.sharding.tables.course.key-generator.column=cid
spring.shardingsphere.sharding.tables.course.key-generator.type=SNOWFLAKE
# 打開sql輸出日誌
spring.shardingsphere.props.sql.show=true
在主數據庫新建 course 表
建表語句、實體類和Mapper類同水平分表
編寫測試類
@Test
void addCourseMaster() {
Course course = new Course();
course.setCname("Java").setUserId(100L).setStatus("Normal");
courseMapper.insert(course);
}
@Test
void findCourseSlave() {
Course course = courseMapper.selectOne(new QueryWrapper<Course>().eq("cid", 476494916214587393L));
System.out.println(course);
}
@Test
void modifyCourse() {
QueryWrapper<Course> wrapper = new QueryWrapper<>();
wrapper.eq("cid", 476494916214587393L);
Course course = courseMapper.selectOne(wrapper);
course.setCname("Sharding");
courseMapper.update(course, wrapper);
}
@Test
void deleteCourse() {
QueryWrapper<Course> wrapper = new QueryWrapper<>();
wrapper.eq("cid", 476494916214587393L);
courseMapper.delete(wrapper);
}
Sharding-Proxy
定位爲透明化的數據庫代理端,提供封裝了數據庫二進制協議的服務端版本,用於完成對異構語言的支持。 目前提供 MySQL 和 PostgreSQL 版本,它可以使用任何兼容 MySQL/PostgreSQL 協議的訪問客戶端(如:MySQL Command Client, MySQL Workbench, Navicat 等)操作數據,對 DBA 更加友好。
- 嚮應用程序完全透明,可直接當做 MySQL/PostgreSQL 使用。
- 適用於任何兼容 MySQL/PostgreSQL 協議的的客戶端。
下載及安裝
- 從官網下載相應的軟件
- 把下載之後壓縮文件,解壓,啓動 bin 目錄啓動文件就可以了
- 查看 lib 文件夾 ,如果擴展名不是
版本號.jar
的要重命名補上版本號.jar
Sharding-Proxy 配置(分表)
- 進入 conf 目錄,修改文件 server.yaml,打開兩段內容註釋
authentication:
users:
root:
password: root
sharding:
password: sharding
authorizedSchemas: sharding_db
props:
max.connections.size.per.query: 1
acceptor.size: 16 # The default value is available processors count * 2.
executor.size: 16 # Infinite by default.
proxy.frontend.flush.threshold: 128 # The default value is 128.
# LOCAL: Proxy will run with LOCAL transaction.
# XA: Proxy will run with XA transaction.
# BASE: Proxy will run with B.A.S.E transaction.
proxy.transaction.type: LOCAL
proxy.opentracing.enabled: false
query.with.cipher.column: true
sql.show: false
-
進入 conf 目錄,打開 config-sharding.yaml
可以看到這樣一句話
# If you want to connect to MySQL, you should manually copy MySQL driver to lib directory.
- 複製 mysql 驅動 jar 包到 lib 目錄
- 配置分庫分表規則
schemaName: sharding_db dataSources: ds_0: url: jdbc:mysql://192.168.2.128:3306/sharding_proxy?serverTimezone=UTC&useSSL=false username: root password: root connectionTimeoutMilliseconds: 30000 idleTimeoutMilliseconds: 60000 maxLifetimeMilliseconds: 1800000 maxPoolSize: 50 shardingRule: tables: t_order: actualDataNodes: ds_0.t_order_${0..1} tableStrategy: inline: shardingColumn: order_id algorithmExpression: t_order_${order_id % 2} keyGenerator: type: SNOWFLAKE column: order_id bindingTables: - t_order defaultDatabaseStrategy: inline: shardingColumn: user_id algorithmExpression: ds_0 defaultTableStrategy: none:
- 在數據庫中新建
sharding_proxy
數據庫 - 啓動 Sharding-Proxy 服務
bin/start.bat
(windows環境)或者bin/start.sh
(Linux環境)
[INFO ] 22:23:16.578 [nioEventLoopGroup-2-1] i.n.handler.logging.LoggingHandler - [id: 0x7e19000c, L:/0:0:0:0:0:0:0:0:3307] READ: [id: 0x096f3d30, L:/0:0:0:0:0:0:0:1:3307 - R:/0:0:0:0:0:0:0:1:52814] [INFO ] 22:23:16.580 [nioEventLoopGroup-2-1] i.n.handler.logging.LoggingHandler - [id: 0x7e19000c, L:/0:0:0:0:0:0:0:0:3307] READ COMPLETE
最後兩行打印以上信息代表啓動成功
- 由於Navicat等工具不支持Sharding_Proxy,所以只能使用命令行窗口連接
mysql -uroot -P3307 -uroot -proot
mysql> show databases;
+-------------+
| Database |
+-------------+
| sharding_db |
+-------------+
1 row in set (0.01 sec)
mysql> use sharding_db;
Database changed
mysql> create table if not exists ds_0.t_order(order_id BIGINT NOT NULL,user_id INT NOT NULL,status VARCHAR(50),PRIMARY KEY (order_id));#創建t_order表
Query OK, 0 rows affected (0.28 sec)
mysql> show tables;
+--------------------------+
| Tables_in_sharding_proxy |
+--------------------------+
| t_order |
+--------------------------+
1 row in set (0.03 sec)
mysql> insert into t_order(order_id,user_id,status)values(11,1,'init');#向表中插入數據
Query OK, 1 row affected (0.10 sec)
mysql> select * from t_order;
+----------+---------+--------+
| order_id | user_id | status |
+----------+---------+--------+
| 11 | 1 | init |
+----------+---------+--------+
1 row in set (0.06 sec)
- 回到 192.168.2.128:3306 實際數據庫中,看到已經創建好了表和添加數據
Sharding-Proxy 配置(分庫)
- 打開 config-sharding.yaml 文件,修改內容
schemaName: sharding_db
dataSources:
ds_0:
url: jdbc:mysql://192.168.2.128:3306/sharding_jdbc_1?serverTimezone=UTC&useSSL=false
username: root
password: root
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
ds_1:
url: jdbc:mysql://192.168.2.128:3306/sharding_jdbc_2?serverTimezone=UTC&useSSL=false
username: root
password: root
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
shardingRule:
tables:
t_order:
actualDataNodes: ds_${0..1}.t_order_${0..1}
tableStrategy:
inline:
shardingColumn: order_id
algorithmExpression: t_order_${order_id % 2}
keyGenerator:
type: SNOWFLAKE
column: order_id
keyGenerator:
type: SNOWFLAKE
column: order_item_id
bindingTables:
- t_order,t_order_item
defaultDatabaseStrategy:
inline:
shardingColumn: user_id
algorithmExpression: ds_${user_id % 2}
defaultTableStrategy:
none:
- 啓動 Sharding-Proxy 服務
- 使用命令行窗口連接
mysql -P3307 -uroot -proot
mysql> show databases;
+-------------+
| Database |
+-------------+
| sharding_db |
+-------------+
1 row in set (0.01 sec)
mysql> use sharding_db;
Database changed
mysql> show tables;
Empty set (0.10 sec)
mysql> create table if not exists ds_0.t_order(order_id BIGINT NOT NULL,user_id INT NOT NULL,status VARCHAR(50),PRIMARY KEY (order_id));#創建t_order表
Query OK, 0 rows affected (0.32 sec)
mysql> show tables;
+---------------------------+
| Tables_in_sharding_jdbc_1 |
+---------------------------+
| t_order |
+---------------------------+
1 row in set (0.03 sec)
mysql> insert into t_order(order_id,user_id,status)values(11,1,'init');#向表中插入數據
Query OK, 1 row affected (0.11 sec)
- 回到 192.168.2.128:3306 實際數據庫中,看到已經創建好了表和添加數據
Sharding-Proxy 配置(讀寫分離)
- 簡化操作=> 直接在 192.168.2.128:3306 中創建 sharding_master sharding_slave_0 sharing_slave_1 三個數據庫 (一主雙從)
- 打開 config-master_slave.yaml 文件,修改內容
schemaName: master_slave_db
dataSources:
master_ds:
url: jdbc:mysql://192.168.174.129:3307/sharding_master?serverTimezone=UTC&useSSL=false
username: root
password: 123456
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
slave_ds_0:
url: jdbc:mysql://192.168.174.129:3307/sharding_slave_0?serverTimezone=UTC&useSSL=false
username: root
password: 123456
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
slave_ds_1:
url: jdbc:mysql://192.168.174.129:3307/sharding_slave_1?serverTimezone=UTC&useSSL=false
username: root
password: 123456
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
masterSlaveRule:
name: ms_ds
masterDataSourceName: master_ds
slaveDataSourceNames:
- slave_ds_0
- slave_ds_1
- 啓動 Sharding-Proxy 服務
- 使用命令行窗口連接
mysql -P3307 -uroot -proot
mysql> show databases;
+-----------------+
| Database |
+-----------------+
| master_slave_db |
| sharding_db |
+-----------------+
2 rows in set (0.38 sec)
mysql> use master_slave_db;
Database changed
mysql> create table if not exists sharding_master.t_order(order_id BIGINT NOT NULL,user_id INT NOT NULL,status VARCHAR(50),PRIMARY KEY (order_id));
Query OK, 0 rows affected (0.08 sec)
mysql> use master_slave_db;
Database changed
mysql> create table if not exists sharding_slave_0.t_order(order_id BIGINT NOT NULL,user_id INT NOT NULL,status VARCHAR(50),PRIMARY KEY (order_id));
Query OK, 0 rows affected (0.03 sec)
mysql> create table if not exists sharding_slave_1.t_order(order_id BIGINT NOT NULL,user_id INT NOT NULL,status VARCHAR(50),PRIMARY KEY (order_id));
Query OK, 0 rows affected (0.02 sec)
#由於簡化操作並未搭建主從複製,故模擬主從複製
mysql> show tables;
+---------------------------+
| Tables_in_sharding_master |
+---------------------------+
| t_order |
+---------------------------+
1 row in set (0.01 sec)
mysql> insert into t_order(order_id,user_id,status)values(11,1,'init');
Query OK, 1 row affected (0.04 sec)
mysql> select * from t_order;
Empty set (0.05 sec)
#由於會向主庫插入數據,而查詢在從庫中,所以查不到數據
mysql> insert into sharding_slave_0.t_order(order_id,user_id,status)values(12,1,'init');
Query OK, 1 row affected (0.03 sec)
mysql> insert into sharding_slave_1.t_order(order_id,user_id,status)values(13,1,'init');
Query OK, 1 row affected (0.01 sec)
#模擬主從複製向從庫插入數據 (故意插入id不同的數據)
mysql> select * from t_order;
+----------+---------+--------+
| order_id | user_id | status |
+----------+---------+--------+
| 12 | 1 | init |
+----------+---------+--------+
1 row in set (0.01 sec)
mysql> select * from t_order;
+----------+---------+--------+
| order_id | user_id | status |
+----------+---------+--------+
| 13 | 1 | init |
+----------+---------+--------+
1 row in set (0.01 sec)
mysql> select * from t_order;
+----------+---------+--------+
| order_id | user_id | status |
+----------+---------+--------+
| 12 | 1 | init |
+----------+---------+--------+
1 row in set (0.00 sec)
mysql> select * from t_order;
+----------+---------+--------+
| order_id | user_id | status |
+----------+---------+--------+
| 13 | 1 | init |
+----------+---------+--------+
1 row in set (0.00 sec)
#多次查詢會發現隨機從從表中查詢