讀寫分離,簡單地說是把對數據庫的讀和寫操作分開,以對應不同的數據庫服務器。主數據庫提供寫操作,從數據庫提供讀操作,這樣能有效地減輕單臺數據庫的壓力。主數據庫進行寫操作後,數據及時間同步到所讀的數據庫,儘可能保證讀、寫數據庫的數據一致,比如MySQL的主從複製、Oracle的DATA GUARD、SQL Server的複製訂閱等。在很多系統中,讀操作的比例遠高於寫操作,所以對應讀操作的數據庫可以有多臺,通過負載均衡技術進一步分攤讀操作的壓力,讓整個數據系統高效、平穩地運行。而這些讀寫分離所需的複雜的數據庫架構,要對開發人員和應用程序透明。我們通過Mycat即可輕易實現上述功能,不僅可以支持MySQL,也可以支持Oracle和SQL Server。
Mycat控制後臺數據庫的讀寫分離和負載均衡由schema.xml文件datahost標籤的balance屬性控制。負載均衡類型,目前的取值有如下的種:
l balance=”0”:不開啓讀寫分離機制,所有讀操作都發送到當前可用的writeHost上。
l balance=”1”:全部的readHost與standby writeHost都參與select語句的負載均衡,簡而言之,當爲雙主雙從模式(M1->S1,M2->S2,並且M1與M2互爲主備)時,在正常情況下,M1、S1和S2都參與select語句的負載均衡。
l balance=”2”:所有的讀操作都隨機地在writeHost、readHost上分發。
l balance=”3”:所有的讀請求都隨機分發到writeHost對應的readHost上執行,writeHost不負擔讀壓力,注意balance只在Mycat1.4及之後的版本中有。
下面將通過實例驗證並結合log來說明各種情況下的讀寫分離。
MySQL主從讀寫分離的準備環境見下表:
項目 | Mycat | MySQL-master | MySQL-slave |
IP | 11.112.0.123 | 11.112.0.10 | 11.112.0.51 |
Port | 8066/9066 | 3066 | 3066 |
MySQL爲一主一從,本文檔重在介紹Mycat的用法,關於MySQL主從配置請參考其他文檔。
實驗用例表如下:
create database yf; create table travelrecord( id int(11) not null auto_increment, org_code varchar(20) not null, test_name varchar(20) default null, primary key(id) ) engine=InnoDB default CHARSET=UTF8;
當balance爲0時,不開啓讀寫分離機制,所有讀操作都發送到當前的writeHost上。Mycat的基本配置如下:
<?xml version="1.0"?> <!DOCTYPE mycat:schema SYSTEM "schema.dtd"> <mycat:schema xmlns:mycat="http://io.mycat/"> <schema name="mycat01" checkSQLschema="false" sqlMaxLimit="100"> <table name="travelrecord" primaryKey="id" dataNode="mysql1" /> </schema> <dataNode name="mysql1" dataHost="mysql1" database="yf" /> <dataHost name="mysql1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> <writeHost host="mysql1" url="11.112.0.10:3306" user="root" password="root"> <readHost host="mysql2" url="11.112.0.51:3306" user="root" password="root" /> </writeHost> </dataHost> </mycat:schema>
登錄管理端口
mysql -uroot -p123456 -P9066 -hmycat1
查看datasource;
登錄數據端口
mysql -uroot -p123456 -P8066 -hmycat1
多次執行select * from travelrecord ;通過datasource可以看到所有讀操作都分發到了mysql1上:
從日誌中也可以看到讀操作分發到了mysql1(11.112.0.10)
當balance爲1時,所有讀操作都發送到了當前writeHost對應的readhost和備用的writehost,這樣就可以減輕主庫的壓力,高效地提供讀寫操作,而由其他服務器承擔比較耗費資源的讀操作。
修改schema.xml中的balance=”1”,並重新加載配置文件。
reload @@config_all;
多次執行select * from travelrecord ;通過datasource可以看到所有讀操作都分發到了mysql2上:
從日誌中也可以看到讀操作分發到了mysql2(11.112.0.51)
執行插入語句:insert into travelrecord (org_code,test_name) values('1000','test'); 通過datasource可以看到所有讀操作都分發到了mysql2上:
由於這裏只是一主一從,對於balance=3和4的情況無法更好的體現,感興趣的同學可以自行測試。
參考:《分佈式數據庫架構及企業實踐-基於Mycat中間件》