ShadingSphere ShardingSphere是一款起源於噹噹網內部的應用框架,2015年在噹噹網內部誕生,2016年由主要開發人員張亮帶入京東數科,在國內經歷了噹噹網、電信翼支付、京東數科等多家大型互聯網企業的考驗,在2017年開源。 並逐漸由原本只關註於關係型資料庫增強工具的Shar ...
ShadingSphere
ShardingSphere是一款起源於噹噹網內部的應用框架,2015年在噹噹網內部誕生,2016年由主要開發人員張亮帶入京東數科,在國內經歷了噹噹網、電信翼支付、京東數科等多家大型互聯網企業的考驗,在2017年開源。
並逐漸由原本只關註於關係型資料庫增強工具的ShardingJDBC升級成為一整套以數據分片為基礎的數據生態圈,更名為ShardingSphere;在2020年4月,成為Apache軟體基金會頂級項目
Apache ShardingSphere
產品定位為 Database Plus
,旨在構建多模資料庫上層的標準和生態。 它關註如何充分合理地利用資料庫的計算和存儲能力,而並非實現一個全新的資料庫。ShardingSphere
站在資料庫的上層視角,關註他們之間的協作多於資料庫自身。
連接、增量 和 可插拔 是 Apache ShardingSphere` 的核心概念。
-
連接
:通過對資料庫協議、SQL
方言以及資料庫存儲的靈活適配,快速的連接應用與多模式的異構資料庫; -
增量
:獲取資料庫的訪問流量,並提供流量重定向(數據分片、讀寫分離、影子庫)、流量變形(數據加密、數據脫敏)、流量鑒權(安全、審計、許可權)、流量治理(熔斷、限流)以及流量分析(服務質量分析、可觀察性)等透明化增量功能; -
可插拔
:項目採用微內核 + 三層可插拔模型,使內核、功能組件以及生態對接完全能夠靈活的方式進行插拔式擴展,開發者能夠像使用積木一樣定製屬於自己的獨特系統。
Apache ShardingSphere
由 JDBC
、Proxy
和 Sidecar
(規劃中)這 3 款既能夠獨立部署,又支持混合部署配合使用的產品組成。 它們均提供標準化的基於資料庫作為存儲節點的增量功能,可適用於如 Java
同構、異構語言、雲原生等各種多樣化的應用場景。
關係型資料庫當今依然占有巨大市場份額,是企業核心系統的基石,未來也難於撼動,我們更加註重在原有基礎上提供增量,而非顛覆。
ShardingSphere-JDBC
定位為輕量級 Java
框架,在 Java
的 JDBC
層提供的額外服務。 它使用客戶端直連資料庫,以 jar
包形式提供服務,無需額外部署和依賴,可理解為增強版的 JDBC
驅動,完全相容 JDBC
和各種 ORM
框架。
-
適用於任何基於
JDBC
的ORM
框架,如:JPA
,Hibernate
,Mybatis
,Spring JDBC Template
或直接使用JDBC
; -
支持任何第三方的資料庫連接池,如:
DBCP
,C3P0
,BoneCP
,HikariCP
等; -
支持任意實現
JDBC
規範的資料庫,目前支持MySQL
,PostgreSQL
,Oracle
,SQLServer
以及任何可使用JDBC
訪問的資料庫。
ShardingSphere-Proxy
ShardingSphere-Proxy
是 Apache ShardingSphere
的第二個產品。 它定位為透明化的資料庫代理端,提供封裝了資料庫二進位協議的服務端版本,用於完成對異構語言的支持。 目前提供 MySQL
和 PostgreSQL
(相容 openGauss
等基於 PostgreSQL
的資料庫)版本,它可以使用任何相容 MySQL/PostgreSQL
協議的訪問客戶端(如:MySQL Command Client
, MySQL Workbench
, Navicat
等)操作數據,對 DBA
更加友好。
-
嚮應用程式完全透明,可直接當做
MySQL/PostgreSQL
使用。 -
適用於任何相容
MySQL/PostgreSQL
協議的的客戶端。
項目說明 | ShardingSphere-JDBC | ShardingSphere-Proxy |
---|---|---|
資料庫 | 任意 | MySQL/PostgreSQL |
連接消耗數 | 高 | 低 |
異構語言 | 僅Java | 任意 |
性能 | 損耗低 | 損耗略高 |
無中心化 | 是 | 否 |
靜態入口 | 無 | 有 |
ShardingSphere-Proxy
的優勢在於對異構語言的支持,以及為 DBA
提供可操作入口。
ShadingJDBC使用
① 分片
一般我們在提到分庫分表的時候,大多是以水平切分模式(水平分庫、分表)為基礎來說的,數據分片將原本一張數據量較大的表 t_order
拆分生成數個表結構完全一致的小數據量表 t_order_0
、t_order_1
、···、t_order_n
,每張表只存儲原大表中的一部分數據,當執行一條SQL
時會通過 分庫策略
、分片策略
將數據分散到不同的資料庫、表內。
② 數據節點
數據節點是分庫分表中一個不可再分的最小數據單元(表),它由數據源名稱和數據表組成,例如上圖中 order_db_1.t_order_0
、order_db_2.t_order_1
就表示一個數據節點。
③ 邏輯表
邏輯表是指一組具有相同邏輯和數據結構表的總稱。比如我們將訂單表t_order
拆分成 t_order_0
··· t_order_9
等 10張表。此時我們會發現分庫分表以後資料庫中已不在有 t_order
這張表,取而代之的是 t_order_n
,但我們在代碼中寫 SQL
依然按 t_order
來寫。此時 t_order
就是這些拆分表的邏輯表
。
④ 真實表
真實表也就是上邊提到的 t_order_n
資料庫中真實存在的物理表。
⑤ 分片鍵
用於分片的資料庫欄位。我們將 t_order
表分片以後,當執行一條SQL時,通過對欄位 order_id
取模的方式來決定,這條數據該在哪個資料庫中的哪個表中執行,此時 order_id
欄位就是 t_order
表的分片健。
⑥ 分片演算法
上邊我們提到可以用分片健取模的規則分片,但這隻是比較簡單的一種,在實際開發中我們還希望用 >=
、<=
、>
、<
、BETWEEN
和 IN
等條件作為分片規則,自定義分片邏輯,這時就需要用到分片策略與分片演算法。
從執行 SQL 的角度來看,分庫分表可以看作是一種路由機制,把 SQL 語句路由到我們期望的資料庫或數據表中並獲取數據,分片演算法可以理解成一種路由規則。
咱們先捋一下它們之間的關係,分片策略只是抽象出的概念,它是由分片演算法和分片健組合而成,分片演算法做具體的數據分片邏輯。
分庫、分表的分片策略配置是相對獨立的,可以各自使用不同的策略與演算法,每種策略中可以是多個分片演算法的組合,每個分片演算法可以對多個分片健做邏輯判斷。
分片演算法和分片策略的關係
sharding-jdbc
提供了4種分片演算法:
1:精確分片演算法
精確分片演算法(PreciseShardingAlgorithm)用於單個欄位作為分片鍵,SQL中有 = 與 IN 等條件的分片,需要在標準分片策略(StandardShardingStrategy )下使用。
2:範圍分片演算法
範圍分片演算法(RangeShardingAlgorithm)用於單個欄位作為分片鍵,SQL中有 BETWEEN AND、>、<、>=、<= 等條件的分片,需要在標準分片策略(StandardShardingStrategy )下使用。
3:複合分片演算法
複合分片演算法(ComplexKeysShardingAlgorithm)用於多個欄位作為分片鍵的分片操作,同時獲取到多個分片健的值,根據多個欄位處理業務邏輯。需要在複合分片策略(ComplexShardingStrategy )下使用。
4:Hint分片演算法
Hint分片演算法(HintShardingAlgorithm)稍有不同,上邊的演算法中我們都是解析SQL 語句提取分片鍵,並設置分片策略進行分片。但有些時候我們並沒有使用任何的分片鍵和分片策略,可還想將 SQL 路由到目標資料庫和表,就需要通過手動干預指定SQL的目標資料庫和表信息,這也叫強制路由。
註意:sharding-jdbc
並沒有直接提供分片演算法的實現,需要開發者根據業務自行實現。
⑦ 分片策略
上邊講分片演算法的時候已經說過,分片策略是一種抽象的概念,實際分片操作的是由分片演算法和分片健來完成的。
1:標準分片策略
標準分片策略適用於單分片鍵,此策略支持 PreciseShardingAlgorithm 和 RangeShardingAlgorithm 兩個分片演算法。
其中 PreciseShardingAlgorithm 是必選的,用於處理 = 和 IN 的分片。RangeShardingAlgorithm 是可選的,用於處理BETWEEN AND, >, <,>=,<= 條件分片,如果不配置RangeShardingAlgorithm,SQL中的條件等將按照全庫路由處理。
2:複合分片策略
複合分片策略,同樣支持對 SQL語句中的 =,>, <, >=, <=,IN和 BETWEEN AND 的分片操作。不同的是它支持多分片鍵,具體分配片細節完全由應用開發者實現。
3:行表達式分片策略 inline
行表達式分片策略,支持對 SQL語句中的 = 和 IN 的分片操作,但只支持單分片鍵。這種策略通常用於簡單的分片,不需要自定義分片演算法,可以直接在配置文件中接著寫規則。
t_order_$->{t_order_id % 4} 代表 t_order 對其欄位 t_order_id取模,拆分成4張表,而表名分別是t_order_0 到 t_order_3。
4:Hint分片策略
Hint分片策略,對應上邊的Hint分片演算法,通過指定分片健而非從 SQL中提取分片健的方式進行分片的策略。
⑧ 分散式主鍵
數據分⽚後,不同數據節點⽣成全局唯⼀主鍵是⾮常棘⼿的問題,同⼀個邏輯表(t_order
)內的不同真實表(t_order_n
)之間的⾃增鍵由於⽆法互相感知而產⽣重覆主鍵。
儘管可通過設置⾃增主鍵 初始值
和 步⻓
的⽅式避免ID碰撞,但這樣會使維護成本加大,乏完整性和可擴展性。如果後去需要增加分片表的數量,要逐一修改分片表的步長,運維成本非常高,所以不建議這種方式。
實現分散式主鍵⽣成器的方式很多,可以參考我之前寫的9種分散式ID生成方式。
為了讓上手更加簡單,ApacheShardingSphere 內置了UUID
、SNOWFLAKE
兩種分散式主鍵⽣成器,預設使⽤雪花演算法(snowflake
)⽣成64bit的⻓整型數據。不僅如此它還抽離出分散式主鍵⽣成器的介面,⽅便我們實現⾃定義的⾃增主鍵⽣成演算法。
⑨ 廣播表
廣播表:存在於所有的分片數據源中的表,表結構和表中的數據在每個資料庫中均完全一致。一般是為字典表或者配置表 t_config
,某個表一旦被配置為廣播表,只要修改某個資料庫的廣播表,所有數據源中廣播表的數據都會跟著同步。
⑩ 綁定表
綁定表:那些分片規則一致的主表和子表。比如:t_order
訂單表和 t_order_item
訂單服務項目表,都是按 order_id
欄位分片,因此兩張表互為綁定表關係。
那綁定表存在的意義是啥呢?
通常在我們的業務中都會使用 t_order
和 t_order_item
等表進行多表聯合查詢,但由於分庫分表以後這些表被拆分成N多個子表。如果不配置綁定表關係,會出現笛卡爾積關聯查詢,將產生如下四條SQL
。
SELECT * FROM t_order_0 o JOIN t_order_item_0 i ON o.order_id=i.order_id
SELECT * FROM t_order_0 o JOIN t_order_item_1 i ON o.order_id=i.order_id
SELECT * FROM t_order_1 o JOIN t_order_item_0 i ON o.order_id=i.order_id
SELECT * FROM t_order_1 o JOIN t_order_item_1 i ON o.order_id=i.order_id
笛卡爾積查詢
而配置綁定表關係後再進行關聯查詢時,只要對應表分片規則一致產生的數據就會落到同一個庫中,那麼只需 t_order_0
和 t_order_item_0
表關聯即可。
SELECT * FROM t_order_0 o JOIN t_order_item_0 i ON o.order_id=i.order_id
SELECT * FROM t_order_1 o JOIN t_order_item_1 i ON o.order_id=i.order_id
綁定表關係
註意:在關聯查詢時 t_order 它作為整個聯合查詢的主表。所有相關的路由計算都只使用主表的策略,t_order_item 表的分片相關的計算也會使用 t_order 的條件,所以要保證綁定表之間的分片鍵要完全相同。
案例準備
我們基於MyBatisPlus+ShadingJDBC
實現資料庫分片、讀寫分離功能,準備了工程shading-jdbc
,該工程是一個SpringBoot+MyBatisPlus
實現了MySQL
增加和查詢的案例,我們要將ShadingJDBC
集成進來,將它改造成具備分表分庫、讀寫分離的案例。
準備資料庫 sd1
、sd2
,在每個資料庫中創建表,
表結構說明: goods 用於資料庫分片。goods_0, goods_1用於表分片
創建腳本如下:
-- 資料庫sd1
CREATE database `sd1` DEFAULT CHARACTER SET utf8 ;
CREATE TABLE sd1.`goods` (
`id` bigint(20) NOT NULL,
`goods_name` varchar(100) DEFAULT NULL,
`type` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
create table sd1.`goods_0` as select * from sd1.`goods` where 1=2;
create table sd1.`goods_1` as select * from sd1.`goods` where 1=2;
-- 資料庫sd2
CREATE database `sd2` DEFAULT CHARACTER SET utf8 ;
create table sd2.`goods` as select * from sd1.`goods` where 1=2;
create table sd2.`goods_0` as select * from sd1.`goods` where 1=2;
create table sd2.`goods_1` as select * from sd1.`goods` where 1=2;
案例說明:
上面創建的表,雖然是goods_0
和goods_1
,但案例中Pojo
用到了邏輯表,如下:
@Data
@TableName(value = "goods") //這裡用的是邏輯表
public class Goods {
@TableId(value = "id",type = IdType.INPUT)
private Long id;
@TableField(value = "goods_name")
private String goodsName;
@TableField(value = "type")
private Long type;
}
處理上面之外,案例提供了三個方法:
package com.execise.controller;
import com.execise.domain.Goods;
import com.execise.service.GoodsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@Controller
@RequestMapping("/goods")
public class GoodsController {
@Autowired
private GoodsService goodsService;
@GetMapping
public List<Goods> list(){
return goodsService.list();
}
//@GetMapping("/{id}")
public Goods getOne(@PathVariable int id){
return goodsService.getById(id);
}
@GetMapping("/add/{goodsName}/{type}")
public String add(@PathVariable String goodsName, @PathVariable int type){
Goods goods = new Goods();
goods.setGoodsName(goodsName);
goods.setType(type);
goodsService.save(goods);
return "添加成功!";
}
}
分庫案例
我們使用ShadingJDBC
實現數據分片,將一部分數據添加到sd1
一部分數據添加到sd2
中,一部分數據添加到goods_0
中,一部分數據添加到goods_1
中。
我們先實現將一部分數據添加到sd1
中,一部分數據添加到sd2
中,這種操作就是分庫操作,分庫操作可以減少每個資料庫中存儲的數據,當數據少了,查詢的時候,單台資料庫查找的數據量就減少了,從而加速了每台資料庫查找速度。
分庫策略
分庫策略如上圖:
#求餘演算法
添加數據的時候,我們由於只有2台資料庫,我們可以根據某個欄位 column%2 求餘,來確定數據存入哪個資料庫,這種演算法是很常規的演算法。
#案例求餘
在案例中,我們可以把type作為求餘的column,用type%2的餘數作為資料庫的下標,這種演算法是非常簡單的。
分庫配置
修改application.yml
,配置分庫策略,配置如下:
spring:
shardingsphere:
# 數據源配置
datasource:
# 名稱隨意,但必須唯一
names: ds1,ds2
# 這裡的名稱需要在datasource.names中存在
ds1:
# jdbc需要配置連接池
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: root
url: jdbc:mysql://localhost:3306/sd1?serverTimezone=Asia/Shanghai&characterEncoding=utf8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useSSL=false
ds2:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: root
url: jdbc:mysql://localhost:3306/sd2?serverTimezone=Asia/Shanghai&characterEncoding=utf8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useSSL=false
# 分片配置
sharding:
# 需要分片的表配置
tables:
# 需要分片的表名,邏輯名,隨意
goods:
# 數據節點配置ds${}組成上面names中的數據源名稱, 1..2代表 1到2之間的數值
# 資料庫中表的語法:schema.表名 = database.表名
actualDataNodes: ds${1..2}.goods
# 分庫策略
databaseStrategy:
# 使用inline分片演算法
inline:
# 分片鍵 為表中某個欄位
shardingColumn: type
# 具體分片時的表達式
algorithmExpression: ds${type % 2 + 1}
props:
# 是否列印sql
sql.show: true
logging:
pattern:
console: '%d{HH:mm:ss} %msg %n\'
level:
root: info
com:
execise: debug
分表案例
基於上面的案例,我們再實現分表操作,一部分數據存入goods_0
,一部分數據存入goods_1
。
分表策略
如上圖:
#分表策略
我們需要將數據存入到goods_0或者goods_1中,也可以採用求餘法,採用id作為求餘的列, id%2的餘數作為資料庫表的下標。
分表配置
修改application.yml
,配置分表策略,配置如下:
spring:
main:
allow-bean-definition-overriding: true
shardingsphere:
datasource:
names: ds1,ds2
ds1:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: root
url: jdbc:mysql://localhost:3306/sd1?serverTimezone=Asia/Shanghai&characterEncoding=utf8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useSSL=false
ds2:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: root
url: jdbc:mysql://localhost:3306/sd2?serverTimezone=Asia/Shanghai&characterEncoding=utf8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useSSL=false
sharding:
tables:
goods:
actualDataNodes: ds${1..2}.goods_${0..1}
databaseStrategy:
inline:
shardingColumn: type
algorithmExpression: ds${type % 2 + 1}
# 表分片策略
tableStrategy:
inline:
shardingColumn: id
algorithmExpression: goods_${id % 2}
keyGenerator:
type: SNOWFLAKE
column: id
props:
sql.show: true
logging:
pattern:
console: '%d{HH:mm:ss} %msg %n\'
level:
root: info
com:
execise: debug
配置參數說明
上面我們完成了分表分庫的配置,但很多配置並未說明是什麼意思,參數詳情如下:
dataSources: # 省略數據源配置,請參考使用手冊
rules:
- !SHARDING
tables: # 數據分片規則配置
<logic-table-name> (+): # 邏輯表名稱
actualDataNodes (?): # 由數據源名 + 表名組成(參考Inline語法規則)
databaseStrategy (?): # 分庫策略,預設表示使用預設分庫策略,以下的分片策略只能選其一
standard: # 用於單分片鍵的標準分片場景
shardingColumn: # 分片列名稱
shardingAlgorithmName: # 分片演算法名稱
complex: # 用於多分片鍵的複合分片場景
shardingColumns: #分片列名稱,多個列以逗號分隔
shardingAlgorithmName: # 分片演算法名稱
hint: # Hint 分片策略
shardingAlgorithmName: # 分片演算法名稱
none: # 不分片
tableStrategy: # 分表策略,同分庫策略
keyGenerateStrategy: # 分散式序列策略
column: # 自增列名稱,預設表示不使用自增主鍵生成器
keyGeneratorName: # 分散式序列演算法名稱
autoTables: # 自動分片表規則配置
t_order_auto: # 邏輯表名稱
actualDataSources (?): # 數據源名稱
shardingStrategy: # 切分策略
standard: # 用於單分片鍵的標準分片場景
shardingColumn: # 分片列名稱
shardingAlgorithmName: # 自動分片演算法名稱
bindingTables (+): # 綁定表規則列表
- <logic_table_name_1, logic_table_name_2, ...>
- <logic_table_name_1, logic_table_name_2, ...>
broadcastTables (+): # 廣播表規則列表
- <table-name>
- <table-name>
defaultDatabaseStrategy: # 預設資料庫分片策略
defaultTableStrategy: # 預設表分片策略
defaultKeyGenerateStrategy: # 預設的分散式序列策略
defaultShardingColumn: # 預設分片列名稱
# 分片演算法配置
shardingAlgorithms:
<sharding-algorithm-name> (+): # 分片演算法名稱
type: # 分片演算法類型
props: # 分片演算法屬性配置
# ...
# 分散式序列演算法配置
keyGenerators:
<key-generate-algorithm-name> (+): # 分散式序列演算法名稱
type: # 分散式序列演算法類型
props: # 分散式序列演算法屬性配置
# ...
props:
# ...
ShardingProxy 使用
下載與安裝
訪問 https://shardingsphere.apache.org/document/current/en/downloads/ 下載
也可獲取歷史版本的下載
https://archive.apache.org/dist/shardingsphere/
- 解壓縮後修改conf/server.yaml和以config-首碼開頭的文件,如:conf/config-xxx.yaml文件,進行分片規則、讀寫分離規則配置。
需要修改server.yaml後方可啟動。把authentication這塊原來的註釋符(#)都刪除即可
-
如果使用mysql資料庫時,需要把mysql的jar複製到它的lib目錄下。
-
windows下雙擊start.bat啟動: 預設使用3307埠,可通過命令修改。
start.bat 埠
- Linux操作系統請運行
bin/start.sh
,Windows操作系統請運行bin/start.bat
啟動Sharding-Proxy。如需配置啟動埠、配置文件位置後進行啟動
分庫案例
修改配置文件config-sharding.yaml如下
schemaName: sharding_db
dataSources:
sp_1:
url: jdbc:mysql://127.0.0.1:3306/sd1?serverTimezone=UTC&useSSL=false
username: root
password: root
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 10
sp_2:
url: jdbc:mysql://127.0.0.1:3306/sd2?serverTimezone=UTC&useSSL=false
username: root
password: root
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 10
shardingRule:
tables:
student:
actualDataNodes: sp_${1..2}.student_${0..1}
tableStrategy:
inline:
shardingColumn: id
algorithmExpression: student_${id % 2}
databaseStrategy:
inline:
shardingColumn: grade
algorithmExpression: sp_${grade % 2 + 1}
keyGenerator:
type: SNOWFLAKE
column: id
bindingTables:
- student
分表案例
修改配置文件config-sharding.yaml如下
schemaName: sharding_db
dataSources:
master:
username: root
password: 123456
url: jdbc:mysql://192.168.136.160:3307/masterdb?serverTimezone=Asia/Shanghai&characterEncoding=utf8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useSSL=false
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 10
slave1:
username: root
password: 123456
url: jdbc:mysql://192.168.136.160:3308/masterdb?serverTimezone=Asia/Shanghai&characterEncoding=utf8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useSSL=false
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 10
slave2:
username: root
password: 123456
url: jdbc:mysql://192.168.136.160:3309/masterdb?serverTimezone=Asia/Shanghai&characterEncoding=utf8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useSSL=false
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 10
shardingRule:
tables:
goods:
actualDataNodes: ds_ms1.goods_${0..1}
tableStrategy:
inline:
shardingColumn: id
algorithmExpression: goods_${id%2}
keyGenerator:
type: SNOWFLAKE
column: id
bindingTables:
- goods
masterSlaveRules:
ds_ms1:
loadBalanceAlgorithmType: round_robin
masterDataSourceName: master
slaveDataSourceNames:
- slave1
- slave2
MySQL主從複製
① 創建master容器
-
創建配置
mkdir -p /data/mysql/master/conf # master資料庫配置 sudo tee /data/mysql/master/conf/mysqld.cnf <<-'EOF' [mysqld] server-id = 1 # 節點ID,確保唯一 # log config log-bin = mysql-bin #開啟mysql的binlog日誌功能 sync_binlog = 1 #控制資料庫的binlog刷到磁碟上去 , 0 不控制,性能最好,1每次事物提交都會刷到日誌文件中,性能最差,最安全 binlog_format = mixed #binlog日誌格式,mysql預設採用statement,建議使用mixed expire_logs_days = 7 #binlog過期清理時間 max_binlog_size = 100m #binlog每個日誌文件大小 binlog_cache_size = 4m #binlog緩存大小 max_binlog_cache_size= 512m #最大binlog緩存大 binlog-ignore-db=mysql #不生成日誌文件的資料庫,多個忽略資料庫可以用逗號拼接,或者 複製這句話,寫多行 auto-increment-offset = 1 # 自增值的偏移量 auto-increment-increment = 1 # 自增值的自增量 slave-skip-errors = all #跳過從庫錯誤 EOF
-
創建容器
# 創建master資料庫 docker run --name mysql-master -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123456 \ -v /data/mysql/master/conf/mysqld.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf \ -v /data/mysql/master/data:/var/lib/mysql \ -d mysql:5.7
② 創建2個slave容器
-
創建slave的配置
mkdir -p /data/mysql/slave1/conf # slave資料庫配置 sudo tee /data/mysql/slave1/conf/mysqld.cnf <<-'EOF' [mysqld] server-id = 101 log-bin=mysql-bin relay-log = mysql-relay-bin replicate-wild-ignore-table=mysql.% replicate-wild-ignore-table=test.% replicate-wild-ignore-table=information_schema.% EOF mkdir -p /data/mysql/slave2/conf # slave資料庫配置 sudo tee /data/mysql/slave2/conf/mysqld.cnf <<-'EOF' [mysqld] server-id = 102 log-bin=mysql-bin relay-log = mysql-relay-bin replicate-wild-ignore-table=mysql.% replicate-wild-ignore-table=test.% replicate-wild-ignore-table=information_schema.% EOF
-
創建容器
docker run --name mysql-slave1 -p 3308:3306 -e MYSQL_ROOT_PASSWORD=123456 \ -v /data/mysql/slave1/conf/mysqld.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf \ -v /data/mysql/slave1/data:/var/lib/mysql \ -d mysql:5.7 docker run --name mysql-slave2 -p 3309:3306 -e MYSQL_ROOT_PASSWORD=123456 \ -v /data/mysql/slave2/conf/mysqld.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf \ -v /data/mysql/slave2/data:/var/lib/mysql \ -d mysql:5.7
③ master創建用戶並授權
-
進入master的資料庫,為master創建複製用戶
# 進入master容器 docker exec -it mysql-master bash # root用戶連接mysql mysql -uroot -p123456 # 創建用戶 CREATE USER repl_user IDENTIFIED BY 'repl_passwd';
-
賦予戶複製的許可權
grant replication slave on *.* to 'repl_user'@'%' identified by 'repl_passwd'; FLUSH PRIVILEGES;
④ 查看master的狀態
# 記錄 File與Position的值
show master status;
⑤ 從庫配置
# 進入從庫容器
docker exec -it mysql-slave bash
# 連接從庫
mysql -uroot -p123456
CHANGE MASTER TO
MASTER_HOST = '192.168.136.160',
MASTER_USER = 'repl_user',
MASTER_PASSWORD = 'repl_passwd',
MASTER_PORT = 3307,
MASTER_LOG_FILE='mysql-bin.000003',
MASTER_LOG_POS=858,
MASTER_RETRY_COUNT = 60,
MASTER_HEARTBEAT_PERIOD = 10000;
start slave;
# MASTER_LOG_FILE='mysql-bin.000005',#與主庫File 保持一致
# MASTER_LOG_POS=120 , #與主庫Position 保持一致
show slave status\G