開源數據庫中間件-MyCat

開源數據庫中間件-MyCat

如今隨着互聯網的發展,數據的量級也是撐指數的增長,從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支持的數據庫:

 

MyCat下載及安裝

MySQL安裝與啓動

JDK:要求jdk必須是1.7及以上版本

MySQL:推薦mysql是5.5以上版本

MySQL安裝與啓動步驟如下:( 步驟1-5省略 )

(1)將MySQL的服務端和客戶端安裝包(RPM)上傳到服務器

(2)查詢之前是否安裝過MySQL

rpm -qa|grep -i mysql

(3)卸載舊版本MySQL

rpm -e --nodeps  軟件名稱

  1. 安裝服務端

rpm -ivh MySQL-server-5.5.49-1.linux2.6.i386.rpm

  1. 安裝客戶端

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進行測試 

1.2.2 MyCat安裝及啓動

MyCat:

MyCat的官方網站:

http://www.mycat.org.cn/

下載地址:

https://github.com/MyCATApache/Mycat-download

第一步:將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

./mycat start

停止:

./mycat stop

mycat 支持的命令{ console | start | stop | restart | status | dump }

Mycat的默認端口號爲:8066

MyCat分片-海量數據存儲解決方案

 什麼是分片

簡單來說,就是指通過某種特定的條件,將我們存放在同一個數據庫中的數據分散存放到多個數據庫(主機)上面,以達到分散單臺設備負載的效果。

數據的切分(Sharding)根據其切分規則的類型,可以分爲兩種切分模式。

   (1)一種是按照不同的表(或者Schema)來切分到不同的數據庫(主機)之上,這種切分可以稱之爲數據的垂直(縱向)切分

   (2)另外一種則是根據表中的數據的邏輯關係,將同一個表中的數據按照某種條件拆分到多臺數據庫(主機)上面,這種切分稱之爲數據的水平(橫向)切分。

            

MyCat分片策略:

 分片相關的概念

邏輯庫(schema)

前面一節講了數據庫中間件,通常對實際應用來說,並不需要知道中間件的存在,業務開發人員只需要知道數據庫的概念,所以數據庫中間件可以被看做是一個或多個數據庫集羣構成的邏輯庫。

邏輯表(table):

既然有邏輯庫,那麼就會有邏輯表,分佈式數據庫中,對應用來說,讀寫數據的表就是邏輯表。邏輯表,可以是數據切分後,分佈在一個或多個分片庫中,也可以不做數據切分,不分片,只有一個表構成。

分片表:是指那些原有的很大數據的表,需要切分到多個數據庫的表,這樣,每個分片都有一部分數據,所有分片構成了完整的數據。 總而言之就是需要進行分片的表。

非分片表:一個數據庫中並不是所有的表都很大,某些表是可以不用進行切分的,非分片是相對分片表來說的,就是那些不需要進行數據切分的表。

分片節點(dataNode)

數據切分後,一個大表被分到不同的分片數據庫上面,每個表分片所在的數據庫就是分片節點(dataNode)。

節點主機(dataHost)

數據切分後,每個分片節點(dataNode)不一定都會獨佔一臺機器,同一機器上面可以有多個分片數據庫,這樣一個或多個分片節點(dataNode)所在的機器就是節點主機(dataHost),爲了規避單節點主機併發數限制,儘量將讀寫壓力高的分片節點(dataNode)均衡的放在不同的節點主機(dataHost)。

分片規則(rule)

前面講了數據切分,一個大表被分成若干個分片表,就需要一定的規則,這樣按照某種業務規則把數據分到某個分片的規則就是分片規則,數據切分選擇合適的分片規則非常重要,將極大的避免後續數據處理的難度。

 MyCat分片配置

(1)配置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>

(2)配置 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>

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有些類似。

我們再查看MySQL的3個庫,發現表都自動創建好啦。好神奇。

接下來是插入表數據,注意,在寫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用於定義分片規則  ,我們這裏講解兩種最常見的分片規則

(1)按主鍵範圍分片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

 

  1. 一致性哈希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><!-- 要分片的數據庫節點數量,必須指定,否則沒法分片 -->

                   <property name="virtualBucketTimes">160</property><!-- 一個實際的數據庫節點被映射爲這麼多虛擬節點,默認是160倍,也就是虛擬節點數是物理節點數的160倍 -->

                   <!-- <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個讀節點的配置

Mycat讀寫分離和自動切換機制,需要mysql的主從複製機制配合。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章