使用MyCat實現(xiàn)MySQL主從讀寫分離全過程
一、MySQL 讀寫分離基礎(chǔ)概述
在高并發(fā)業(yè)務(wù)場景中,單臺 MySQL 數(shù)據(jù)庫難以同時承載大量讀寫請求。讀寫分離通過“主庫寫、從庫讀”的分工,結(jié)合主從復(fù)制保障數(shù)據(jù)一致性,成為緩解數(shù)據(jù)庫壓力的核心方案。
1.1 讀寫分離工作原理
讀寫分離的核心是“請求路由”與“數(shù)據(jù)同步”的結(jié)合,具體流程如下:
角色分工:
- 主庫(Master):僅處理寫操作(INSERT/UPDATE/DELETE/DDL),確保數(shù)據(jù)變更的唯一性和一致性;
- 從庫(Slave):僅處理讀操作(SELECT),分擔(dān)主庫的讀請求壓力(如商品查詢、數(shù)據(jù)統(tǒng)計)。
數(shù)據(jù)同步:依賴 MySQL 主從復(fù)制機制——主庫將寫操作記錄到“二進制日志(Binary Log)”,從庫通過 IO 線程拉取日志并寫入“中繼日志(Relay Log)”,再通過 SQL 線程回放日志,實現(xiàn)與主庫數(shù)據(jù)同步。
路由轉(zhuǎn)發(fā):通過中間件(如 MyCat)或應(yīng)用層判斷請求類型,自動將寫請求轉(zhuǎn)發(fā)到主庫,讀請求分發(fā)到從庫(支持負載均衡)。
1.2 為什么需要讀寫分離
- 突破單庫性能瓶頸:多數(shù)業(yè)務(wù)中讀請求占比超 80%(如電商詳情頁、新聞列表),將讀請求分流到從庫,可顯著降低主庫負載;
- 緩解鎖爭用:寫操作會加排他鎖(X 鎖),讀操作加共享鎖(S 鎖),分離后避免“寫鎖阻塞讀、讀鎖阻塞寫”的問題;
- 優(yōu)化讀性能:從庫可針對性優(yōu)化(如啟用查詢緩存、使用 MyISAM 引擎),進一步提升讀響應(yīng)速度;
- 提高可用性:主庫故障時,從庫可切換為新主庫,減少業(yè)務(wù)中斷時間(需配合故障切換機制)。
1.3 讀寫分離的兩種實現(xiàn)方式
讀寫分離主要通過“應(yīng)用層”或“中間件層”實現(xiàn),MyCat 屬于中間件層方案,兩種方式對比如下:
| 實現(xiàn)方式 | 核心邏輯 | 優(yōu)點 | 缺點 |
|---|---|---|---|
| 應(yīng)用程序?qū)訉崿F(xiàn) | 在代碼中判斷 SQL 類型(寫請求→主庫,讀請求→從庫),直接連接數(shù)據(jù)庫 | 無中間件開銷,性能損耗低;部署簡單 | 代碼耦合度高,多語言應(yīng)用需重復(fù)開發(fā);架構(gòu)調(diào)整(如增減從庫)需修改代碼 |
| 中間件層實現(xiàn) | 在客戶端與數(shù)據(jù)庫間部署代理(如 MyCat),由代理統(tǒng)一解析請求、轉(zhuǎn)發(fā)路由 | 對應(yīng)用透明(無需改代碼);支持分庫分表、故障切換、負載均衡 | 增加系統(tǒng)復(fù)雜度;代理層需優(yōu)化配置以避免成為新瓶頸 |
主流讀寫分離中間件對比
| 中間件 | 開發(fā)背景 | 支持事務(wù) | 支持存儲過程 | 核心優(yōu)勢 | 適用場景 |
|---|---|---|---|---|---|
| MyCat | 開源社區(qū)(基于 Cobar 二次開發(fā)) | 支持 | 支持 | 社區(qū)活躍、功能全面(讀寫分離+分庫分表)、文檔豐富 | 中小到大型企業(yè),需靈活擴展的場景 |
| Cobar | 阿里巴巴 B2B 團隊 | 支持 | 支持 | 早期成熟方案,穩(wěn)定性強 | 已停更,僅適合維護 legacy 系統(tǒng) |
| OneProxy | 商業(yè)軟件 | 支持 | 支持 | 高并發(fā)穩(wěn)定性好,提供商業(yè)支持 | 對穩(wěn)定性要求高的付費場景 |
| Amoeba | 阿里陳思儒(個人開發(fā)) | 不支持 | 不支持 | 輕量易用,部署簡單 | 小型讀密集場景,無復(fù)雜事務(wù)需求 |
二、MyCat 中間件簡介
MyCat 是開源企業(yè)級數(shù)據(jù)庫中間件,定位為“MySQL 集群的統(tǒng)一入口”,通過封裝底層數(shù)據(jù)庫拓撲,為應(yīng)用提供透明的“邏輯庫”訪問方式,核心能力聚焦于讀寫分離與分庫分表。
2.1 MyCat 核心功能
- 讀寫分離:自動路由寫請求到主庫、讀請求到從庫,支持多種讀負載均衡策略;
- 分庫分表:將大表按規(guī)則(如哈希、范圍)拆分到多個數(shù)據(jù)庫,解決單庫數(shù)據(jù)量過大問題;
- 事務(wù)支持:兼容 MySQL 事務(wù)特性,保障 ACID 一致性;
- 高可用:支持主從故障自動切換,減少人工干預(yù);
- 擴展性:可融合內(nèi)存緩存、NoSQL、HDFS 等技術(shù),適配復(fù)雜數(shù)據(jù)場景。
2.2 MyCat 適用場景
- 讀請求密集的業(yè)務(wù)(如電商、新聞、社交);
- 數(shù)據(jù)量較大,需分庫分表擴展的場景;
- 多語言應(yīng)用或微服務(wù)架構(gòu),需統(tǒng)一數(shù)據(jù)庫訪問入口;
- 需降低應(yīng)用與數(shù)據(jù)庫耦合度,簡化架構(gòu)調(diào)整的場景。
三、環(huán)境準(zhǔn)備與 MyCat 安裝
MyCat 基于 Java 開發(fā),需先配置 JDK 環(huán)境,再完成安裝與目錄初始化(以 CentOS 7.9、MyCat 1.6 為例)。
1.整個實驗的環(huán)境 以及服務(wù)器信息
- 環(huán)境部署:CentOS 7.9
虛擬機服務(wù)環(huán)境:
- Master服務(wù)器:192.168.100.129,部署 mysql 5.7
- Slave1服務(wù)器:192.168.100.140,部署 mysql 5.7
- Slave2服務(wù)器:192.168.100.150,部署 mysql 5.7
- MyCat服務(wù)器:192.168.100.200(預(yù)備機器),部署 jdk-8u191-linux + MyCat中間件
2.先完成master,slave1,slave2的主從復(fù)制配置,詳情請見
3.1 前提:安裝 JDK(mycat服務(wù)器192.168.100.200)
MyCat 依賴 Java 運行環(huán)境,推薦 JDK 1.8,linux自帶的open jdk 1.8也行。
- 下載并解壓 JDK:
# 下載 JDK 1.8(可從 Oracle 官網(wǎng)或國內(nèi)鏡像獲?。? 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 環(huán)境變量:
vim /etc/profile.d/java.sh # 添加以下內(nèi)容 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 # 生效環(huán)境變量 source /etc/profile.d/java.sh # 驗證安裝(顯示 JDK 版本即成功) java -version
3.2 MyCat 下載與解壓
- 下載 MyCat 穩(wěn)定版(1.6 RELEASE):
# 從 GitHub 下載(或訪問 MyCat 官網(wǎng):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.gz rz #本地上傳mycat壓縮包(推薦)
- 解壓到 /usr/local 目錄:
tar -zxvf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz -C /usr/local/ # 進入 MyCat 目錄,確認結(jié)構(gòu) cd /usr/local/mycat ls # 應(yīng)顯示 bin、conf、lib、logs 等目錄
3.3 創(chuàng)建 MyCat 專用用戶與權(quán)限配置
為避免使用 root 運行中間件,創(chuàng)建專用用戶并授權(quán):
# 創(chuàng)建 mycat 用戶 useradd mycat # 設(shè)置密碼(123) passwd mycat #密碼為123 # 授權(quán) MyCat 目錄權(quán)限給 mycat 用戶 chown -R mycat.mycat /usr/local/mycat
3.4 MyCat 目錄結(jié)構(gòu)說明
| 目錄路徑 | 核心作用 |
|---|---|
| /usr/local/mycat/bin | 可執(zhí)行文件:mycat(啟動/停止/重啟腳本)、wrapper(底層啟動依賴) |
| /usr/local/mycat/conf | 配置文件:server.xml(用戶授權(quán))、schema.xml(邏輯庫與路由)、rule.xml(分片規(guī)則) |
| /usr/local/mycat/lib | 依賴 JAR 包:MySQL 驅(qū)動、MyCat 核心組件等 |
| /usr/local/mycat/logs | 日志文件:wrapper.log(啟動日志,排查啟動故障)、mycat.log(業(yè)務(wù)日志) |
四、MyCat 核心配置(讀寫分離關(guān)鍵)
MyCat 實現(xiàn)讀寫分離的核心是“定義邏輯庫→綁定數(shù)據(jù)節(jié)點→配置主從路由”,關(guān)鍵配置文件為 server.xml(用戶授權(quán))和 schema.xml(路由規(guī)則)。
4.1 配置 MyCat 環(huán)境變量
為方便全局調(diào)用 MyCat 命令,配置環(huán)境變量:
vim /etc/profile.d/mycat.sh # 添加以下內(nèi)容 export MYCAT_HOME=/usr/local/mycat export PATH=$MYCAT_HOME/bin:$PATH # 生效環(huán)境變量 source /etc/profile.d/mycat.sh
4.2 配置用戶授權(quán)(server.xml)
定義客戶端訪問 MyCat 的賬號、密碼及關(guān)聯(lián)的“邏輯庫”(邏輯庫是 MyCat 封裝的虛擬庫,對應(yīng)底層物理庫):
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/">
<!-- 管理員賬號:擁有讀寫權(quán)限 -->
<user name="mycat">
<property name="password">123</property> <!-- 密碼 -->
<property name="schemas">ceshi</property> <!-- 關(guān)聯(lián)邏輯庫名稱(需與 schema.xml 一致),必須是關(guān)聯(lián)的主從庫里的庫。 -->
</user>
<!-- 普通用戶:僅只讀權(quán)限 -->
<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 是讀寫分離的核心配置文件,需定義“邏輯庫→數(shù)據(jù)節(jié)點→主從數(shù)據(jù)庫”的映射關(guān)系,并指定讀寫策略。
4.3.1 配置模板(適配“1主2從”架構(gòu))
1.首先進行源文件備份
mv /usr/local/mycat/conf/schema.xml /usr/local/mycat/conf/schema.xml.bak
vim /usr/local/mycat/conf/schema.xml
下方內(nèi)容直接復(fù)制粘貼,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 核心參數(shù)詳解(讀寫分離關(guān)鍵)
| 參數(shù)名 | 取值與含義 | 推薦配置 |
|---|---|---|
| balance | 讀負載均衡策略:- 0:不分離,所有讀請求走寫節(jié)點;- 1:所有從庫+備用主庫參與讀負載;- 2:讀請求隨機分發(fā)到主庫+從庫;- 3:讀請求僅走從庫,主庫不承擔(dān)讀 | 1(均衡分擔(dān)讀壓力) |
| writeType | 寫策略:- 0:所有寫請求走第一個 writeHost(主庫);- 1:寫請求隨機走 writeHost(1.5+ 已廢棄) | 0(主庫唯一寫節(jié)點) |
| switchType | 主從切換策略:- -1:不自動切換,需手動干預(yù);- 1:默認自動切換(基于心跳檢測);- 2:基于主從同步狀態(tài)切換(心跳用 show slave status);- 3:基于 MySQL MGR 集群切換 | -1(手動切換更安全,避免誤切) |
五、MySQL 主從復(fù)制配置(讀寫分離前提)
MyCat 讀寫分離依賴 MySQL 主從復(fù)制(確保從庫數(shù)據(jù)與主庫一致),需先完成“1主2從”的主從配置(以 MySQL 5.7 為例)。
5.1 前提:主從庫環(huán)境準(zhǔn)備
- 主庫(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;
所有節(jié)點關(guān)閉防火墻與 SELinux:
systemctl stop firewalld && systemctl disable firewalld setenforce 0 && sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
5.2 主庫(Master)配置
以下均為主從復(fù)制配置完成后的設(shè)置:
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)配置
以下均為主從復(fù)制配置完成后的設(shè)置:
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
驗證啟動狀態(tài):
# 查看 MyCat 進程(默認端口 8066,管理端口 9066) netstat -tnlp | grep 8066 ./mycat status #顯示running即可。 # 查看啟動日志(排查故障,如端口占用、配置錯誤) cat /usr/local/mycat/logs/wrapper.log(可不查)
6.2 讀寫分離測試
測試需通過“客戶端連接 MyCat”而非直接連接 MySQL,驗證“寫走主庫、讀走從庫”。
6.2.1 測試讀操作(僅從庫接收,從庫負載均衡)
在測試讀實驗期間,后臺的主從復(fù)制必須正常啟動,不能關(guān)閉
- 客戶端連接 MyCat(在第四臺機器192.168.100.200):
yum install -y mariadb-server mariadb #mycat只是中間件,需要借助客戶端工具才能提供數(shù)據(jù)交互終端。 systemctl start mariadb.service
- 切換到master庫ceshi,插入數(shù)據(jù):
mysql> use ceshi;
# 插入數(shù)據(jù)
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的表,即為成功。
觀察結(jié)果
在 MyCat 客戶端(192.168.100.200 機器)多次執(zhí)行 select * from test; 后,可觀察到以下核心現(xiàn)象:
- 數(shù)據(jù)來源僅為從庫:執(zhí)行查詢時,始終不會出現(xiàn)主庫(master)中插入的記錄 (‘3’,‘wangwu’,‘this_is_master’),證明讀操作未路由到主庫,僅從從庫獲取數(shù)據(jù);
- 從庫負載均衡生效:多次執(zhí)行查詢會交替返回兩個從庫的獨有數(shù)據(jù):交替出現(xiàn)的結(jié)果表明 MyCat 已實現(xiàn)從庫間的讀請求負載均衡,符合 “讀走從庫” 的讀寫分離預(yù)期。
6.2.2 測試寫操作(僅主庫接收)
- 暫停從庫主從同步(僅測試用,模擬從庫數(shù)據(jù)差異):
連接 Slave1(192.168.100.140):
mysql> stop slave; #防止主機的數(shù)據(jù)被同步到從屬機。
連接 Slave2(192.168.100.150):
mysql> stop slave; #防止主機的數(shù)據(jù)被同步到從屬機。
MyCat服務(wù)器,執(zhí)行寫操作:
mysql> insert into test values('4','qianqi','this_is_client');
觀察結(jié)果:
在 MyCat 客戶端執(zhí)行 insert into test values(‘4’,‘qianqi’,‘this_is_client’); 后,分別登錄主庫(master)、slave1、slave2 查看 test 表,可觀察到以下對比現(xiàn)象:
主庫(master)數(shù)據(jù)變化:
- 登錄主庫執(zhí)行 select * from ceshi.test;,能看到新增記錄 (‘4’,‘qianqi’,‘this_is_client’),同時保留主庫原有記錄 (‘3’,‘wangwu’,‘this_is_master’),證明寫操作已路由到主庫;
- 從庫(slave1、slave2)數(shù)據(jù)無變化:
結(jié)合 “已暫停主從同步” 的前提,從庫未出現(xiàn)新增數(shù)據(jù),直接證明寫操作未路由到任何從庫,僅主庫接收寫請求,符合 “寫走主庫” 的讀寫分離預(yù)期。
六、總結(jié)
- 核心依賴:MyCat 讀寫分離的前提是 MySQL 主從復(fù)制,需確保從庫
Slave_IO_Running與Slave_SQL_Running均為Yes; - 關(guān)鍵配置:MyCat 的
schema.xml中,balance(讀負載)、writeType(寫路由)、switchType(故障切換)是決定讀寫分離效果的核心參數(shù); - 價值:MyCat 為應(yīng)用提供透明的數(shù)據(jù)庫訪問入口,無需修改代碼即可實現(xiàn)讀寫分離,同時支持?jǐn)U展分庫分表,是企業(yè)級 MySQL 架構(gòu)的重要中間件;
- 注意事項:生產(chǎn)環(huán)境需關(guān)閉
validate-password=OFF,配置強密碼;switchType建議設(shè)為 -1(手動切換),避免主從延遲導(dǎo)致的切換異常;定期監(jiān)控主從延遲與 MyCat 連接池狀態(tài)。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
mysql將bin-log日志文件轉(zhuǎn)為sql文件的方法
這篇文章主要介紹了mysql將bin-log日志文件轉(zhuǎn)為sql文件的方法,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-12-12
MySQ登錄提示ERROR 1045 (28000)錯誤的解決方法
這篇文章主要為大家詳細介紹了MySQ登錄提示ERROR 1045 (28000)錯誤的解決方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-07-07
虛擬主機MySQL數(shù)據(jù)庫的備份與還原的方法
虛擬主機MySQL數(shù)據(jù)庫的備份與還原的方法...2007-07-07
MYSQL加密和壓縮函數(shù)詳解以及實戰(zhàn)(附示例)
這篇文章主要給大家介紹了關(guān)于MYSQL加密和壓縮函數(shù)詳解以及實戰(zhàn)的相關(guān)資料,加密函數(shù)主要用來對數(shù)據(jù)進行加密和界面處理,以保證某些重要數(shù)據(jù)不被別人獲取,文中通過代碼介紹的非常詳細,需要的朋友可以參考下2023-12-12
Linux下實現(xiàn)MySQL數(shù)據(jù)備份和恢復(fù)的命令使用全攻略
這篇文章主要介紹了Linux下實現(xiàn)MySQL數(shù)據(jù)備份和恢復(fù)的命令使用全攻略,包括使用Mysqldump和LVM快照以及xtrabackup三種方法,傾力推薦!需要的朋友可以參考下2015-11-11

