分庫分表中間件
MyCat
官方地址:https://mycat.org.cn MyCat 是一個要部署在服務器上的軟件,類似於 Proxy,使用 MyCat 需要有一定的運維能力。
ShardingSphere
官方地址:http://shardingsphere.apache.org/index_zh.html
簡介
Apache ShardingSphere 是一套開源的分布式數據庫解決方案組成的生態圈,由 JDBC、Proxy 和 Sidecar(規划中)這 3 款既能夠獨立部署,又支持混合部署配合使用的產品組成,提供標准化的數據水平擴展、分布式事務和分布式治理等功能,ShardingSphere 定位為關系型數據庫中間件,旨在充分合理地在分布式的場景下利用關系型數據庫的計算和存儲能力
Sharding-JDBC
Sharding-JDBC 定位為輕量級 Java 框架,以 jar 包形式提供服務,無需額外部署和依賴,核心功能,數據分片,讀寫分離。
結構
Sharding-Proxy
Sharding-Proxy 類似於 MyCat,它定位為透明化的數據庫代理端,提供封裝了數據庫二進制協議的服務端版本,用於完成對異構語言的支持。目前僅支持 MySQL、PstgreSQL。
結構
Sharding-Sidecar
Sharding-Sidecar 目前正在規划中,定位為 Kubernetes 的雲原生數據庫代理,以 Sidecar 的形式代理所有對數據庫的訪問。
核心概念
邏輯表
水平拆分的數據庫(表)的相同邏輯和數據結構表的總稱。拆分之后的表,t_order_0、t_order_1,邏輯表名為 t_order。
真實表
在分片的數據庫中真實存在的物理表。t_order_0 就是一張具體的表。
數據節點
數據分片的最小單元。由數據源名稱和數據表組成。
綁定表
指分片規則一致的主表和子表。
廣播表
指所有的分片數據源中都存在的表,表結構和表中的數據在每個數據庫中均完全一致。適用於數據量不大且需要與海量數據的表進行關聯查詢的場景,例如:字典表。
分片鍵
用於分片的數據庫字段,是將數據庫(表)水平拆分的關鍵字段。
分片算法
通過分片算法將數據分片,支持通過 =、>=、<=、>、<、BETWEEN 和 IN 分片。
分片策略
真正可用於分片操作的是分片鍵 + 分片算法,也就是分片策略。
分片鍵與分片算法原理圖
建立 JDBC 環境
創建表
t_order:
CREATE TABLE `t_order` (
`tid` bigint(20) NOT NULL,
`tname` varchar(255) DEFAULT NULL,
`goods_id` bigint(20) DEFAULT NULL,
`tstatus` varchar(255) DEFAULT NULL,
PRIMARY KEY (`tid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
建立 SpringBoot 工程
修改 pom.xml:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.22</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
<version>5.0.0-beta</version>
</dependency>
</dependencies>
創建實體類:
/**
* 訂單
*
* @author BNTang
* @date 2021/10/11
*/
@Data
@TableName("t_order")
public class Order {
private Long tid;
private String tname;
private Long goodsId;
private String tstatus;
}
創建 Mapper:
/**
* @author BNTang
* @version 1.0
* @project ShardingSpherePro
* @description
* @since Created in 2021/10/11 011 20:47
**/
public interface OrderMapper extends BaseMapper<Order> {
}
修改啟動類,添加注解:
@MapperScan("top.it6666.shardingspherepro.mapper")
在修改 application.properties
之前首先來看看 shardingsphere 官網所給出的配置內容,這里有一個小坑如下:
我這里就先照着它所給出的配置來進行,先演示一下這個坑然后在進行解決這個坑點,然后我拷貝了它的配置到了自己的工程當中內容如下:
spring.shardingsphere.datasource.names=shardingspheredb1
spring.shardingsphere.datasource.shardingspheredb1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.shardingspheredb1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.shardingspheredb1.jdbc-url=jdbc:mysql://localhost:3310/shardingspheredb1?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.shardingspheredb1.username=root
spring.shardingsphere.datasource.shardingspheredb1.password=root
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
需要注意的是如上配置的 shardingspheredb1
它代表着一個 databases 也就是一個數據源,那么下面的配置也要跟着改:
編寫測試類:
@SpringBootTest
@RunWith(SpringRunner.class)
class ShardingSphereProApplicationTests {
@Resource
private OrderMapper orderMapper;
@Test
void addOrder() {
for (int i = 0; i < 10; i++) {
Order order = new Order();
order.setTid((long) i);
order.setTname("訂單" + i);
order.setGoodsId(Long.valueOf("" + (1000 + i)));
order.setTstatus("1");
System.out.println(order);
this.orderMapper.insert(order);
}
}
}
運行測試類插入數據,結果發現報錯了:
說找不到 database URL,然后我們在將進行改正,只需要將 jdbc-url
改為 url
即可修改 application.properties 配置文件:
spring.shardingsphere.datasource.names=shardingspheredb1
spring.shardingsphere.datasource.shardingspheredb1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.shardingspheredb1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.shardingspheredb1.url=jdbc:mysql://localhost:3306/shardingspheredb1?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.shardingspheredb1.username=root
spring.shardingsphere.datasource.shardingspheredb1.password=root
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
數據分片存儲
建立分片真實表,t_order_0,t_order_1 SQL如下:
CREATE TABLE `t_order_0` (
`tid` bigint(20) NOT NULL,
`tname` varchar(255) DEFAULT NULL,
`goods_id` bigint(20) DEFAULT NULL,
`tstatus` varchar(255) DEFAULT NULL,
PRIMARY KEY (`tid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `t_order_1` (
`tid` bigint(20) NOT NULL,
`tname` varchar(255) DEFAULT NULL,
`goods_id` bigint(20) DEFAULT NULL,
`tstatus` varchar(255) DEFAULT NULL,
PRIMARY KEY (`tid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
分表配置
修改 application.properties 添加如下相關的配置內容:
# 配置t_order真實表規則
spring.shardingsphere.rules.sharding.tables.t_order.actual-data-nodes=shardingspheredb1.t_order_$->{0..1}
# 配置分表策略 主鍵+分片算法
spring.shardingsphere.rules.sharding.tables.t_order.table-strategy.standard.sharding-column=tid
spring.shardingsphere.rules.sharding.tables.t_order.table-strategy.standard.sharding-algorithm-name=table-inline
# 配置 分片算法
spring.shardingsphere.rules.sharding.sharding-algorithms.table-inline.type=INLINE
spring.shardingsphere.rules.sharding.sharding-algorithms.table-inline.props.algorithm-expression=t_order_$->{tid % 2}
# 主鍵盤生成策略
spring.shardingsphere.rules.sharding.tables.t_order.key-generate-strategy.column=tid
spring.shardingsphere.rules.sharding.tables.t_order.key-generate-strategy.key-generator-name=snowflake
spring.shardingsphere.rules.sharding.key-generators.snowflake.type=SNOWFLAKE
spring.shardingsphere.rules.sharding.key-generators.snowflake.props.worker-id=1
# 打印執行sql
spring.shardingsphere.props.sql-show=true
- 這里就來一一解釋一下如上配置當中比較關鍵的幾個內容
spring.shardingsphere.rules.sharding.tables.t_order.actual-data-nodes
該內容就是配置t_order
真實表規則, 我如上配置的就是 0,1 spring.shardingsphere.rules.sharding.sharding-algorithms.table-inline.props.algorithm-expression
配置的內容就是真實表的尋找算法spring.shardingsphere.rules.sharding.tables.t_order.table-strategy.standard.sharding-column
指定了分表以 tid 進行分表操作
如上的內容配置完畢之后再次運行測試類,在運行測試類之前其實可以將 id 的設置給去除因為如上配置了 主鍵盤生成策略
,然后查看分片表的數據如下圖所示:
分庫分表
添加第二個數據源,修改 application.properties:
spring.shardingsphere.datasource.names=shardingspheredb1,shardingspheredb2
# 配置第 2 個數據源
spring.shardingsphere.datasource.shardingspheredb2.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.shardingspheredb2.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.shardingspheredb2.url=jdbc:mysql://localhost:3306/shardingspheredb2?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.shardingspheredb2.username=root
spring.shardingsphere.datasource.shardingspheredb2.password=root
修改表規則,修改配置文件,都是同一個配置文件內容修改,不再強調了:
# 水平拆分 水平分片
# 配置 t_order 表規則 數據源.真實表
# 配置t_order真實表規則
spring.shardingsphere.rules.sharding.tables.t_order.actual-data-nodes=shardingspheredb$->{1..2}.t_order_$->{0..1}
配置配置分庫,主鍵 + 分片算法策略:
# 配置分庫策略 主鍵+分片算法
spring.shardingsphere.rules.sharding.tables.t_order.database-strategy.standard.sharding-column=goods_id
spring.shardingsphere.rules.sharding.tables.t_order.database-strategy.standard.sharding-algorithm-name=database-inline
spring.shardingsphere.rules.sharding.sharding-algorithms.database-inline.type=INLINE
spring.shardingsphere.rules.sharding.sharding-algorithms.database-inline.props.algorithm-expression=shardingspheredb$->{goods_id % 2 + 1}
最終 application.properties
配置文件內容如下:
spring.shardingsphere.datasource.names=shardingspheredb1,shardingspheredb2
spring.shardingsphere.datasource.shardingspheredb1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.shardingspheredb1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.shardingspheredb1.url=jdbc:mysql://www.yangbuyi.top:3310/shardingspheredb1?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.shardingspheredb1.username=root
spring.shardingsphere.datasource.shardingspheredb1.password=yangbuyiya
# 配置第 2 個數據源
spring.shardingsphere.datasource.shardingspheredb2.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.shardingspheredb2.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.shardingspheredb2.url=jdbc:mysql://www.yangbuyi.top:3310/shardingspheredb2?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.shardingspheredb2.username=root
spring.shardingsphere.datasource.shardingspheredb2.password=yangbuyiya
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
# 水平拆分 水平分片
# 配置 t_order 表規則 數據源.真實表
# 配置t_order真實表規則
spring.shardingsphere.rules.sharding.tables.t_order.actual-data-nodes=shardingspheredb$->{1..2}.t_order_$->{0..1}
# 配置分表策略 主鍵+分片算法
spring.shardingsphere.rules.sharding.tables.t_order.table-strategy.standard.sharding-column=tid
spring.shardingsphere.rules.sharding.tables.t_order.table-strategy.standard.sharding-algorithm-name=table-inline
# 配置 分片算法
spring.shardingsphere.rules.sharding.sharding-algorithms.table-inline.type=INLINE
spring.shardingsphere.rules.sharding.sharding-algorithms.table-inline.props.algorithm-expression=t_order_$->{tid % 2}
# 主鍵盤生成策略
spring.shardingsphere.rules.sharding.tables.t_order.key-generate-strategy.column=tid
spring.shardingsphere.rules.sharding.tables.t_order.key-generate-strategy.key-generator-name=snowflake
spring.shardingsphere.rules.sharding.key-generators.snowflake.type=SNOWFLAKE
spring.shardingsphere.rules.sharding.key-generators.snowflake.props.worker-id=1
# 打印執行sql
spring.shardingsphere.props.sql-show=true
# 配置分庫策略 主鍵+分片算法
spring.shardingsphere.rules.sharding.tables.t_order.database-strategy.standard.sharding-column=goods_id
spring.shardingsphere.rules.sharding.tables.t_order.database-strategy.standard.sharding-algorithm-name=database-inline
spring.shardingsphere.rules.sharding.sharding-algorithms.database-inline.type=INLINE
spring.shardingsphere.rules.sharding.sharding-algorithms.database-inline.props.algorithm-expression=shardingspheredb$->{goods_id % 2 + 1}
運行測試類,運行 SQL 如下圖所示:
最終數據庫數據存儲結果:
最終如上 application.yml 當中的配置含義為分表是按照 tid
進行分表,分庫是按照 goods_id
進行的分庫,到此該章節的內容到此結束。