Shading-JDBC、ShadingSphere、ShardingProxy 使用詳解

来源:https://www.cnblogs.com/wren/archive/2022/10/01/16746592.html
-Advertisement-
Play Games

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 ShardingSphereJDBCProxySidecar(規劃中)這 3 款既能夠獨立部署,又支持混合部署配合使用的產品組成。 它們均提供標準化的基於資料庫作為存儲節點的增量功能,可適用於如 Java 同構、異構語言、雲原生等各種多樣化的應用場景。

關係型資料庫當今依然占有巨大市場份額,是企業核心系統的基石,未來也難於撼動,我們更加註重在原有基礎上提供增量,而非顛覆。


ShardingSphere-JDBC


定位為輕量級 Java 框架,在 JavaJDBC 層提供的額外服務。 它使用客戶端直連資料庫,以 jar 包形式提供服務,無需額外部署和依賴,可理解為增強版的 JDBC 驅動,完全相容 JDBC 和各種 ORM 框架。

  • 適用於任何基於 JDBCORM 框架,如:JPA, Hibernate, Mybatis, Spring JDBC Template 或直接使用 JDBC

  • 支持任何第三方的資料庫連接池,如:DBCP, C3P0, BoneCP, HikariCP 等;

  • 支持任意實現 JDBC 規範的資料庫,目前支持 MySQLPostgreSQLOracleSQLServer 以及任何可使用 JDBC 訪問的資料庫。


在這裡插入圖片描述


ShardingSphere-Proxy


ShardingSphere-ProxyApache ShardingSphere 的第二個產品。 它定位為透明化的資料庫代理端,提供封裝了資料庫二進位協議的服務端版本,用於完成對異構語言的支持。 目前提供 MySQLPostgreSQL(相容 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_0t_order_1、···、t_order_n,每張表只存儲原大表中的一部分數據,當執行一條SQL時會通過 分庫策略分片策略 將數據分散到不同的資料庫、表內。


② 數據節點

數據節點是分庫分表中一個不可再分的最小數據單元(表),它由數據源名稱和數據表組成,例如上圖中 order_db_1.t_order_0order_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 表的分片健。


在這裡插入圖片描述


⑥ 分片演算法

上邊我們提到可以用分片健取模的規則分片,但這隻是比較簡單的一種,在實際開發中我們還希望用 >=<=><BETWEENIN 等條件作為分片規則,自定義分片邏輯,這時就需要用到分片策略與分片演算法。

從執行 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 內置了UUIDSNOWFLAKE 兩種分散式主鍵⽣成器,預設使⽤雪花演算法(snowflake)⽣成64bit的⻓整型數據。不僅如此它還抽離出分散式主鍵⽣成器的介面,⽅便我們實現⾃定義的⾃增主鍵⽣成演算法。


⑨ 廣播表

廣播表:存在於所有的分片數據源中的表,表結構和表中的數據在每個資料庫中均完全一致。一般是為字典表或者配置表 t_config,某個表一旦被配置為廣播表,只要修改某個資料庫的廣播表,所有數據源中廣播表的數據都會跟著同步。


⑩ 綁定表

綁定表:那些分片規則一致的主表和子表。比如:t_order 訂單表和 t_order_item 訂單服務項目表,都是按 order_id 欄位分片,因此兩張表互為綁定表關係。

那綁定表存在的意義是啥呢?

通常在我們的業務中都會使用 t_ordert_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_0t_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集成進來,將它改造成具備分表分庫、讀寫分離的案例。

準備資料庫 sd1sd2,在每個資料庫中創建表,

表結構說明: 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_0goods_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/


  1. 解壓縮後修改conf/server.yaml和以config-首碼開頭的文件,如:conf/config-xxx.yaml文件,進行分片規則、讀寫分離規則配置。

需要修改server.yaml後方可啟動。把authentication這塊原來的註釋符(#)都刪除即可


在這裡插入圖片描述


  1. 如果使用mysql資料庫時,需要把mysql的jar複製到它的lib目錄下。

  2. windows下雙擊start.bat啟動: 預設使用3307埠,可通過命令修改。

    start.bat 埠
    

在這裡插入圖片描述


  1. 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容器

  1. 創建配置

    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
    
    
  2. 創建容器

    # 創建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容器

  1. 創建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
    
    
  2. 創建容器

    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創建用戶並授權

  1. 進入master的資料庫,為master創建複製用戶

    # 進入master容器
    docker exec -it mysql-master bash
    # root用戶連接mysql
    mysql -uroot -p123456
    # 創建用戶
    CREATE USER repl_user IDENTIFIED BY 'repl_passwd';
    
    
  2. 賦予戶複製的許可權

    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


在這裡插入圖片描述


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 一.需求來源 今天碰到了一個需求,需要在頁面里,用水平瀑布流的方式,將一些圖片進行載入,這讓我突然想起我很久以前寫的一篇文章《JS兩種方式實現水平瀑布流佈局》 但是有個問題,這個需求是Vue項目的,那沒辦法,這裡給大家分享下我的開發過程, ...
  • 一、常見的圖片格式 BMP 是無損的、既支持索引色也支持直接色的點陣圖。這種圖片格式幾乎沒有對數據進行壓縮,所以BMP格式的圖片通常是較大的文件。 GIF 是無損的、採用索引色的點陣圖。採用LZW壓縮演算法進行編碼。文件小,是GIF格式的優點,同時,GIF格式還具有支持動畫以及透明的優點。但是GIF格 ...
  • 效果 之前: 之後 Code <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>菜鳥教程(runoob.com)</title> </head> <body> <div class="rect"> <img src="https: ...
  • vue組件中最常見的數據傳遞就是父子組件之間的傳遞,父組件可以通過 props 向下傳數據給子組件,子組件可以通過 $emit 事件攜帶數據給父組件。然而當兩個頁面沒有任關係,該如何通信?這就引出了 EventBus ( 事件匯流排 ) 這個概念 初始化 方法一:新建文件 首先需要初始化一個 Even ...
  • 此博客主要介紹JavaScript中sort()排序的使用方法,也進一步講述了:當排序的值存在null、undefined、0這三個特殊值時,解決排序混亂的方法,並結合自己的理解來闡述解決方法的原理。 JavaScript排序 — sort()方法 ——解決null、undefined、0之間的排序 ...
  • 可調CAP策略是在原來CAP理論基礎上的延伸和發展,它允許我們隨時重組電腦集群的運行模式,根據不同的業務需求,在CP和AP之間動態調節。 ...
  • 適配器設計模式(Adapter Design Pattern)可以將不相容的介面轉換為可相容的介面,讓原本由於介面不相容而不能一起工作的類可以一起工作。 ...
  • 定義 迭代器模式(Iterator pattern):用於順序訪問集合對象里的每一個元素,不用暴露集合是怎樣存儲元素的。 舉例 某個班級有若幹個學生,現在需要統計這些學生的平均分數。假設所有學生的分數是用數組存儲的: int totalScore(int *array, int n) { int s ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...