文章目錄
- 18.1 MySQL 讀寫分離概述
- 18.1.1 工作原理
- 18.1.2 為什么要讀寫分離
- 18.1.3 實現方式
- 18.2 什么是 MyCat
- 18.3 MyCat 安裝與配置
- 1. 下載與解壓
- 2. 創建用戶并修改權限
- 3. 目錄說明
- 4. Java 環境要求
- 18.4 MyCat 啟動與配置
- 1. 配置環境變量
- 2. 配置 hosts(多節點集群)
- 3. 配置 Mycat
- 3.1 配置 server
- 3.2 schema 配置
- 3.2.1 首先 備份
- 3.2.2 更改配置
- 4. 啟動 MyCat
- 在這里插入圖片描述
- 18.5 配置 MySQL 主從
- 1. 安裝 MySQL 5.7
- 2. 配置主庫(master)
- 3. 配置從庫(slave)
- 4. 測試讀寫分離
- 總結
18.1 MySQL 讀寫分離概述
18.1.1 工作原理
- 主庫負責寫操作:
INSERT
、UPDATE
、DELETE
- 從庫負責讀操作:
SELECT
- 主從復制保證從庫數據與主庫同步
- 數據內部交換過程:主庫寫入 → 二進制日志 → 從庫同步
18.1.2 為什么要讀寫分離
- 單臺服務器性能瓶頸,需分擔負載
- 主從分工,緩解鎖爭用(X鎖和S鎖)
- 從庫可使用 MyISAM,提高查詢性能
- 增加冗余,提高可用性
18.1.3 實現方式
- 應用程序層實現
- 優點:易部署,對訪問壓力中等的系統性能良好
- 缺點:代碼耦合、難以支持高級功能、大型系統不適用
- 中間件層實現
- 優點:架構靈活、透明化分庫分表、可做 failover 和監控
- 常用中間件:
- Cobar:阿里B2B的分布式系統,已停更
- MyCat:Cobar二次開發,社區活躍
- OneProxy:商業收費,高并發穩定
- Vitess:YouTube使用,架構復雜
- Kingshard、Atlas、MaxScale、MySQL Router等
18.2 什么是 MyCat
- 開源企業級數據庫中間件
- 支持事務、ACID
- 替代 MySQL 集群或 Oracle 集群
- 融合內存緩存、NoSQL、大數據技術(HDFS)
- 可視為企業級數據庫中間件,實現分庫分表、讀寫分離
18.3 MyCat 安裝與配置
1. 下載與解壓
#官方網站
http://www.mycat.org.cn/
#github
https://github.com/MyCATApache/Mycat-download下載地址
wget https://github.com/MyCATApache/Mycat-download/blob/master/1.6-RELEASE/Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gztar -xf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz -C /usr/local/
cd /usr/local/mycat
2. 創建用戶并修改權限
useradd mycat
passwd mycat
chown -R mycat.mycat /usr/local/mycat
3. 目錄說明
bin/
:可執行文件和 shell 腳本conf/
:配置文件server.xml
:服務器參數、用戶授權schema.xml
:邏輯庫和數據分片配置rule.xml
:分片規則
lib/
:依賴 JAR 文件logs/
:日志文件(配置在log4j.xml
)
4. Java 環境要求
- JDK 1.7 及以上(可做可不做)
tar xf jdk-8u191-linux-x64.tar.gz -C /usr/java/
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
java -version
18.4 MyCat 啟動與配置
1. 配置環境變量
vim /etc/profile.d/mycat.sh
#!/bin/bash
export MYCAT_HOME=/usr/local/mycat
export PATH=$MYCAT_HOME/bin:$PATH
source /etc/profile.d/mycat.sh
2. 配置 hosts(多節點集群)
這里使用的是上一篇博文的主從mysql
192.168.10.14 slave1
192.168.10.15 slave2
192.168.10.16 master
3. 配置 Mycat
cp /usr/local/mycat/conf/server.xml /usr/local/mycat/conf/server.xml.bakvim /usr/local/mycat/conf/server.xml
3.1 配置 server
后邊標1的都是需要重點關注需要更改,ha為自己的邏輯庫,可以自擬
<user name="mycat"> 1<property name="password">123456</property> 1<property name="schemas">ha</property> 1<!-- 表級 DML 權限設置 --><!-- <privileges check="false"><schema name="TESTDB" dml="0110" ><table name="tb01" dml="0000"></table><table name="tb02" dml="1111"></table></schema></privileges> --></user><user name="user"><property name="password">user</property><property name="schemas">ha</property> 1<property name="readOnly">true</property></user>
3.2 schema 配置
3.2.1 首先 備份
cp /usr/local/mycat/conf/schema.xml /usr/local/mycat/conf/schema.xml.bak
3.2.2 更改配置
#直接復制
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://org.opencloudb/">
<schema name="ha" checkSQLschema="false" sqlMaxLimit="100" dataNode='dn1'>
</schema>
<dataNode name="dn1" dataHost="dthost" database="ha"/>
<dataHost name="dthost" maxCon="500" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType=" -1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="master" url="192.168.10.16:3306" user="mycat" password="123456">
</writeHost>
<writeHost host="slave1" url="192.168.10.14:3306" user="mycat" password="123456" />
</dataHost>
</mycat:schema>==============================================================================
使用這個即可,直接刪除復制粘貼<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/"><!-- 定義邏輯庫 schema --><schema name="ha" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1"></schema><!-- 數據節點 --><dataNode name="dn1" dataHost="dthost" database="ha"/><!-- 數據主機組 --><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.10.16:3306" user="mycat" password="123456"><!-- 從庫 (讀) --><readHost host="slave1" url="192.168.10.14:3306" user="mycat" password="123456"/><readHost host="slave2" url="192.168.10.15:3306" user="mycat" password="123456"/></writeHost></dataHost>
</mycat:schema>
① 重要參數說明:
上文中的兩個ha不是一個東西,第一個ha是自己擬定的邏輯庫名,后面那個才是mysql數據庫集群中的真實數據庫名。
-
balance
:讀負載均衡方式(0-3)負載均衡類型,目前的取值有 4 種: 1.balance="0", 不開啟讀寫分離機制,所有讀操作都發送到當前可用的 writeHost 上;2.balance="1",全部的 readHost 與stand by writeHost 參與 select 語句的負載均衡,簡單的說,當 雙主雙從模式(M1->S1,M2->S2,并且 M1 與 M2 互為主備),正常情況下,M2、S1、S2 都參與 select 語句的負載均衡;3.balance="2",所有讀操作都隨機的在 writeHost、readhost 上分發;4.balance="3",所有讀請求隨機的分發到 wiriterHost 對應的readhost 執行,writerHost 不負擔讀壓力。注意:writerHost 不負擔讀壓writeType
-
switchType
:寫節點切換策略(-1表示不自動切換)switchType 指的是切換的模式,目前的取值也有 4 種:1.switchType='-1' 表示不自動切換;2.switchType='1' 默認值,表示自動切換;3.switchType='2' 基于MySQL 主從同步的狀態決定是否切換,心跳語句為 show slave status;4.switchType='3'基于 MySQL galary cluster 的切換機制(適合集群)(1.4.1),心跳語句為 show status like 'wsrep%'。
-
writeType
:寫節點策略(0表示主寫,掛了切換到備)1、writeType=”0”, 所有寫操作發送到配置的第一個 writeHost,第一個掛了切到還生存的第二個 writeHost,重新啟動后已切換后的為準,切換記錄在配置文件中:dnindex.properties . 2、writeType=”1”,所有寫操作都隨機的發送到配置的 writeHost,1.5 以后廢棄不推薦。默認 0 就好了!
② 參數說明:
-
Mycat schema 配置的 XML 根節點
<mycat:schema xmlns:mycat="http://org.opencloudb/">
-
schema 節點
<schema name="ha" checkSQLschema="false" sqlMaxLimit="100" dataNode='dn1'> </schema># name="ha":定義 schema 名稱為 ha,客戶端通過 use ha 來訪問。 ## checkSQLschema="false":關閉 SQL schema 檢查,加快解析。 ### sqlMaxLimit="100":單條 SQL 返回最大 100 行。 #### dataNode='dn1':指定使用的數據節點為 dn1。
-
dataNode 節點
<dataNode name="dn1" dataHost="dthost" database="ha"/>#name="dn1":定義數據節點的名字,這個名字需要是唯一的。##dataHost="dthost":綁定到名為 dthost 的 dataHost。 (該屬性用于定義該分片屬于哪個數據庫實例)###database="ha":訪問的物理數據庫名為 ha。 (該屬性用于定義該分片屬性哪個具體數據庫實例上的具體庫)
-
dataHost 節點
<dataHost name="dthost" maxCon="500" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="-1" slaveThreshold="100">maxCon / minCon:連接池最大/最小連接數。balance="1":負載均衡策略,1 表示輪詢。writeType="0":寫策略,只寫到第一個可用節點。dbType="mysql":數據庫類型 MySQL。dbDriver="native":使用原生驅動。switchType="-1":切換策略,-1 表示自動。slaveThreshold="100":從庫延遲閾值(行數或毫秒,取決于版本)
-
心跳檢測
<heartbeat>select user()</heartbeat> #用來檢測數據庫連接是否活躍
-
writeHost 節點
<writeHost host="slave1" url="192.168.10.14:3306" user="mycat" password="123456"/> <writeHost host="slave2" url="192.168.10.15:3306" user="mycat" password="123456"/>配置兩個寫節點(主庫)。writeType="0" 表示只寫第一個 writeHost(slave1)。第二個 writeHost 在此配置下不會被寫入使用。
數據流向 schema → dataNode → dataHost → writeHost 的結構,
4. 啟動 MyCat
cd /usr/local/mycat/bin
./mycat start
cat /usr/local/mycat/logs/wrapper.log
18.5 配置 MySQL 主從
1. 安裝 MySQL 5.7
mysql -umycat -p123456 -h127.0.0.1 -P8066
2. 配置主庫(master)
# /etc/my.cnf
validate-password=OFF
server-id=1
log-bin=mysql-bin-master
binlog-do-db=ha
binlog-ignore-db=mysql
配完要重啟數據庫,但是重啟會導致主從數據有問題
mysql> create database ha;
mysql> use ha;
mysql> create table test(id int, name varchar(20));
mysql> insert into test values(1,'man');
mysql> grant all privileges on *.* to 'mycat'@'%' identified by '123456';
mysql> flush privileges;================================================
簡易版 可直接使用這個mysql> grant all privileges on *.* to 'mycat'@'%' identified by '123456';
mysql> flush privileges;
mysql> create database ha;
mysql> use ha;
mysql> create table test(id int, name varchar(20));
3. 配置從庫(slave)
# /etc/my.cnf
server-id=2
validate-password=OFF
mysql> grant all on *.* to mycat@'%' identified by '123456';
mysql> stop slave;
mysql> change master to master_host='192.168.10.14', master_user='slave', master_password='123456';
mysql> start slave;
mysql> show slave status\G# /etc/my.cnf
server-id=3
validate-password=OFF
mysql> grant all on *.* to mycat@'%' identified by '123456';
mysql> stop slave;
mysql> change master to master_host='192.168.10.15', master_user='slave', master_password='123456';
mysql> start slave;
mysql> show slave status\G之前配了主從就不用配主從了!只需要grant加權限就行了!!!只需要
mysql> grant all privileges on *.* to 'mycat'@'%' identified by '123456';
mysql> flush privileges;
4. 測試讀寫分離
#先安裝數據庫
yum install -y mariadb-server mariadb
systemctl start mariadb.service
在客戶端服務器上測試
mysql -u mycat -p123456 -h 192.168.10.80 -P8066
//通過mycat服務器代理訪問mysql ,在通過客戶端連接mysql后寫入的數據只有主服務會記錄,然后同步給從--從服務器在主服務器上:
create database ha;
use ha;
create table test (id int(10),name varchar(10),address varchar(20));在兩臺從服務器上:
stop slave; #關閉同步
use ha;
//在slave1上:
insert into test values('1','zhangsan','this_is_slave1');//在slave2上:
insert into test values('2','lisi','this_is_slave2');//在主服務器上:
insert into test values('3','wangwu','this_is_master');//在客戶端服務器上:
use ha;(這里是邏輯庫,然后邏輯庫區調用的真實庫ha)
select * from test; //客戶端會分別向slave1和slave2讀取數據,顯示的只有在兩個從服務器上添加的數據,沒有在主服務器上添加的數據
重復兩遍查詢可以看到slave1和slave2進行輪詢查詢,沒有master出現,符合讀寫分離
insert into test values('4','qianqi','this_is_client'); //只有主服務器上有此數據//在兩個從服務器上執行 start slave; 即可實現同步在主服務器上添加的數據
start slave;
select * from test; 然后再進行查詢,發現是134,234進行輪詢,實驗成功
如果只能查到134或者234,檢查四個虛擬機的防火墻和selinux
這里按理說應該使用第五臺虛擬機當客戶端進行測試,但是這里用的是mycat服務端兼客戶端,所以ip直接寫的80即本機ip,本質上就是客戶端—》mycat-----》mysql集群,mycat之所以可以使用mysql命令是因為兼容協議,可以吧自己偽裝成mysql,然后查詢進入mycat,由mycat進行調度。
總結
mycat配置的核心就是server.xml和schema.xml,server中是配置的mycat這個服務的全局配置,也就是說客戶端使用登陸的mycat用戶名和密碼(不是數據庫中的用戶名和密碼!),schema中的是對邏輯庫和物理庫的映射等配置,在那里面是真實對應的數據庫用戶和密碼。