haha,首先這不是一篇入門Mycat的部落格但小編感覺又很入門的部落格!這篇部落格主要講解Mycat中資料分片的相關知識,同時小編將會在本機資料庫上進行測試驗證,圖文並茂展示出來。
資料庫分割槽分表,咋一聽非常地高大上,總有一種高高在上,望塵莫及的感覺,但小編想說的是,其實,作為一個開發人員,該來的總是會來,該學的東西你還是得學,區別只是時間先後順序的問題。
一、分割槽分表
分割槽就是把一個資料表的檔案和索引分散儲存在不同的物理檔案中,和分片的區別在於分割槽作用在單臺物理主機單個資料庫。
mysql支援的分割槽型別包括Range、List、Hash、Key,其中Range比較常用:
RANGE分割槽:基於屬於一個給定連續區間的列值,把多行分配給分割槽。
LIST分割槽:類似於按RANGE分割槽,區別在於LIST分割槽是基於列值匹配一個離散值集合中的某個值來進行選擇。
HASH分割槽:基於使用者定義的表示式的返回值來進行選擇的分割槽,該表示式使用將要插入到表中的這些行的列值進行計算。這個函式可以包含MySQL 中有效的、產生非負整數值的任何表示式。
KEY分割槽:類似於按HASH分割槽,區別在於KEY分割槽只支援計算一列或多列,且MySQL伺服器提供其自身的雜湊函式。必須有一列或多列包含整數值。
分表是指在邏輯上將一個表拆分成多個邏輯表,在整體上看是一張表,分表有水平拆分和垂直拆分兩種,舉個例子,將一張大的儲存商戶資訊的表按照商戶號的範圍進行分表,將不同範圍的記錄分佈到不同的表中。
二、Mycat 資料分片Sharding的種類
Mycat 的分片其實和分表差不多意思,就是當資料庫過於龐大,尤其是寫入過於頻繁且很難由一臺主機支撐時,這時資料庫就會面臨瓶頸。我們將存放在同一個資料庫例項中的資料分散存放到多個資料庫例項(主機)上,進行多臺裝置存取以提高效能,在切分資料的同時可以提高系統的整體性。
資料分片是指將資料全域性地劃分為相關的邏輯片段,有水平切分、垂直切分、混合切分三種型別,下面主要講下Mycat的水平和垂直切分。有一點很重要,那就是Mycat是分散式的,因此分出來的資料片分佈到不同的物理機上是正常的,靠網路通訊進行協作。
水平切分
就是按照某個欄位的某種規則分散到多個節點庫中,每個節點中包含一部分資料。可以將資料水平切分簡單理解為按照資料行進行切分,就是將表中的某些行切分到一個節點,將另外某些行切分到其他節點,從分散式的整體來看它們是一個整體的表。
垂直切分
一個資料庫由很多表構成,每個表對應不同的業務,垂直切分是指按照業務將表進行分類並分不到不同的節點上。垂直拆分簡單明瞭,拆分規則明確,應用程式模組清晰、明確、容易整合,但是某個表的資料量達到一定程度後擴充套件起來比較困難。
混合切分
為水平切分和垂直切分的結合。
三、Mycat 垂直切分、水平切分實戰
1、垂直切分
上面說到,垂直切分主要是根據具體業務來進行拆分的,那麼,我們可以想象這麼一個場景,假設我們有一個非常大的電商系統,那麼我們需要將訂單表、流水錶、使用者表、使用者評論表等分別分不到不同的資料庫中來提高吞吐量,架構圖大概如下:
由於小編是在一臺機器上測試,因此就只有host1這個節點,但不同的表還是依舊對應不同的資料庫,只不過是所有資料庫屬於同一個資料庫例項(主機)而已,後期不同主機只需增加<dataHost>
節點即可。
mycat配置檔案如下:
server.xml
<user name="root">
<property name="password">root</property>
// 對應四個邏輯庫
<property name="schemas">order,trade,user,comment</property>
</user>
複製程式碼
schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<!-- 4個邏輯庫,對應4個不同的分片節點 -->
<schema name="order" checkSQLschema="false" sqlMaxLimit="100" dataNode="database1" />
<schema name="trade" checkSQLschema="false" sqlMaxLimit="100" dataNode="database2" />
<schema name="user" checkSQLschema="false" sqlMaxLimit="100" dataNode="database3" />
<schema name="comment" checkSQLschema="false" sqlMaxLimit="100" dataNode="database4" />
<!-- 四個分片,對應四個不同的資料庫 -->
<dataNode name="database1" dataHost="localhost1" database="database1" />
<dataNode name="database2" dataHost="localhost1" database="database2" />
<dataNode name="database3" dataHost="localhost1" database="database3" />
<dataNode name="database4" dataHost="localhost1" database="database4" />
<!-- 實際物理主機,只有這一臺 -->
<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="hostM1" url="localhost:3306" user="root"
password="root">
</writeHost>
</dataHost>
</mycat:schema>
複製程式碼
登陸本機mysql,建立order,trade,user,comment
4個資料庫:
create database database1 character set utf8;
create database database2 character set utf8;
create database database3 character set utf8;
create database database4 character set utf8;
複製程式碼
執行bin
目錄下的startup_nowrap.bat
檔案,如果輸出下面內容,則說明已經啟動mycat成功,如果沒有,請檢查order,trade,user,comment
4個資料庫是否已經建立。
採用下面語句登陸Mycat伺服器:
mysql -uroot -proot -P8066 -h127.0.0.1
在comment
資料庫中建立Comment
表,並插入一條資料
上圖1處新建一個Comment
表,2處插入一條記錄,3處檢視記錄插入到哪個資料節點中,即database4
。
2、水平切分
server.xml
<user name="root">
<property name="password">root</property>
<property name="schemas">TESTDB</property>
</user>
複製程式碼
schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
<table name="travelrecord" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" />
</schema>
<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>
<!-- can have multi write hosts -->
<writeHost host="hostM1" url="localhost:3306" user="root"
password="root">
</writeHost>
</dataHost>
</mycat:schema>
複製程式碼
rule.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:rule SYSTEM "rule.dtd">
<mycat:rule xmlns:mycat="http://io.mycat/">
<tableRule name="auto-sharding-long">
<rule>
<columns>id</columns>
<algorithm>rang-long</algorithm>
</rule>
</tableRule>
<function name="rang-long"
class="io.mycat.route.function.AutoPartitionByLong">
<property name="mapFile">autopartition-long.txt</property>
</function>
</mycat:rule>
複製程式碼
conf
目錄下的autopartition-long.txt
# range start-end ,data node index
# K=1000,M=10000.
0-500M=0
500M-1000M=1
1000M-1500M=2
複製程式碼
上面的配置建立了一個名為TESTDB
的邏輯庫,並指定了需要切分的表<table>
標籤,表名為travelrecord
,分割槽的策略採用rang-long
演算法,即根據id
資料列值的範圍進行切分,具體的規則在autopartition-long.txt
檔案中定義,即id
在0-500*10000
範圍內的記錄存放在db1
的travelrecord
表中,id
在500*10000 - 1000*10000
範圍內的記錄存放在db2
資料庫的travelrecord
表中,下面我們插入兩條資料,驗證是否和分片規則一致。
建立db1,db2,db3
資料庫
create database db1 character set utf8;
create database db2 character set utf8;
create database db3 character set utf8;
複製程式碼
登陸Mycat伺服器
mysql -uroot -proot -P8066 -h127.0.0.1
建立travelrecord
表並插入id
等於1,id
等於5000010兩條記錄
建立資料表後,資料庫結構如下:
插入兩條記錄:
可以看到,id
等於1的記錄被插入到db1
中,id
等於5000010的記錄被插入到db2
中,那麼資料庫是否真的是這樣呢?
確實是這樣的,到此我們就完成了mycat資料庫的水平切分,這個例子只是演示按照id列值得範圍進行切分,mycat還支援很多的分片演算法,如取模、一致性雜湊演算法、按日期分片演算法等等,大家可以看《分散式資料庫架構及企業實戰----基於Mycat中介軟體》這本書深入學習。