文章目錄
- 使用 MyCat 實現 MySQL 主從讀寫分離完整指南
- 一、MySQL 讀寫分離基礎概述
- 1.1 讀寫分離工作原理
- 1.2 為什么需要讀寫分離
- 1.3 讀寫分離的兩種實現方式
- 主流讀寫分離中間件對比
- 二、MyCat 中間件簡介
- 2.1 MyCat 核心功能
- 2.2 MyCat 適用場景
- 三、環境準備與 MyCat 安裝
- 3.1 前提:安裝 JDK(mycat服務器192.168.100.200)
- 3.2 MyCat 下載與解壓
- 3.3 創建 MyCat 專用用戶與權限配置
- 3.4 MyCat 目錄結構說明
- 四、MyCat 核心配置(讀寫分離關鍵)
- 4.1 配置 MyCat 環境變量
- 4.2 配置用戶授權(server.xml)
- 4.3 配置邏輯庫與主從路由(schema.xml)
- 4.3.1 配置模板(適配“1主2從”架構)
- 4.3.2 核心參數詳解(讀寫分離關鍵)
- 五、MySQL 主從復制配置(讀寫分離前提)
- 5.1 前提:主從庫環境準備
- 5.2 主庫(Master)配置
- 5.3 從庫(Slave1/Slave2)配置
- 六、MyCat 啟動與讀寫分離測試
- 6.1 啟動 MyCat
- 6.2 讀寫分離測試
- 6.2.1 測試讀操作(僅從庫接收,從庫負載均衡)
- 6.2.2 測試寫操作(僅主庫接收)
- 六、總結
使用 MyCat 實現 MySQL 主從讀寫分離完整指南
一、MySQL 讀寫分離基礎概述
在高并發業務場景中,單臺 MySQL 數據庫難以同時承載大量讀寫請求。讀寫分離通過“主庫寫、從庫讀”的分工,結合主從復制保障數據一致性,成為緩解數據庫壓力的核心方案。
1.1 讀寫分離工作原理
讀寫分離的核心是“請求路由”與“數據同步”的結合,具體流程如下:
- 角色分工:
- 主庫(Master):僅處理寫操作(INSERT/UPDATE/DELETE/DDL),確保數據變更的唯一性和一致性;
- 從庫(Slave):僅處理讀操作(SELECT),分擔主庫的讀請求壓力(如商品查詢、數據統計)。
- 數據同步:依賴 MySQL 主從復制機制——主庫將寫操作記錄到“二進制日志(Binary Log)”,從庫通過 IO 線程拉取日志并寫入“中繼日志(Relay Log)”,再通過 SQL 線程回放日志,實現與主庫數據同步。
- 路由轉發:通過中間件(如 MyCat)或應用層判斷請求類型,自動將寫請求轉發到主庫,讀請求分發到從庫(支持負載均衡)。
1.2 為什么需要讀寫分離
- 突破單庫性能瓶頸:多數業務中讀請求占比超 80%(如電商詳情頁、新聞列表),將讀請求分流到從庫,可顯著降低主庫負載;
- 緩解鎖爭用:寫操作會加排他鎖(X 鎖),讀操作加共享鎖(S 鎖),分離后避免“寫鎖阻塞讀、讀鎖阻塞寫”的問題;
- 優化讀性能:從庫可針對性優化(如啟用查詢緩存、使用 MyISAM 引擎),進一步提升讀響應速度;
- 提高可用性:主庫故障時,從庫可切換為新主庫,減少業務中斷時間(需配合故障切換機制)。
1.3 讀寫分離的兩種實現方式
讀寫分離主要通過“應用層”或“中間件層”實現,MyCat 屬于中間件層方案,兩種方式對比如下:
實現方式 | 核心邏輯 | 優點 | 缺點 |
---|---|---|---|
應用程序層實現 | 在代碼中判斷 SQL 類型(寫請求→主庫,讀請求→從庫),直接連接數據庫 | 無中間件開銷,性能損耗低;部署簡單 | 代碼耦合度高,多語言應用需重復開發;架構調整(如增減從庫)需修改代碼 |
中間件層實現 | 在客戶端與數據庫間部署代理(如 MyCat),由代理統一解析請求、轉發路由 | 對應用透明(無需改代碼);支持分庫分表、故障切換、負載均衡 | 增加系統復雜度;代理層需優化配置以避免成為新瓶頸 |
主流讀寫分離中間件對比
中間件 | 開發背景 | 支持事務 | 支持存儲過程 | 核心優勢 | 適用場景 |
---|---|---|---|---|---|
MyCat | 開源社區(基于 Cobar 二次開發) | 支持 | 支持 | 社區活躍、功能全面(讀寫分離+分庫分表)、文檔豐富 | 中小到大型企業,需靈活擴展的場景 |
Cobar | 阿里巴巴 B2B 團隊 | 支持 | 支持 | 早期成熟方案,穩定性強 | 已停更,僅適合維護 legacy 系統 |
OneProxy | 商業軟件 | 支持 | 支持 | 高并發穩定性好,提供商業支持 | 對穩定性要求高的付費場景 |
Amoeba | 阿里陳思儒(個人開發) | 不支持 | 不支持 | 輕量易用,部署簡單 | 小型讀密集場景,無復雜事務需求 |
二、MyCat 中間件簡介
MyCat 是開源企業級數據庫中間件,定位為“MySQL 集群的統一入口”,通過封裝底層數據庫拓撲,為應用提供透明的“邏輯庫”訪問方式,核心能力聚焦于讀寫分離與分庫分表。
2.1 MyCat 核心功能
- 讀寫分離:自動路由寫請求到主庫、讀請求到從庫,支持多種讀負載均衡策略;
- 分庫分表:將大表按規則(如哈希、范圍)拆分到多個數據庫,解決單庫數據量過大問題;
- 事務支持:兼容 MySQL 事務特性,保障 ACID 一致性;
- 高可用:支持主從故障自動切換,減少人工干預;
- 擴展性:可融合內存緩存、NoSQL、HDFS 等技術,適配復雜數據場景。
2.2 MyCat 適用場景
- 讀請求密集的業務(如電商、新聞、社交);
- 數據量較大,需分庫分表擴展的場景;
- 多語言應用或微服務架構,需統一數據庫訪問入口;
- 需降低應用與數據庫耦合度,簡化架構調整的場景。
三、環境準備與 MyCat 安裝
MyCat 基于 Java 開發,需先配置 JDK 環境,再完成安裝與目錄初始化(以 CentOS 7.9、MyCat 1.6 為例)。
1.整個實驗的環境 以及服務器信息
- 環境部署:CentOS 7.9
- 虛擬機服務環境:
- Master服務器:192.168.100.129,部署 mysql 5.7
- Slave1服務器:192.168.100.140,部署 mysql 5.7
- Slave2服務器:192.168.100.150,部署 mysql 5.7
- MyCat服務器:192.168.100.200(預備機器),部署 jdk-8u191-linux + MyCat中間件
2.先完成master,slave1,slave2的主從復制配置,詳情請見
3.1 前提:安裝 JDK(mycat服務器192.168.100.200)
MyCat 依賴 Java 運行環境,推薦 JDK 1.8,linux自帶的open jdk 1.8也行。
- 下載并解壓 JDK:
# 下載 JDK 1.8(可從 Oracle 官網或國內鏡像獲取) wget https://repo.huaweicloud.com/java/jdk/8u191-b12/jdk-8u191-linux-x64.tar.gz # 解壓到 /usr/java 目錄 mkdir -p /usr/java tar -zxvf jdk-8u191-linux-x64.tar.gz -C /usr/java/
- 配置 JDK 環境變量:
vim /etc/profile.d/java.sh # 添加以下內容 export JAVA_HOME=/usr/java/jdk1.8.0_191 export PATH=$JAVA_HOME/bin:$PATH export CLASSPATH=$JAVA_HOME/jre/lib/ext:$JAVA_HOME/lib/tools.jar # 生效環境變量 source /etc/profile.d/java.sh # 驗證安裝(顯示 JDK 版本即成功) java -version
3.2 MyCat 下載與解壓
- 下載 MyCat 穩定版(1.6 RELEASE):
# 從 GitHub 下載(或訪問 MyCat 官網:http://www.mycat.org.cn/) wget https://github.com/MyCATApache/Mycat-download/blob/master/1.6-RELEASE/Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gzrz #本地上傳mycat壓縮包(推薦)
- 解壓到 /usr/local 目錄:
tar -zxvf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz -C /usr/local/ # 進入 MyCat 目錄,確認結構 cd /usr/local/mycat ls # 應顯示 bin、conf、lib、logs 等目錄
3.3 創建 MyCat 專用用戶與權限配置
為避免使用 root 運行中間件,創建專用用戶并授權:
# 創建 mycat 用戶
useradd mycat
# 設置密碼(123)
passwd mycat #密碼為123
# 授權 MyCat 目錄權限給 mycat 用戶
chown -R mycat.mycat /usr/local/mycat
3.4 MyCat 目錄結構說明
目錄路徑 | 核心作用 |
---|---|
/usr/local/mycat/bin | 可執行文件:mycat(啟動/停止/重啟腳本)、wrapper(底層啟動依賴) |
/usr/local/mycat/conf | 配置文件:server.xml(用戶授權)、schema.xml(邏輯庫與路由)、rule.xml(分片規則) |
/usr/local/mycat/lib | 依賴 JAR 包:MySQL 驅動、MyCat 核心組件等 |
/usr/local/mycat/logs | 日志文件:wrapper.log(啟動日志,排查啟動故障)、mycat.log(業務日志) |
四、MyCat 核心配置(讀寫分離關鍵)
MyCat 實現讀寫分離的核心是“定義邏輯庫→綁定數據節點→配置主從路由”,關鍵配置文件為 server.xml
(用戶授權)和 schema.xml
(路由規則)。
4.1 配置 MyCat 環境變量
為方便全局調用 MyCat 命令,配置環境變量:
vim /etc/profile.d/mycat.sh
# 添加以下內容
export MYCAT_HOME=/usr/local/mycat
export PATH=$MYCAT_HOME/bin:$PATH
# 生效環境變量
source /etc/profile.d/mycat.sh
4.2 配置用戶授權(server.xml)
定義客戶端訪問 MyCat 的賬號、密碼及關聯的“邏輯庫”(邏輯庫是 MyCat 封裝的虛擬庫,對應底層物理庫):
vim /usr/local/mycat/conf/server.xml<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/"><!-- 管理員賬號:擁有讀寫權限 --><user name="mycat"><property name="password">123</property> <!-- 密碼 --><property name="schemas">ceshi</property> <!-- 關聯邏輯庫名稱(需與 schema.xml 一致),必須是關聯的主從庫里的庫。 --></user><!-- 普通用戶:僅只讀權限 --><user name="user"><property name="password">user</property><property name="schemas">ceshi</property><property name="readOnly">true</property> <!-- 只讀配置,禁止寫操作 --></user>
</mycat:server>
4.3 配置邏輯庫與主從路由(schema.xml)
schema.xml
是讀寫分離的核心配置文件,需定義“邏輯庫→數據節點→主從數據庫”的映射關系,并指定讀寫策略。
4.3.1 配置模板(適配“1主2從”架構)
1.首先進行源文件備份
mv /usr/local/mycat/conf/schema.xml /usr/local/mycat/conf/schema.xml.bak
vim /usr/local/mycat/conf/schema.xml
下方內容直接復制粘貼,ip改為自己的機器即可。
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/"><schema name="ceshi" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1"> </schema><dataNode name="dn1" dataHost="dthost" database="ceshi"/> <dataHost name="dthost"maxCon="500" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="-1" slaveThreshold="100"> <heartbeat>select 1</heartbeat><writeHost host="master" url="192.168.100.139:3306" user="mycat" password="123"> <readHost host="slave1" url="192.168.100.128:3306" user="mycat"password="123"/><readHost host="slave2" url="192.168.100.130:3306" user="mycat"password="123"/></writeHost></dataHost>
</mycat:schema>
4.3.2 核心參數詳解(讀寫分離關鍵)
參數名 | 取值與含義 | 推薦配置 |
---|---|---|
balance | 讀負載均衡策略: - 0:不分離,所有讀請求走寫節點; - 1:所有從庫+備用主庫參與讀負載; - 2:讀請求隨機分發到主庫+從庫; - 3:讀請求僅走從庫,主庫不承擔讀 | 1(均衡分擔讀壓力) |
writeType | 寫策略: - 0:所有寫請求走第一個 writeHost(主庫); - 1:寫請求隨機走 writeHost(1.5+ 已廢棄) | 0(主庫唯一寫節點) |
switchType | 主從切換策略: - -1:不自動切換,需手動干預; - 1:默認自動切換(基于心跳檢測); - 2:基于主從同步狀態切換(心跳用 show slave status); - 3:基于 MySQL MGR 集群切換 | -1(手動切換更安全,避免誤切) |
五、MySQL 主從復制配置(讀寫分離前提)
MyCat 讀寫分離依賴 MySQL 主從復制(確保從庫數據與主庫一致),需先完成“1主2從”的主從配置(以 MySQL 5.7 為例)。
5.1 前提:主從庫環境準備
- 主庫(Master):IP 192.168.100.129,已安裝 MySQL 5.7;
- 從庫1(Slave1):IP 192.168.100.140,已安裝 MySQL 5.7;
- 從庫2(Slave2):IP 192.168.100.150,已安裝 MySQL 5.7;
- 所有節點關閉防火墻與 SELinux:
主從復制詳情見主從復制systemctl stop firewalld && systemctl disable firewalld setenforce 0 && sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
5.2 主庫(Master)配置
以下均為主從復制配置完成后的設置:
mysql> create database ceshi;
mysql> use database;
mysql> create table test (id int(10),name varchar(10),address varchar(20));mysql> grant all privileges on *.* to 'mycat'@'%' identified by '123';
mysql> flush privileges;
5.3 從庫(Slave1/Slave2)配置
以下均為主從復制配置完成后的設置:
mysql> grant all on db.* to 'mycat'@'%' identified by '123';
六、MyCat 啟動與讀寫分離測試
完成 MyCat 與 MySQL 主從配置后,啟動 MyCat 并驗證讀寫分離效果。
6.1 啟動 MyCat
- 啟動 MyCat:
cd /usr/local/mycat/bin ./mycat start # 啟動;停止用 mycat stop,重啟用 mycat restart
- 驗證啟動狀態:
# 查看 MyCat 進程(默認端口 8066,管理端口 9066) netstat -tnlp | grep 8066 ./mycat status #顯示running即可。 # 查看啟動日志(排查故障,如端口占用、配置錯誤) cat /usr/local/mycat/logs/wrapper.log(可不查)
6.2 讀寫分離測試
測試需通過“客戶端連接 MyCat”而非直接連接 MySQL,驗證“寫走主庫、讀走從庫”。
6.2.1 測試讀操作(僅從庫接收,從庫負載均衡)
在測試讀實驗期間,后臺的主從復制必須正常啟動,不能關閉
-
客戶端連接 MyCat(在第四臺機器192.168.100.200):
yum install -y mariadb-server mariadb #mycat只是中間件,需要借助客戶端工具才能提供數據交互終端。 systemctl start mariadb.service
-
切換到master庫ceshi,插入數據:
mysql> use ceshi;# 插入數據 mysql> insert into test values('3','wangwu','this_is_master');
-
slave1從屬機
mysql> use ceshi; mysql> insert into test values('1','zhangsan','this_is_slave1'); mysql> select * from test
-
slave2從屬機
mysql> use ceshi; mysql> insert into test values('2','lisi','this_is_slave2'); mysql> select * from test
-
在mycat機器上
#格式:mysql -uMyCat賬號 -p密碼 -hMyCatIP -PMyCat端口(默認 8066) mysql -umycat -p123 -h127.0.0.1 -P8066 # MyCat 部署在 192.168.100.200 mysql> show databases; #顯示ceshi庫 mysql> use ceshi; mysql> show tables; #顯示test表 mysql> select * from test; #交替顯示slave1,slave2的表,即為成功。
-
觀察結果
在 MyCat 客戶端(192.168.100.200 機器)多次執行 select * from test; 后,可觀察到以下核心現象:
- 數據來源僅為從庫:執行查詢時,始終不會出現主庫(master)中插入的記錄 (‘3’,‘wangwu’,‘this_is_master’),證明讀操作未路由到主庫,僅從從庫獲取數據;
- 從庫負載均衡生效:多次執行查詢會交替返回兩個從庫的獨有數據:
交替出現的結果表明 MyCat 已實現從庫間的讀請求負載均衡,符合 “讀走從庫” 的讀寫分離預期。
6.2.2 測試寫操作(僅主庫接收)
- 暫停從庫主從同步(僅測試用,模擬從庫數據差異):
- 連接 Slave1(192.168.100.140):
mysql> stop slave; #防止主機的數據被同步到從屬機。
- 連接 Slave2(192.168.100.150):
mysql> stop slave; #防止主機的數據被同步到從屬機。
- 連接 Slave1(192.168.100.140):
- MyCat服務器,執行寫操作:
mysql> insert into test values('4','qianqi','this_is_client');
- 觀察結果:
在 MyCat 客戶端執行 insert into test values(‘4’,‘qianqi’,‘this_is_client’); 后,分別登錄主庫(master)、slave1、slave2 查看 test 表,可觀察到以下對比現象:
- 主庫(master)數據變化:
登錄主庫執行 select * from ceshi.test;,能看到新增記錄 (‘4’,‘qianqi’,‘this_is_client’),同時保留主庫原有記錄 (‘3’,‘wangwu’,‘this_is_master’),證明寫操作已路由到主庫;
從庫(slave1、slave2)數據無變化:
結合 “已暫停主從同步” 的前提,從庫未出現新增數據,直接證明寫操作未路由到任何從庫,僅主庫接收寫請求,符合 “寫走主庫” 的讀寫分離預期。
六、總結
- 核心依賴:MyCat 讀寫分離的前提是 MySQL 主從復制,需確保從庫
Slave_IO_Running
與Slave_SQL_Running
均為Yes
; - 關鍵配置:MyCat 的
schema.xml
中,balance
(讀負載)、writeType
(寫路由)、switchType
(故障切換)是決定讀寫分離效果的核心參數; - 價值:MyCat 為應用提供透明的數據庫訪問入口,無需修改代碼即可實現讀寫分離,同時支持擴展分庫分表,是企業級 MySQL 架構的重要中間件;
- 注意事項:生產環境需關閉
validate-password=OFF
,配置強密碼;switchType
建議設為 -1(手動切換),避免主從延遲導致的切換異常;定期監控主從延遲與 MyCat 連接池狀態。