-
如今隨著網際網路的發展,資料的量級也是撐指數的增長,從GB到TB到PB。對資料的各種操作也是愈加的困難,傳統的關係性資料庫已經無法滿足快速查詢與插入資料的需求。這個時候NoSQL的出現暫時解決了這一危機。它通過降低資料的安全性,減少對事務的支援,減少對複雜查詢的支援,來獲取效能上的提升。
-
但是,在有些場合NoSQL一些折衷是無法滿足使用場景的,就比如有些使用場景是絕對要有事務與安全指標的。這個時候NoSQL肯定是無法滿足的,所以還是需要使用關係性資料庫。如果使用關係型資料庫解決海量儲存的問題呢?此時就需要做資料庫叢集,為了提高查詢效能將一個資料庫的資料分散到不同的資料庫中儲存。
MyCat簡介
-
Mycat 背後是阿里曾經開源的知名產品——Cobar。Cobar 的核心功能和優勢是 MySQL 資料庫分片,此產品曾經廣為流傳,據說最早的發起者對 Mysql 很精通,後來從阿里跳槽了,阿里隨後開源的 Cobar,並維持到 2013 年年初,然後,就沒有然後了。
-
Cobar 的思路和實現路徑的確不錯。基於 Java 開發的,實現了 MySQL 公開的二進位制傳輸協議,巧妙地將自己偽裝成一個 MySQL Server,目前市面上絕大多數MySQL客戶端工具和應用都能相容。比自己實現一個新的資料庫協議要明智的多,因為生態環境在哪裡擺著。
-
Mycat 是基於 cobar 演變而來,對 cobar 的程式碼進行了徹底的重構,使用 NIO 重構了網路模組,並且優化了 Buffer 核心,增強了聚合,Join 等基本特性,同時相容絕大多數資料庫成為通用的資料庫中介軟體。
-
簡單的說,MyCAT就是:一個新穎的資料庫中介軟體產品支援mysql叢集,或者mariadb cluster,提供高可用性資料分片叢集。你可以像使用mysql一樣使用mycat。對於開發人員來說根本感覺不到mycat的存在。
MyCat下載及安裝
MySQL安裝與啟動
JDK:要求jdk必須是1.7及以上版本
MySQL:推薦mysql是5.5以上版本
MySQL安裝與啟動步驟如下:( 步驟1-5省略 )
- 將MySQL的服務端和客戶端安裝包(RPM)上傳到伺服器
rpm -qa|grep -i mysql
3. 解除安裝舊版本MySQL
rpm -e --nodeps 軟體名稱
4. 安裝服務端
rpm -ivh MySQL-server-5.5.49-1.linux2.6.i386.rpm
5. 安裝客戶端
rpm -ivh MySQL-client-5.5.49-1.linux2.6.i386.rpm
6. 啟動MySQL服務
service mysql start
7. 登入MySQL
mysql -u root
8. 設定遠端登入許可權
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'IDENTIFIED BY '123456' WITH GRANT OPTION;
在本地SQLyog 連線遠端MySQL進行測試
MyCat安裝及啟動
MyCat的官方網站:
www.mycat.org.cn
下載地址:
github.com/MyCATApache…
- 將Mycat-server-1.4-release-20151019230038-linux.tar.gz上傳至伺服器
- 將壓縮包解壓縮。建議將mycat放到/usr/local/mycat目錄下
tar -xzvf Mycat-server-1.4-release-20151019230038-linux.tar.gz
mv mycat /usr/local
複製程式碼
- 進入mycat目錄的bin目錄,啟動:
./mycat start
停止:./mycat stop
mycat 支援的命令{ console | start | stop | restart | status | dump }
Mycat的預設埠號為:8066
MyCat分片
什麼是分片
簡單來說,就是指通過某種特定的條件,將我們存放在同一個資料庫中的資料分散存放到多個資料庫(主機)上面,以達到分散單臺裝置負載的效果。
資料的切分(Sharding)根據其切分規則的型別,可以分為兩種切分模式。
- 一種是按照不同的表(或者Schema)來切分到不同的資料庫(主機)之上,這種切分可以稱之為資料的垂直(縱向)切分
分片相關的概念
邏輯庫(schema) :
- 前面一節講了資料庫中介軟體,通常對實際應用來說,並不需要知道中介軟體的存在,業務開發人員只需要知道資料庫的概念,所以資料庫中介軟體可以被看做是一個或多個資料庫叢集構成的邏輯庫。
邏輯表(table):
- 既然有邏輯庫,那麼就會有邏輯表,分散式資料庫中,對應用來說,讀寫資料的表就是邏輯表。邏輯表,可以是資料切分後,分佈在一個或多個分片庫中,也可以不做資料切分,不分片,只有一個表構成。
分片表:
- 是指那些原有的很大資料的表,需要切分到多個資料庫的表,這樣,每個分片都有一部分資料,所有分片構成了完整的資料。 總而言之就是需要進行分片的表。
非分片表:
- 一個資料庫中並不是所有的表都很大,某些表是可以不用進行切分的,非分片是相對分片表來說的,就是那些不需要進行資料切分的表。
分片節點(dataNode)
- 資料切分後,一個大表被分到不同的分片資料庫上面,每個表分片所在的資料庫就是分片節點(dataNode)。
節點主機(dataHost)
- 資料切分後,每個分片節點(dataNode)不一定都會獨佔一臺機器,同一機器上面可以有多個分片資料庫,這樣一個或多個分片節點(dataNode)所在的機器就是節點主機(dataHost),為了規避單節點主機併發數限制,儘量將讀寫壓力高的分片節點(dataNode)均衡的放在不同的節點主機(dataHost)。
分片規則(rule)
- 前面講了資料切分,一個大表被分成若干個分片表,就需要一定的規則,這樣按照某種業務規則把資料分到某個分片的規則就是分片規則,資料切分選擇合適的分片規則非常重要,將極大的避免後續資料處理的難度。
MyCat分片配置
- 配置schema.xml
- schema.xml作為MyCat中重要的配置檔案之一,管理著MyCat的邏輯庫、邏輯表以及對應的分片規則、DataNode以及DataSource。弄懂這些配置,是正確使用MyCat的前提。這裡就一層層對該檔案進行解析。
- schema 標籤用於定義MyCat例項中的邏輯庫
- Table 標籤定義了MyCat中的邏輯表 rule用於指定分片規則,auto-sharding-long的分片規則是按ID值的範圍進行分片 1-5000000 為第1片 5000001-10000000 為第2片.... 具體設定我們會在第5小節中講解。
- dataNode 標籤定義了MyCat中的資料節點,也就是我們通常說所的資料分片。
- dataHost標籤在mycat邏輯庫中也是作為最底層的標籤存在,直接定義了具體的資料庫例項、讀寫分離配置和心跳語句。
- 在伺服器上建立3個資料庫,分別是db1 db2 db3
- 修改schema.xml如下:
<?xml version="1.0"?> <!DOCTYPE mycat:schema SYSTEM "schema.dtd"> <mycat:schema xmlns:mycat="http://org.opencloudb/"> <schema name="PINYOUGOUDB" checkSQLschema="false" sqlMaxLimit="100"> <table name="tb_test" 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> <writeHost host="hostM1" url="192.168.25.142:3306" user="root" password="123456"> </writeHost> </dataHost> </mycat:schema> 複製程式碼
- 配置 server.xml
- server.xml幾乎儲存了所有mycat需要的系統配置資訊。最常用的是在此配置使用者名稱、密碼及許可權。在system中新增UTF-8字符集設定,否則儲存中文會出現問號
<property name="charset">utf8</property>
- 修改user的設定 , 我們這裡為 PINYOUGOUDB設定了兩個使用者
<user name="test"> <property name="password">test</property> <property name="schemas">PINYOUGOUDB</property> </user> <user name="root"> <property name="password">123456</property> <property name="schemas">PINYOUGOUDB</property> </user> 複製程式碼
- server.xml幾乎儲存了所有mycat需要的系統配置資訊。最常用的是在此配置使用者名稱、密碼及許可權。在system中新增UTF-8字符集設定,否則儲存中文會出現問號
MyCat分片測試
進入mycat ,執行下列語句建立一個表:
CREATE TABLE tb_test (
id BIGINT(20) NOT NULL,
title VARCHAR(100) NOT NULL ,
PRIMARY KEY (id)
) ENGINE=INNODB DEFAULT CHARSET=utf8
複製程式碼
建立後你會發現,MyCat會自動將你的錶轉換為大寫,這一點與Oracle有些類似。
接下來是插入表資料,注意,在寫INSERT語句時一定要寫把欄位列表寫出來,否則會出現下列錯誤提示:
錯誤程式碼: 1064 partition table, insert must provide ColumnList
我們試著插入一些資料:
INSERT INTO TB_TEST(ID,TITLE) VALUES(1,'goods1');
INSERT INTO TB_TEST(ID,TITLE) VALUES(2,'goods2');
INSERT INTO TB_TEST(ID,TITLE) VALUES(3,'goods3');
複製程式碼
我們會發現這些資料被寫入到第一個節點中了,那什麼時候資料會寫到第二個節點中呢?
我們插入下面的資料就可以插入第二個節點了
INSERT INTO TB_TEST(ID,TITLE) VALUES(5000001,'goods5000001');
因為我們採用的分片規則是每節點儲存500萬條資料,所以當ID大於5000000則會儲存到第二個節點上。
目前只設定了兩個節點,如果資料大於1000萬條,會怎麼樣呢?執行下列語句測試一下
INSERT INTO TB_TEST(ID,TITLE) VALUES(10000001,'goods10000001');
MyCat分片規則
rule.xml用於定義分片規則 ,我們這裡講解兩種最常見的分片規則
- 按主鍵範圍分片rang-long,在配置檔案中我們找到
<tableRule name="auto-sharding-long"> <rule> <columns>id</columns> <algorithm>rang-long</algorithm> </rule> </tableRule> 複製程式碼
- tableRule 是定義具體某個表或某一類表的分片規則名稱,columns用於定義分片的列,algorithm代表演算法名稱, 我們接著找rang-long的定義
<function name="rang-long" class="org.opencloudb.route.function.AutoPartitionByLong"> <property name="mapFile">autopartition-long.txt</property> </function> 複製程式碼
- Function用於定義演算法 mapFile 用於定義演算法需要的資料,我們開啟autopartition-long.txt
# range start-end ,data node index # K=1000,M=10000. 0-500M=0 500M-1000M=1 1000M-1500M=2 複製程式碼
- 一致性雜湊murmur
- 當我們需要將資料平均分在幾個分割槽中,需要使用一致性hash規則, 我們找到function的name為murmur 的定義,將count屬性改為3,因為我要將資料分成3片
<function name="murmur" class="org.opencloudb.route.function.PartitionByMurmurHash"> <property name="seed">0</property> <!-- 預設是0 --> <property name="count">3</property> <!-- 要分片的資料庫節點數量,必須指定,否則沒法分片 --> <!-- 一個實際的資料庫節點被對映為這麼多虛擬節點,預設是160倍,也就是虛擬節點數是物理節點數的160倍 --> <property name="virtualBucketTimes">160</property> <!-- <property name="weightMapFile">weightMapFile</property> 節點的權重,沒有指定權重的節點預設是1。 以properties檔案的格式填寫,以從0開始到count-1的整數值也就是節點索引為key, 以節點權重值為值。所有權重值必須是正整數,否則以1代替 --> <!-- <property name="bucketMapPath">/etc/mycat/bucketMapPath</property> 用於測試時觀察各物理節點與虛擬節點的分佈情況,如果指定了這個屬性, 會把虛擬節點的murmur hash值與物理節點的對映按行輸出到這個檔案,沒有預設值,如果不指定,就不會輸出任何東西 --> </function> 複製程式碼
- 我們再配置檔案中可以找到表規則定義
<tableRule name="sharding-by-murmur"> <rule> <columns>id</columns> <algorithm>murmur</algorithm> </rule> </tableRule> 複製程式碼
- 但是這個規則指定的列是id ,如果我們的表主鍵不是id ,而是order_id ,那麼我們應該重新定義一個tableRule:
<tableRule name="sharding-by-murmur-order"> <rule> <columns>order_id</columns> <algorithm>murmur</algorithm> </rule> </tableRule> 複製程式碼
- 在schema.xml中配置邏輯表時,指定規則為sharding-by-murmur-order
<table name="tb_order" dataNode="dn1,dn2,dn3" rule="sharding-by-murmur-order" />
我們測試一下,建立訂單表 ,並插入資料,測試分片效果。
瞭解資料庫讀寫分離
資料庫讀寫分離對於大型系統或者訪問量很高的網際網路應用來說,是必不可少的一個重要功能。對於MySQL來說,標準的讀寫分離是主從模式,一個寫節點Master後面跟著多個讀節點,讀節點的數量取決於系統的壓力,通常是1-3個讀節點的配置
擴充套件思考
- 連表查詢怎麼做
- 分片策略是每個表需要配嗎?如果不配置的話會怎麼樣?
- 分片策略有哪些,都應對什麼場景比較多
- 支援事務嗎?怎麼支援的?
- 查詢誇庫時, 返回的結果集是怎麼樣的?效率怎麼樣呢?
- 不同的分片策略下,例項擴充套件怎麼操作
- 缺點是怎麼樣的