mycat實現獨寫分離,首先需要mysql配置好主從複製
MySQL主從複製:搭建流程
MyCAT讀寫分離和主從切換能做什麼?
在傳統項目爲了能快速實現業務系統,一般都採用三層架構(mvc),所有的模塊功能集成在一起,所有的數據都放在一個數據庫中,如圖所示:
當項目不斷髮展,用戶量不斷增加,單臺應用服務器已經無法承載系統要求(一個tomcat承受訪問能力有限),那麼就需要引入nginx做反響代理和負載均衡,對外一致提供服務,對內部署兩套系統,如下圖所示:
配置了nginx貌似解決了單應用部署的性能問題,但是隨着部署應用服務器越來越多,單臺數據庫服務無法承載業務需求,爲了緩解數據庫的壓力,可以在應用和數據庫之間搭建一層緩存,典型的NoSql服務redis用於做緩存,可以通過統計查詢記錄,緩存熱點數據從而減小數據庫訪問壓力,如下圖所示:
緩存只能緩解數據庫訪問壓力,攔截部分數據庫請求,隨着用戶量增加訪問進一步增長,不能根本解決問題,這個時候我們就必須對數據庫架構做出改變,通過mycat實現數據庫的讀寫分離和主從切換功能,如下圖所示:
Mycat實現Mysql主從複製,其中寫操作在master主節點上執行,包括insert,delete,update 語句操作;讀操作在slave節點上執行,只有select語句操作,其他操作均由主master的二進制文件決定;MyCat支持雙主多從等搭配,多主多從情況需要配置多個writeHost兄弟節點,多個readHost節點即可!
Mycat的架構其實很好理解,Mycat是數據庫代理中間件,Mycat後面就是物理數據庫。和Web服務器的Nginx類似。對於使用者來說,訪問的都是Mycat,不會接觸到後端的數據庫。如下案例是做一個主從、讀寫分離的示例。
服務器信息如下:
主機信息 ip地址 說明
itcast-01 192.168.79.130 裝載mysql5.7x版本,用於master主服務
itcast-02 192.168.79.131 裝載mysql5.7x版本,用於slave從服務
itcast-01 192.168.79.130 安裝mycat服務,版本1.4x
Mycat作爲主數據庫中間件,肯定是與代碼弱關聯的,所以代碼是不用修改的,使用Mycat後,連接數據庫是不變的,MyCAT默認端口是8066。連接方式和普通數據庫一樣,比如:jdbc:mysql://192.168.79.130:8066/database
mycat配置
配置讀寫分離的schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://org.opencloudb/">
<!--定義主從同步數據庫,mycat做讀寫分離,只能綁定一個dataNota-->
<schema name="KEVINDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="sync1">
</schema>
<!--邏輯節點配置 name節點名稱 dataHost節點主機(物理節點) database 節點數據庫(物理數據庫名) -->
<!--獨寫分離的dataNode database爲mysql配置主從同步指定的數據庫 kevin-->
<dataNode name="sync1" dataHost="sync01" database="kevin" />
<!--
Balance參數設置:
1. balance=“0”, 所有讀操作都發送到當前可用的writeHost上。
2. balance=“1”,所有讀操作都隨機的發送到readHost。
3. balance=“2”,所有讀操作都隨機的在writeHost、readhost上分發
WriteType參數設置:
1. writeType=“0”, 所有寫操作都發送到可用的writeHost上。
2. writeType=“1”,所有寫操作都隨機的發送到readHost。
3. writeType=“2”,所有寫操作都隨機的在writeHost、readhost分上發。
switchType 目前有三種選擇:
-1:表示不自動切換
1 :默認值,自動切換
2 :基於MySQL主從同步的狀態決定是否切換
“Mycat心跳檢查語句配置爲 show slave status ,dataHost 上定義兩個新屬性: switchType="2" 與slaveThreshold="100",此時意味着開啓MySQL主從複製狀態綁定的讀寫分離與切換機制。Mycat心跳機制通過檢測 show slave status 中的 "Seconds_Behind_Master", "Slave_IO_Running", "Slave_SQL_Running" 三個字段來確定當前主從同步的狀態以及Seconds_Behind_Master主從複製時延。“
-->
<!--配置獨寫分離的 數據庫配置 -->
<dataHost name="sync01" maxCon="1000" minCon="10" balance="1"
writeType="0" dbType="mysql" dbDriver="native" switchType="2" slaveThreshold="100">
<heartbeat>show slave status</heartbeat>
<!-- can have multi write hosts -->
<!-- itcast-01 -->
<writeHost host="hostM1" url="192.168.79.130:3306" user="root"
password="root123">
<!-- itcast-02 -->
<readHost host="hostS1" url="192.168.79.131:3306" user="root" password="root123"/>
</writeHost>
<!--備用master節點,當默認master宕機,會自動切換 -->
<writeHost host="hostM2" url="192.168.79.13x:3306" user="root"
password="root123"/>
</dataHost>
</mycat:schema>
schema.xml定義了MyCAT邏輯和物理邏輯信息如果對schema.xml配置標籤不瞭解,請看MyCAT安裝及配置說明
示例配置一主一從結構是最簡單的配置:
MyCat支持雙主多從,如果有N個主,那麼就配置N個writeHost兄弟節點;如果有M個從節點,那麼就配置M個readHost節點即可。
注:
- 需要注意mycat數據節點dataNode配置的database物理數據庫名,要與mysql主從複製中master服務配置my.cnf定義的同步數據庫一致.
- Mycat主從分離只是在讀的時候做了處理,寫入數據的時候,只會寫入到writehost,需要通過mysql的主從複製將數據複製到readhost!如果mysql主從複製沒有搭建好,那麼readhost將會沒有數據.
數據測試:
- 通過ip+8066端口連接mycat服務,會根據scheam.xml定義的scheam創建MyCAT邏輯庫KEVINDB
- 在itcast01數據庫手動創建kevin數據庫,itcast02數據庫會自動複製
- MyCAT邏輯庫KEVINDB創建表tb_kevin和數據會自動同步到itcast01,itcast02
查看MyCAT運行日誌:
tail -f mycat.log
02/26 10:39:52.053 INFO [Timer1] (AbstractConnection.java:452) -close connection,reason: idle ,ServerConnection [id=9, schema=MYCATDB, host=192.168.79.1, user=root,txIsolation=3, autocommit=true, schema=MYCATDB]
02/26 10:44:02.710 INFO [Timer0] (PhysicalDatasource.java:269) -create connections ,because idle connection not enough ,cur is 7, minCon is 10 for hostM1
02/26 10:44:02.717 INFO [$_NIOREACTOR-1-RW] (NewConnectionRespHandler.java:44) -connectionAcquired MySQLConnection [id=2536, lastTime=1582685042709, schema=db3, old shema=db3, borrowed=false, fromSlaveDB=false, threadId=10707, charset=latin1, txIsolation=0, autocommit=true, attachment=null, respHandler=null, host=192.168.79.131, port=3306, statusSync=null, writeQueue=0, modifiedSQLExecuted=false]
02/26 14:51:38.732 INFO [$_NIOREACTOR-2-RW] (FrontendAuthenticator.java:164) -ServerConnection [id=10, schema=null, host=192.168.79.1, user=root,txIsolation=3, autocommit=true, schema=null]'root' login success
02/26 14:52:59.512 INFO [$_NIOREACTOR-3-RW] (FrontendAuthenticator.java:164) -ServerConnection [id=11, schema=null, host=192.168.79.1, user=root,txIsolation=3, autocommit=true, schema=null]'root' login success
02/26 14:53:07.468 INFO [$_NIOREACTOR-0-RW] (FrontendAuthenticator.java:164) -ServerConnection [id=12, schema=null, host=192.168.79.1, user=root,txIsolation=3, autocommit=true, schema=null]'root' login success
02/26 14:53:07.860 INFO [$_NIOREACTOR-0-RW] (AbstractConnection.java:452) -close connection,reason:quit cmd ,ServerConnection [id=12, schema=KEVINDB, host=192.168.79.1, user=root,txIsolation=3, autocommit=true, schema=KEVINDB]
02/26 14:53:28.498 INFO [$_NIOREACTOR-1-RW] (FrontendAuthenticator.java:164) -ServerConnection [id=13, schema=null, host=192.168.79.1, user=root,txIsolation=3, autocommit=true, schema=null]'root' login success
02/26 14:53:28.611 INFO [$_NIOREACTOR-1-RW] (AbstractConnection.java:452) -close connection,reason:quit cmd ,ServerConnection [id=13, schema=KEVINDB, host=192.168.79.1, user=root,txIsolation=3, autocommit=true, schema=KEVINDB]
02/26 14:53:32.613 INFO [$_NIOREACTOR-2-RW] (FrontendAuthenticator.java:164) -ServerConnection [id=14, schema=null, host=192.168.79.1, user=root,txIsolation=3, autocommit=true, schema=null]'root' login success
02/26 15:22:06.370 WARN [$_NIOREACTOR-2-RW] (SingleNodeHandler.java:189) -execute sql err : errno:1054 Unknown column 'KEVINup' in 'field list' con:MySQLConnection [id=14, lastTime=1582701725697, schema=kevin, old shema=kevin, borrowed=true, fromSlaveDB=false, threadId=9306, charset=utf8, txIsolation=3, autocommit=true, attachment=sync1{update TB_KEVIN set KEVIN=KEVINup where id=5}, respHandler=SingleNodeHandler [node=sync1{update TB_KEVIN set KEVIN=KEVINup where id=5}, packetId=1], host=192.168.79.130, port=3306, statusSync=org.opencloudb.mysql.nio.MySQLConnection$StatusSync@7446fdae, writeQueue=0, modifiedSQLExecuted=true]
從日誌看出,select * …查詢通過192.168.79.131從機執行,update …修改語句通過192.168.79.130主機執行,從而實現的mycat讀寫分離!!!