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

MyCat 連續分片實戰:自定義數字範圍分片配置與路由驗證

     編輯:MySQL 綜合教學

前言

自定義數字範圍分片適用於「業務對 ID 範圍有明確規劃」的場景,例如:前 500 萬用戶落分片 1,500 萬-1000 萬落分片 2,以此類推。MyCat 通過 AutoPartitionByLong 算法讀取映射文件實現該功能。本文完整演示配置、映射文件、建表、寫入與查詢路由行為。

一、分片邏輯

  • 映射文件定義 起始ID-結束ID=分片編號(分片編號從 0 開始)。
  • 寫入/查詢時,MyCat 根據分片字段值二分查找映射區間,命中即路由至對應分片。
  • 未命中任何區間時路由至 defaultNode。
  • 支援 M(百萬)、K(千)等單位簡寫,如 0-500M=0。

二、配置文件

function.xml

<function name="rang-long-04" class="org.opencloudb.route.function.AutoPartitionByLong">
  <property name="mapFile">autopartition-long04.txt</property>
  <property name="defaultNode">0</property>
  <property name="type">0</property>
</function>

<tablerule name="rang-long-tr04">
  <rule>
    <columns>ID</columns>
    <algorithm>rang-long-04</algorithm>
  </rule>
</tablerule>

映射文件 autopartition-long04.txt

0-500M=0      # 0 - 5,000,000   → 分片 0 (dn21)
500M-1000M=1  # 5,000,000 - 10,000,000 → 分片 1 (dn22)
1000M-1500M=2 # 10,000,000 - 15,000,000 → 分片 2 (dn23)

三、建表與寫入驗證

CREATE TABLE ORDER0401(
  ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  PROVINCE VARCHAR(16),
  SN VARCHAR(64),
  CREATE_TIME DATETIME
);

測試數據

-- ID=10001 落在 0-500M → dn21
INSERT INTO ORDER0401(ID,PROVINCE,SN,CREATE_TIME)
VALUES(10001,'shanghai','shanghai10006_10000',NOW());

-- ID=5000001 落在 500M-1000M → dn22
INSERT INTO ORDER0401(ID,PROVINCE,SN,CREATE_TIME)
VALUES(5000001,'shanghai','shanghai10006_5000001',NOW());

EXPLAIN 驗證

mysql> EXPLAIN INSERT ... VALUES(10001,...);
+-----------+--------------------------------------------------+
| DATA_NODE | SQL                                              |
+-----------+--------------------------------------------------+
| dn21      | INSERT ... VALUES(10001,...)                     |
+-----------+--------------------------------------------------+

mysql> EXPLAIN INSERT ... VALUES(5000001,...);
+-----------+--------------------------------------------------+
| DATA_NODE | SQL                                              |
+-----------+--------------------------------------------------+
| dn22      | INSERT ... VALUES(5000001,...)                   |
+-----------+--------------------------------------------------+

四、寫入路由日誌深度解析

關鍵節點(ID=10001 寫入):

  1. ServerConnection INSERT ... ID=10001
  2. RouterUtil try to find cache by primary key
  3. DefaultLayedCachePool create child Cache: TESTDB_ORDER0401 ... size 10000, expire seconds 18000 —— 首次寫入觸發主鍵緩存構建
  4. route={ 1 -> dn21{INSERT ...} } rrs
  5. NonBlockingSession release connection MySQLConnection[id=8, host=13.217.1.11, port=3317, attachment=dn21{...}]
  6. PhysicalDatasource release channel ... modifiedSQLExecuted=false

關鍵觀察:範圍分片首次寫入會構建 TableID2DataNodeCache(主鍵→分片映射緩存),後續同主鍵查詢/更新可直接命中緩存,避免重複解析映射文件。

五、查詢路由行為

1. 主鍵精確查詢 → 單節點(命中緩存)

mysql> EXPLAIN SELECT * FROM ORDER0401 WHERE ID=5000001;
+-----------+--------------------------------------------------+
| DATA_NODE | SQL                                              |
+-----------+--------------------------------------------------+
| dn22      | SELECT * FROM ORDER0401 WHERE ID=5000001         |
+-----------+--------------------------------------------------+

日誌:RouterUtil try to find cache by primary key ... TableID2DataNodeCache.TESTDB_ORDER0401 miss cache, key:5000001 ... route={ 1 -> dn22{...} }

2. 主鍵範圍查詢 → 全節點

mysql> EXPLAIN SELECT * FROM ORDER0401 WHERE ID < 50000;
+-----------+--------------------------------------------------+
| DATA_NODE | SQL                                              |
+-----------+--------------------------------------------------+
| dn21      | SELECT * FROM ORDER0401 WHERE ID < 50000 LIMIT 100 |
| dn22      | SELECT * FROM ORDER0401 WHERE ID < 50000 LIMIT 100 |
+-----------+--------------------------------------------------+

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

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

六、運維建議與擴容策略

  • 映射文件規劃:預留足夠 ID 空間,避免頻繁修改映射文件。建議按業務增長預估 2-3 年容量一次性規劃。
  • 平滑擴容:新增分片時,僅需在映射文件末尾追加新區間,並同步增加 dataNode 定義,執行 reload @@config 生效,無需遷移歷史數據。
  • 熱點防範:若新用戶 ID 按遞增分配,寫入壓力將持續集中在最新分片。可考慮:
      • 使用雪花算法生成非連續 ID,分散寫入熱點
      • 或採用「範圍+哈希」混合策略:高位按範圍分片,低位哈希分片
  • 緩存監控:關注 TableID2DataNodeCache 命中率與大小,必要時調整 size 與 expire seconds。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved