首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MyCat 離散分片實戰:應用層指定分區的直接路由分片

     編輯:MySQL 綜合教學

前言

MyCat 作為開源數據庫中間件,提供了豐富的分片算法。其中「應用指定分區」屬於離散分片的一種,允許應用程式在運行時根據業務邏輯顯式決定數據路由到哪個分片。本文詳細記錄該分片規則的配置、建表、數據驗證與路由日誌分析全流程。

一、分片原理

  • 由應用傳遞分片字段值(必須為數字子串),MyCat 直接截取指定位置的數字作為分區號。
  • 適合業務明確知道數據應落在哪個分片的場景,如按租戶 ID、業務區域代碼直接路由。
  • 屬於「直連路由」,無需計算哈希或範圍判斷,效率極高。

二、配置文件修改

1. function.xml 定義分片函數

<function name="sharding-by-substring-040302"
        class="org.opencloudb.route.function.PartitionDirectBySubString">
  <property name="startIndex">0</property>     <!-- 截取起始位置 -->
  <property name="size">1</property>             <!-- 截取長度 -->
  <property name="partitionCount">8</property>   <!-- 總分片數 -->
  <property name="defaultPartition">0</property> <!-- 預設分片 -->
</function>

<tablerule name="tr-sharding-substr-mc040302">
  <rule>
    <columns>CODE</columns>                    <!-- 分片字段 -->
    <algorithm>sharding-by-substring-040302</algorithm>
  </rule>
</tablerule>

規則解讀:以 CODE='0-10000020' 為例,startIndex=0, size=1 截取首字符 '0',路由至分片 0(即 dn21);若首字符為 '1' 則路由至分片 1(dn22)。未匹配則走 defaultPartition=0。

2. schema.xml 關聯表規則

在 <table name="ORDER040302" rule="tr-sharding-substr-mc040302"/> 中引用上述 tablerule。

三、建表與數據驗證

CREATE TABLE ORDER040302(
  ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  CODE VARCHAR(64),
  SN VARCHAR(64),
  CREATE_TIME DATETIME
);

插入測試數據

-- 首字符 0 → dn21
INSERT INTO ORDER040302(ID,CODE,SN,CREATE_TIME)
VALUES(1,'0-10000020','beijing_03-10000020',NOW());

-- 首字符 1 → dn22
INSERT INTO ORDER040302(ID,CODE,SN,CREATE_TIME)
VALUES(2,'1-10000020','shanghai_10-10000020',NOW());

EXPLAIN 驗證路由

mysql> EXPLAIN INSERT ... VALUES(1,'0-10000020',...);
+-----------+--------------------------------------------------+
| DATA_NODE | SQL                                              |
+-----------+--------------------------------------------------+
| dn21      | INSERT ... VALUES(1,'0-10000020',...)            |
+-----------+--------------------------------------------------+

mysql> EXPLAIN INSERT ... VALUES(2,'1-10000020',...);
+-----------+--------------------------------------------------+
| DATA_NODE | SQL                                              |
+-----------+--------------------------------------------------+
| dn22      | INSERT ... VALUES(2,'1-10000020',...)            |
+-----------+--------------------------------------------------+

四、MyCat 日誌路由流程深度解析

以下為 mycat.log 關鍵節點(以 ID=2 插入為例):

  1. 獲取連接:ServerConnection[id=1, schema=TESTDB] INSERT ...
  2. 路由匹配:route={ 1 -> dn22{INSERT ...} } 直接命中單節點。
  3. 執行入庫:NonBlockingSession release connection MySQLConnection[id=17, host=10.254.1.11, port=3327, attachment=dn22{...}]
  4. 釋放連接:PhysicalDatasource release channel ... modifiedSQLExecuted=false

整個過程無緩存構建、無多節點廣播,屬於典型的單點直連路由。

五、查詢路由行為對比

1. 指定分片字段精確查詢 → 單節點

mysql> EXPLAIN SELECT * FROM ORDER040302 WHERE CODE='0-10000020';
+-----------+--------------------------------------------------+
| DATA_NODE | SQL                                              |
+-----------+--------------------------------------------------+
| dn21      | SELECT * FROM ORDER040302 WHERE CODE='0-10000020' LIMIT 100 |
+-----------+--------------------------------------------------+

日誌顯示:SQLRouteCache add cache ... route={ 1 -> dn21{...} }

2. 分片字段範圍查詢 → 全節點掃描

mysql> EXPLAIN SELECT * FROM ORDER040302 WHERE CODE LIKE '0-1%';
+-----------+--------------------------------------------------+
| DATA_NODE | SQL                                              |
+-----------+--------------------------------------------------+
| dn21      | SELECT * FROM ORDER040302 WHERE CODE LIKE '0-1%' LIMIT 100 |
| dn22      | SELECT * FROM ORDER040302 WHERE CODE LIKE '0-1%' LIMIT 100 |
+-----------+--------------------------------------------------+

即使數據僅存在 dn21,MyCat 仍廣播至所有分片,因為無法從 LIKE 確定具體分片。

3. 非分片字段查詢 → 全節點掃描

mysql> EXPLAIN SELECT * FROM ORDER040302 WHERE SN='beijing_03-10000020';
+-----------+--------------------------------------------------+
| DATA_NODE | SQL                                              |
+-----------+--------------------------------------------------+
| dn21      | SELECT * FROM ORDER040302 WHERE SN='beijing_03-10000020' LIMIT 100 |
| dn22      | SELECT * FROM ORDER040302 WHERE SN='beijing_03-10000020' LIMIT 100 |
+-----------+--------------------------------------------------+

結論:只有精確匹配分片字段才能享受單點路由優勢,其他場景均退化為全表掃描。

六、總結與建議

  • 適用場景:多租戶、多業務線、地區業務隔離等「應用知曉分片」的業務。
  • 字段設計:分片字段建議為純數字或定長前綴,便於 startIndex/size 穩定截取。
  • 避坑指南:
      • 非分片字段查詢會全庫掃描,必要時建立冗餘索引表或引入全局表。
      • 範圍查詢無法下推,業務層盡量拆分為多次精確查詢。
      • partitionCount 需與物理節點數一致,擴容需重新規劃映射規則。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved