MyCat 作為資料庫中間件,核心價值之一是透明化 MySQL 主從架構的讀寫分離與故障自動切換。本文從架構決策、Schema.xml 核心配置、心跳機制、切換策略、驗證測試五個維度深度實戰。
| 策略 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|
| 分表 (單機) | 維護簡單、類似分區 | 無法分攤 IO/CPU、單點故障 | 單表過大、查詢緩慢、但寫入壓力小 |
| 分庫 (多機) | 分攤 IO/CPU/連接數、高可用 | 跨庫 JOIN/事務複雜、運維成本高 | 高併發、大數據量、需水平擴展 |
| 讀寫分離 (主從) | 讀壓力分流、備份不影響主庫、零代碼改造 | 主從延遲導致讀舊數據、寫入仍單點 | 讀多寫少、報表分析、非強一致讀場景 |
結論:分表不解決資源瓶頸,**分庫 + 讀寫分離** 是生產主流架構。MyCat 同時支援兩者。
# 主庫 3317 端口
tar -xzf mysql-5.6.12.tar.gz
cd mysql-5.6.12
cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql56m1 -DMYSQL_DATADIR=/home/data/mysql56m1/data ...
make && make install
# 初始化、啟動、建立復制帳號
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'10.254.%' IDENTIFIED BY 'mycatms';
# 從庫 3327 端口 (同步安裝)
# 從庫配置同步
STOP SLAVE; RESET SLAVE;
CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=3317, MASTER_USER='repl', MASTER_PASSWORD='mycatms', MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS=840;
START SLAVE;
SHOW SLAVE STATUS\G; -- 確認 Slave_IO_Running=Yes, Slave_SQL_Running=Yes
<?xml version="1.0"?>
<mycat:schema xmlns:mycat="https://io.mycat/">
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
<table name="company" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" primaryKey="id" />
</schema>
<!-- 數據節點:映射到後端 MySQL 實例的具體庫 -->
<dataNode name="dn1" dataHost="dh1" database="db1" />
<dataNode name="dn2" dataHost="dh2" database="db1" /> <!-- 從庫同名庫 -->
<dataNode name="dn3" dataHost="dh3" database="db1" /> <!-- 備用從庫 -->
<!-- 數據主機組:定義寫入主機、讀取從機、切換策略 -->
<dataHost name="dh1" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="2" slaveThreshold="100">
<heartbeat>SHOW SLAVE STATUS</heartbeat> <!-- 關鍵:心跳語句必須為 SHOW SLAVE STATUS -->
<writeHost host="hostM1" url="127.0.0.1:3317" user="root" password="123456">
<readHost host="hostS1" url="127.0.0.1:3327" user="root" password="123456" /> <!-- 從屬讀節點 -->
</writeHost>
<!-- 可添加備用寫入主機 (雙主熱備) -->
<writeHost host="hostM2" url="192.168.1.100:3306" user="root" password="123456" />
</dataHost>
<!-- 其他 dataHost dh2, dh3 配置類似,對應其他分片 -->
</mycat:schema>
0:不開啟讀寫分離,所有讀寫走 writeHost。1:**所有 readHost + 備用 writeHost 參與 SELECT 負載均衡** (推薦讀寫分離)。2:所有 readHost + 所有 writeHost 參與 SELECT (雙主雙寫場景)。3:所有 readHost 參與 SELECT (writeHost 不參讀)。-1:不自動切換 (手動運維)。1:**基於心跳檢測** (MyCat 發送 heartbeat 語句,如 SELECT 1),檢測主庫存活。不檢測主從同步狀態,主庫掛了直接切,可能切到數據舊的從庫。**不推薦生產**。2:基於 MySQL 主從同步狀態決定切換 (推薦)。心跳語句**必須為 SHOW SLAVE STATUS**。MyCat 解析 Slave_IO_Running、Slave_SQL_Running、Seconds_Behind_Master,只有同步正常、延遲在閾值內的從庫才會被提升為新主庫。**防止數據丟失/不一致**。3:基於 MySQL Cluster (NDB) 狀態切換。SHOW SLAVE STATUS,MyCat 內建解析器提取關鍵指標。heartbeatTimeout、heartbeatInterval 控制 (毫秒)。switchType=2,Seconds_Behind_Master > slaveThreshold 視為不可用,不參與切換候選。-- 通過 MyCat (8066) 建表、寫入
mysql -u test -p test -h 127.0.0.1 -P 8066 -D TESTDB
mysql> EXPLAIN CREATE TABLE company(id INT NOT NULL PRIMARY KEY, name VARCHAR(100));
-- 路由至 dn1,dn2,dn3 (三分片同步建表)
mysql> EXPLAIN INSERT INTO company(id,name) VALUES(1,'alibaba');
-- 路由至 dn1,dn2,dn3
mysql> INSERT INTO company(id,name) VALUES(1,'alibaba');
-- 驗證主庫 (3317)
/usr/local/mysql56m1/bin/mysql -u root -p -P 3317 -S /usr/local/mysql56m1/mysql.sock -e "SELECT @@port; SELECT * FROM db1.company;"
-- 輸出: 3317, id=1, name=alibaba
-- 驗證從庫 (3327)
/usr/local/mysql56s1/bin/mysql -u root -p -P 3327 -S /usr/local/mysql56s1/mysql.sock -e "SELECT @@port; SELECT * FROM db1.company;"
-- 輸出: 3327, id=1, name=alibaba (數據同步正常)
-- 修改 schema.xml dataHost 區段
balance="1" -- 開啟讀寫分離:readHost 參與 SELECT
switchType="2" -- 基於同步狀態切換
heartbeat="SHOW SLAVE STATUS"
-- 測試:多次 SELECT 觀察路由
mysql> EXPLAIN SELECT * FROM company;
-- 應輪詢分發至 writeHost (主庫) 和 readHost (從庫)
-- 寫入 INSERT/UPDATE/DELETE 始終路由至 writeHost
kill -9 `pidof mysqld` (3317 進程)。SHOW SLAVE STATUS 無回應/錯誤)。Slave_IO_Running=Yes, Slave_SQL_Running=Yes, Seconds_Behind_Master=0。hostS1 (3327) 提升為新 writeHost,原 writeHost 標記為不可用。switchType=2 配合外部編排工具 (MHA/Orchestrator) 實現主主切回。SHOW SLAVE STATUS 需此權限,GRANT REPLICATION CLIENT ON *.* TO 'user'@'%';。auto_increment_offset/increment 避免主鍵衝突,並部署仲裁機制 (MHA/Keepalived/VIP)。SHOW @@datanode、SHOW @@heartbeat、Seconds_Behind_Master、切換事件日誌。MyCat 讀寫分離核心配置:**balance=1 + switchType=2 + heartbeat=SHOW SLAVE STATUS**。此組合實現「讀負載均衡到從庫、寫固定主庫、故障基於同步健康度自動切換」。生產落地需補全權限、監控、演練、一致性業務識別,構建完整高可用體系。