萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> MySQL 教學

MyCat 實現 MySQL 分庫分表完整實戰:從安裝配置到分片規則驗證

MyCat 是基於阿里開源 Cobar 演進的開源數據庫中間件,支援讀寫分離、分庫分表、多租戶、全局序列號等企業級特性,被視為「MySQL 集群」的輕量級替代方案。本文基於 Docker 環境,從零構建 MyCat 1.5 分片集群,詳細記錄核心概念配置、啟動驗證與分表測試全過程。

一、 環境準備

組件版本/規格
OSUbuntu 16.04
JDK1.8+
Docker1.11.2+
MySQL5.7.13 (兩個容器實例)
MyCat1.5-RELEASE
客戶端Navicat for MySQL / mysql-client

1. 啟動兩個 MySQL 容器模擬分片節點

# 節點 1 (dn1) - 映射宿主 3306
docker run --name mysql1 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=bboyjing -d daocloud.io/library/mysql:5.7.13

# 節點 2 (dn2) - 映射宿主 3316
docker run --name mysql2 -p 3316:3306 -e MYSQL_ROOT_PASSWORD=bboyjing -d daocloud.io/library/mysql:5.7.13

# 驗證連通性
mysql -h127.0.0.1 -P3306 -uroot -pbboyjing
mysql -h127.0.0.1 -P3316 -uroot -pbboyjing

2. 在兩個 MySQL 實例建立分片數據庫

# 連入各實例執行
CREATE DATABASE order_db CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

二、 MyCat 核心概念與配置映射

MyCat 配置文件位於 conf/ 目錄,三大核心文件:

  • server.xml:系統參數、用戶權限、全局屬性。
  • schema.xml:邏輯庫、邏輯表、分片節點、分片規則、節點主機定義。
  • rule.xml:分片算法函數定義 (如取模、範圍、一致性哈希、枚舉等)。

核心概念對照表:

MyCat 概念對應物理含義配置位置
用戶連接 MyCat 的客戶端賬號server.xml <user>
邏輯庫對應 MySQL Databaseschema.xml <schema>
邏輯表分片後的邏輯視圖schema.xml <table>
分片節點具體 MySQL 實例上的物理庫schema.xml <dataNode>
分片規則路由算法 (取模、範圍、哈希...)rule.xml <tableRule> + <function>
節點主機MySQL 實例連接池、讀寫分離、心跳schema.xml <dataHost>
全局序列號分片環境下全局唯一 ID 生成sequence_*.conf / ZK/數據庫方式

三、 關鍵配置文件詳解

1. server.xml - 用戶與系統配置

<user name="root">
  <property name="password">bboyjing</property>
  <property name="schemas">OrderDB</property>
  <!-- property name="readOnly">true</property -->
</user>

2. schema.xml - 核心邏輯架構

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="https://io.mycat/">

  <!-- 邏輯庫 -->
  <schema name="OrderDB" checkSQLschema="false" sqlMaxLimit="100">
    <!-- 邏輯表:分片到 dn1,dn2,規則 mod-long -->
    <table name="t_order" dataNode="dn1,dn2" rule="mod-long" primaryKey="id" autoIncrement="true"/>
  </schema>

  <!-- 分片節點:映射到具體 MySQL 實例上的庫 -->
  <dataNode name="dn1" dataHost="dockerhost1" database="order_db"/>
  <dataNode name="dn2" dataHost="dockerhost2" database="order_db"/>

  <!-- 節點主機:定義連接池、心跳、讀寫分離 -->
  <dataHost name="dockerhost1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1">
    <heartbeat>select user()</heartbeat>
    <writeHost host="hostM1" url="127.0.0.1:3306" user="root" password="bboyjing"/>
  </dataHost>

  <dataHost name="dockerhost2" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1">
    <heartbeat>select user()</heartbeat>
    <writeHost host="hostM2" url="127.0.0.1:3316" user="root" password="bboyjing"/>
  </dataHost>

</mycat:schema>

關鍵屬性解析:

  • balance="0":讀寫分離模式。0=不開啟(全走 writeHost),1=所有 readHost+writeHost 負載均衡,2=僅 readHost 負載均衡,3=所有 host 負載均衡 (慎用)。
  • writeType="0":寫負載模式。0=寫第一個 writeHost,故障切換;1=輪詢寫入 (危險,易主主衝突)。
  • switchType="1":心跳檢測類型。1=不自動切換 (推薦),2=基於 MySQL 主從狀態自動切換,3=管理員決定。

3. rule.xml - 分片算法定義

<tableRule name="mod-long">
  <rule>
    <columns>id</columns>          <!-- 分片鍵 -->
    <algorithm>mod-long</algorithm> <!-- 算法引用 -->
  </rule>
</tableRule>

<function name="mod-long" class="org.opencloudb.route.function.PartitionByMod">
  <property name="count">2</property>  <!-- 分片數量,與 dataNode 數量一致 -->
</function>

算法含義: id % 2,結果 0 路由至 dn1,1 路由至 dn2。MyCat 內建豐富算法:PartitionByMod(取模)、PartitionByRange(範圍)、PartitionByDate(日期)、PartitionByPattern(正則)、PartitionByCRC32PreSlot(一致性哈希) 等。

四、 啟動驗證與分表測試

1. 啟動 MyCat

cd /opt/mycat
bin/mycat start
# 查看日誌確認啟動成功
tail -f logs/mycat.log
# 關鍵日誌: "connected successfully MySQLConnection" 表示後端 MySQL 連接池建立正常

MyCat 預設端口:8066 (數據端口)、9066 (管理端口)。

2. 客戶端連接 MyCat

mysql -h127.0.0.1 -P8066 -uroot -pbboyjing

3. 驗證邏輯庫與建表

mysql> SHOW DATABASES;
+----------+
| DATABASE |
+----------+
| OrderDB  |  <-- 來自 server.xml 用戶 schemas 屬性
+----------+

mysql> USE OrderDB;

mysql> CREATE TABLE `t_order` (
    -> `id` INT(11) NOT NULL,
    -> `status` TINYINT(4) NOT NULL,
    -> `price` INT(11) NOT NULL,
    -> `create_time` BIGINT(20) NOT NULL,
    -> PRIMARY KEY (`id`)
    -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Query OK, 0 rows affected (0.05 sec)
MyCat 邏輯庫列表
建表成功

4. 驗證分片效果

登入兩個後端 MySQL 實例,檢查表結構自動建立:

# MySQL1 (3306)
mysql> USE order_db; SHOW TABLES; DESC t_order;
# MySQL2 (3316)
mysql> USE order_db; SHOW TABLES; DESC t_order;

兩側均自動建立相同結構的 t_order 表,證明 MyCat 成功攔截 DDL 並路由至所有分片節點。

5. 測試數據路由 (取模分片)

# 通過 MyCat 插入測試數據
INSERT INTO t_order (id, status, price, create_time) VALUES (1, 1, 100, 1234567890);
INSERT INTO t_order (id, status, price, create_time) VALUES (2, 2, 200, 1234567891);
INSERT INTO t_order (id, status, price, create_time) VALUES (3, 1, 150, 1234567892);
INSERT INTO t_order (id, status, price, create_time) VALUES (4, 3, 300, 1234567893);

# 驗證路由: id%2=1 -> dn1 (mysql1), id%2=0 -> dn2 (mysql2)
# MySQL1 應有 id=1,3
# MySQL2 應有 id=2,4

五、 進階主題與避坑指南

  1. 全局序列號: 分片表主鍵不能依賴 MySQL 自增。配置 sequence_conf.properties 使用 LOCAL、DATABASE (需建 sequence 表)、ZK、SNOWFLAKE (雪花算法) 等方式生成全局唯一 ID。
  2. 跨分片 JOIN: 儘量避免。必須 JOIN 時,使用 ER 關係表 (childTable) 將關聯表路由至同一分片,或應用層組裝。
  3. 分布式事務: MyCat 支援 XA 事務 (兩階段提交),但性能損耗大。業務層面優先設計冪等+補償 (TCC/Saga)。
  4. 讀寫分離陷阱: balance=1/2/3 可能導致主從延遲下讀到舊數據。核心寫入路徑建議 balance=0,讀請求顯式路由至從庫或使用中間件代理層 (如 ProxySQL) 實現更精細控制。
  5. 監控與運維: 管理端口 9066 提供 SHOW @@datasource、SHOW @@cache、RELOAD @@config 等運行時指令,納入監控體系。

六、 總結

MyCat 作為一款成熟的數據庫中間件,以 **「對應用透明、SQL 改造最小、運維成本可控」** 解決了 MySQL 單庫性能與存儲瓶頸。本文實戰驗證了核心配置鏈路:

用戶 → 邏輯庫 → 邏輯表(分片規則) → 分片節點 → 節點主機(物理 MySQL)

落地關鍵在於:

  1. 根據業務特性選擇合適分片鍵與算法 (取模/範圍/哈希)。
  2. 嚴格規劃 dataNode 映射與 dataHost 連接池參數。
  3. 解決全局唯一 ID 生成 (Snowflake 推薦)。
  4. 建立完善的讀寫分離策略與故障切換預案。
  5. **壓測驗證** 分片均勻度、跨分片查詢性能、故障恢復時間。

MyCat 並非銀彈,但對於中小型團隊從單庫向分布式架構演進,是極具性價比的落地選擇。

copyright © 萬盛學電腦網 all rights reserved