【分布式架構(gòu)初探】
第五節(jié)-貓從哪里來,要到哪里去(Mycat的前世今生)
5.1 MyCAT貓的前世
5.2 MyCAT貓的今生
5.3 十分鐘安裝使用
5.4 MYCAT下實(shí)現(xiàn)讀寫分離
5.5 切!切!切!MyCAT中分表分庫策略
5.6 MyCAT的五臟六腑
5.7 課后作業(yè)
5.1 MyCAT貓的前世###
最近貓為什么這么火,Apache的貓,MyCAT的貓。
差不多都長這個(gè)樣

MyCAT原來本沒有想著來生做貓的,因?yàn)樗那笆朗前⒗锏腃obar,
轉(zhuǎn)世之后,成為了MyCAT,并且開源了,就立志做一個(gè)中國的Apache貓.
說道他的前世是阿里的Cobar, Cobar的作者離職了以后,Cobar就幾乎沒有進(jìn)行后續(xù)開發(fā)和維護(hù)了,
后來轉(zhuǎn)為開源的MyCAT,又進(jìn)行了迅速的發(fā)展,現(xiàn)在初步統(tǒng)計(jì)有超過300個(gè)項(xiàng)目使用mycat,其中包括:
中國電信/中國聯(lián)通/蒲公英傳媒/天獅集團(tuán)等等

為什么有這么多的知名公司使用mycat 呢, 我們看看他們的業(yè)務(wù)量,
1.安智賬戶系統(tǒng), 數(shù)據(jù)量單表6000萬條,20多張表,上億條數(shù)據(jù), 系統(tǒng)運(yùn)行良好,偶爾有SQL操作遲緩的現(xiàn)象。
2.公安項(xiàng)目,20個(gè)表,30多億條數(shù)據(jù),選取適合的業(yè)務(wù)使用mycat
從這些項(xiàng)目中我們可以看出,mycat擅長對上億條單表數(shù)據(jù)量的處理,并提供良好的實(shí)時(shí)查詢服務(wù)。
而我們知道,MYSQL的庫中很難處理上億條數(shù)據(jù)的查詢工作,MYCAT提高了MYSQL數(shù)據(jù)庫的處理能力,
從官方的解釋來看,MYCAT適合處理千億條以下的數(shù)據(jù),千億條以上的數(shù)據(jù)更適合HADOOP這些系統(tǒng)來處理。
說了半天,什么是MYCAT呢?
MYCAT就是一個(gè)虛擬的MYSQL SERVER, 這么說可能不太理解, 但是對于應(yīng)用來說,他就是一個(gè)MYSQL SERVER,
應(yīng)用就像連接普通的MYSQL數(shù)據(jù)庫一樣的 去連接他,SQL查詢、操作等等一模一樣。
而MYCAT把數(shù)據(jù)庫復(fù)雜的架構(gòu),以及背后復(fù)雜的分表分庫的邏輯全部透明化了,MYCAT中間件連接多個(gè)MYSQL數(shù)據(jù)庫,
多個(gè)數(shù)據(jù)庫之間還可以做主從同步,而這一切的一切,對應(yīng)用來說,只有一個(gè)數(shù)據(jù)庫,那就是MYCAT。
5.2 MyCAT貓的今生###
MYCAT發(fā)展到現(xiàn)在已經(jīng)不僅僅是MYSQL的代理了,它還支持SQLSERVER/ORACLE/DB2/POSTGRESQL等主流數(shù)據(jù)庫。
MYCAT還可以將一個(gè)表定義為任何一種MYCAT支持的存儲方式,比如MySQL的MyISAM 表、內(nèi)存表、或者M(jìn)ongDB這種
內(nèi)存數(shù)據(jù)庫上。
MYCAT這么強(qiáng)大,那么他的原理是不是特別的復(fù)雜,非也,Mycat 的原理可以用一個(gè)動(dòng)詞來形容:”攔截“
它攔截應(yīng)用發(fā)送過來的SQL, 并對SQL語句進(jìn)行一些特定的分析:分片分析、路由分析、讀寫分離分析、緩存分析等,然后將
分析后的SQL分別發(fā)送到不同的真實(shí)數(shù)據(jù)庫,最后對數(shù)據(jù)庫返回的結(jié)果進(jìn)行處理,返回給用戶。

下面列舉幾個(gè)MYCAT 典型的應(yīng)用場景:
- 單純的讀寫分離,在下面我們會有講解如何進(jìn)行Mycat下面的讀寫分離的配置
- 分表分庫,對于超過1000萬的表進(jìn)行分片,最大支持1000億的單表分片
- 多租戶應(yīng)用,每個(gè)應(yīng)用一個(gè)庫,但應(yīng)用程序只連接MYCAT ,從而不改變程序本身,實(shí)現(xiàn)多租戶
- 報(bào)表系統(tǒng),借助于MYCAT的分表能力,處理大規(guī)模報(bào)表的統(tǒng)計(jì)
- 替代HBase, 分析大數(shù)據(jù)
- 作為海量數(shù)據(jù)實(shí)時(shí)查詢的一種簡單有效的解決方案, 比如100億條數(shù)據(jù)需要在3秒內(nèi)實(shí)時(shí)查詢出來,此時(shí)可以考慮MYCAT
現(xiàn)在MYCAT社區(qū)活躍,MYCAT 周邊的系統(tǒng)也慢慢衍生出來,慢慢的形成了MYCAT生態(tài)圈了,像MYCAT-WEB 監(jiān)控,MYCAT-HA
高可用方案等等,所以MYCAT還是很值得我們學(xué)習(xí)和研究的。
5.3 十分鐘安裝使用###
MYCAT雖然強(qiáng)大,但是他的安裝卻十分簡單, 下面我們進(jìn)入我們十分鐘安裝教程:
1.下載MYCAT安裝包####
在GitHub 的 MyCATApache項(xiàng)目下,我們找到
https://github.com/MyCATApache/Mycat-download/tree/master/1.5-RELEASE
選取 Mycat-server-1.5.1-RELEASE-20160929233042-linux.tar.gz
linux 版本進(jìn)行 下載
目前1.6版本部分功能還在開發(fā)中,1.5版本比較穩(wěn)定,建議下載1.5用于生產(chǎn)環(huán)境使用
2. 解壓運(yùn)行MYCAT安裝包####
下載文件是一個(gè)tar的linux壓縮包,用解壓命令
tar -zxvf Mycat-server-1.5.1-RELEASE-20160929233042-linux.tar.gz

啟動(dòng)命令
./mycat start|restart|stop|console 常用幾項(xiàng)內(nèi)容

日志文件
logs/wrapper.log mycat服務(wù)器日志
logs/mycat.log 數(shù)據(jù)庫操作日志,分析數(shù)據(jù)庫操作路由使用。
啟動(dòng)MyCat最主要的幾個(gè)配置文件:
conf/server.xml 服務(wù)器用戶、虛擬Sechma、端口等配置信息。
conf/sechma.xml 物理數(shù)據(jù)庫映射。
使用MyCAT來說的話,最主要的就是修改這兩個(gè)文件,接下來我們實(shí)現(xiàn)MYCAT下的讀寫分離。
5.4 MYCAT下實(shí)現(xiàn)讀寫分離###
首先參考上一節(jié)MYSQL配置主從復(fù)制,配置好主從數(shù)據(jù)庫之間的數(shù)據(jù)復(fù)制功能。
1.登錄主服務(wù)器的mysql,查詢master的狀態(tài)####
mysql> show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000010 | 106 | db1,db2,db3 | mysql |
+------------------+----------+--------------+------------------+
Master 重啟后會修改mysql-bin(序號加1)
2.查看Slave機(jī)有沒有配置成功:####
mysql> show slave status\G
以下兩個(gè)參數(shù)必須為YES:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
3.MyCAT的配置####
不使用Mycat托管的 MySQL主從服務(wù)器
schema.xml
<dataNode name="dn1" dataHost="localhost1" database="db1" />
<dataNode name="dn2" dataHost="localhost1" database="db2" />
<dataNode name="dn3" dataHost="localhost1" database="db3" />
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM" url="172.19.4.239:3306" user="root" password="123456"></writeHost>
</dataHost>
支持MySQL主從復(fù)制狀態(tài)綁定的讀寫分離機(jī)制,讓讀更加安全可靠,配置如下
<dataNode name="dn1" dataHost="localhost1" database="db1" />
<dataNode name="dn2" dataHost="localhost1" database="db2" />
<dataNode name="dn3" dataHost="localhost1" database="db3" />
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"
writeType="0" dbType="mysql" dbDriver="native" switchType="2" slaveThreshold="100">
<heartbeat>show slave status</heartbeat>
<writeHost host="hostM" url="172.19.4.239:3306" user="root" password="123456">
<readHost host="hostS" url="172.19.4.240:3306" user="root" password="123456" />
</writeHost>
</dataHost>
設(shè)置 balance="1"與writeType="0"
Balance參數(shù)設(shè)置:
- balance=“0”, 所有讀操作都發(fā)送到當(dāng)前可用的writeHost上。
- balance=“1”,所有讀操作都隨機(jī)的發(fā)送到readHost。
- balance=“2”,所有讀操作都隨機(jī)的在writeHost、readhost上分發(fā)
WriteType參數(shù)設(shè)置:
- writeType=“0”, 所有寫操作都發(fā)送到可用的writeHost上。
- writeType=“1”,所有寫操作都隨機(jī)的發(fā)送到readHost。
- writeType=“2”,所有寫操作都隨機(jī)的在writeHost、readhost分上發(fā)。
這樣配置了以后,就已經(jīng)實(shí)現(xiàn)了讀寫分離的功能, 還可以對數(shù)據(jù)庫進(jìn)行負(fù)載均衡
啟動(dòng)mycat , 用應(yīng)用或者Navicat等工具 連接mycat ,端口是 8066
insert , select 進(jìn)行測試。
5.5 切!切!切!MyCAT中分表分庫策略###
上面只是實(shí)現(xiàn)了如何進(jìn)行讀寫分離,基于數(shù)據(jù)庫的主從同步復(fù)制的原理, 我們在之前的課程里已經(jīng)知道,
主從同步復(fù)制的數(shù)據(jù)是 ,保證從數(shù)據(jù)庫和主庫的數(shù)據(jù)一模一樣,也就是說數(shù)據(jù)是多復(fù)制了一份出來,
而MYCAT 只所以能支持上百億的數(shù)據(jù)量,在于他的另一個(gè)功能:分表分庫策略
分表分庫簡單來說,就是MYCAT 下面連接的數(shù)據(jù)庫節(jié)點(diǎn),打比方說有dn1,dn2,dn3, 他們每個(gè)庫中的數(shù)據(jù)
是各不相同的。
把MYCAT當(dāng)做一個(gè)虛擬數(shù)據(jù)庫來看,travelrecord 是MYCAT下面建的一張表, 應(yīng)用調(diào)用MYCAT
庫可以調(diào)用到整張表的數(shù)據(jù), 但是如果查詢某一個(gè)節(jié)點(diǎn)dn1 , 則只能查詢到一部分?jǐn)?shù)據(jù)(通常是1/3)的數(shù)據(jù)
dn1, dn2 , dn3 各自存儲了一部分的數(shù)據(jù), 但是可以通過MYCAT 來查詢到整張表的數(shù)據(jù),
這樣增強(qiáng)了每個(gè)數(shù)據(jù)庫的數(shù)據(jù)存儲處理能力, 這就是MYCAT的高明之處,也就是為什么他能夠處理上百億條數(shù)據(jù)的奧妙。
這里列出一個(gè)簡單的分表分庫的配置:
schema.xml
<table name="travelrecord" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" />
在schema中 我們需要配置mycat 中的虛擬表table ,以及他的rule ,分表規(guī)則
auto-sharding-long 的意思是 事先已經(jīng)定義好每個(gè)dn的 范圍,根據(jù)范圍劃分,這個(gè)規(guī)則在rule.xml中進(jìn)行配置.
datanode 的配置:
<dataNode name="dn1" dataHost="localhost1" database="db1" />
<dataNode name="dn2" dataHost="localhost2" database="db2" />
<dataNode name="dn3" dataHost="localhost3" database="db3" />
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- can have multi write hosts -->
<writeHost host="hostM1" url="172.19.4.3:3306" user="root" password="123456"></writeHost>
</dataHost>
<dataHost name="localhost2" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- can have multi write hosts -->
<writeHost host="hostM2" url="172.19.4.201:3306" user="root" password="123456"></writeHost>
</dataHost>
<dataHost name="localhost3" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- can have multi write hosts -->
<writeHost host="hostM2" url="172.19.4.86:3306" user="root" password="123456"></writeHost>
</dataHost>
這樣數(shù)據(jù)就是自動(dòng)切分到這3個(gè)不同的datanode中了, select 取出來也是完整的數(shù)據(jù)。
分表分庫還有一點(diǎn)竅門就是,你的數(shù)據(jù)是縱向來切,還是橫向來切,
上面講的那個(gè)是 橫向來切:就是把一張表的數(shù)據(jù) 切到不同的 數(shù)據(jù)庫中。
縱向切更簡單,就是以表來分庫, 不同的表 放到不同的庫中, 表中的數(shù)據(jù)在某個(gè)庫中是完整的。
5.6 MyCAT的五臟六腑###
學(xué)會了MYCAT來做讀寫分離和分表分庫的使用以后,我們應(yīng)該更深入MYCAT的五臟六腑,了解MYCAT的運(yùn)行機(jī)制,這樣對線上的應(yīng)用處理一些
應(yīng)急事故,以及解決一些問題提供思路,非常的有幫助,有能力的童鞋還可以參與到MYCAT的后續(xù)開發(fā)中來。

MYCAT 的后端通信采用了NIO非阻塞 和AIO 異步通信方式, 使得通信效率更高
SQL解析這一塊用到了阿里的Druid進(jìn)行解析
協(xié)議這一塊,對于MYSQL數(shù)據(jù)庫采用原生的二進(jìn)制協(xié)議,還支持驅(qū)動(dòng)方式的連接
并且MYCAT還增加order by , group by ,limit 等聚合功能的支持
有興趣的童鞋可以對 MYCAT線程池、網(wǎng)絡(luò)通信、路由分發(fā)、事務(wù)管理、緩存等模塊做輸入的學(xué)習(xí)和分析。
5.7 課后作業(yè)###
- 用MYCAT 實(shí)現(xiàn)上一節(jié)中的 讀寫分離案例
- 用MYCAT 實(shí)現(xiàn)一個(gè)分表分庫的應(yīng)用
更多課程關(guān)注公眾號【小張網(wǎng)?!?br> 公眾號里有微信群加入交流,有大牛親自指導(dǎo)實(shí)戰(zhàn)!
