開源數據庫中間件-MyCa初探與分片實踐

著做權歸做者全部,任何形式的轉載都請聯繫做者得到受權並註明出處。

  • 現在隨着互聯網的發展,數據的量級也是撐指數的增加,從GB到TB到PB。對數據的各類操做也是越發的困難,傳統的關係性數據庫已經沒法知足快速查詢與插入數據的需求。這個時候NoSQL的出現暫時解決了這一危機。它經過下降數據的安全性,減小對事務的支持,減小對複雜查詢的支持,來獲取性能上的提高。node

  • 可是,在有些場合NoSQL一些折衷是沒法知足使用場景的,就好比有些使用場景是絕對要有事務與安全指標的。這個時候NoSQL確定是沒法知足的,因此仍是須要使用關係性數據庫。若是使用關係型數據庫解決海量存儲的問題呢?此時就須要作數據庫集羣,爲了提升查詢性能將一個數據庫的數據分散到不一樣的數據庫中存儲。mysql

MyCat簡介

  • Mycat 背後是阿里曾經開源的知名產品——Cobar。Cobar 的核心功能和優點是 MySQL 數據庫分片,此產品曾經廣爲流傳,聽說最先的發起者對 Mysql 很精通,後來從阿里跳槽了,阿里隨後開源的 Cobar,並維持到 2013 年年初,而後,就沒有而後了。linux

  • Cobar 的思路和實現路徑的確不錯。基於 Java 開發的,實現了 MySQL 公開的二進制傳輸協議,巧妙地將本身假裝成一個 MySQL Server,目前市面上絕大多數MySQL客戶端工具和應用都能兼容。比本身實現一個新的數據庫協議要明智的多,由於生態環境在哪裏擺着。git

  • Mycat 是基於 cobar 演變而來,對 cobar 的代碼進行了完全的重構,使用 NIO 重構了網絡模塊,而且優化了 Buffer 內核,加強了聚合,Join 等基本特性,同時兼容絕大多數數據庫成爲通用的數據庫中間件。github

  • 簡單的說,MyCAT就是:一個新穎的數據庫中間件產品支持mysql集羣,或者mariadb cluster,提供高可用性數據分片集羣。你能夠像使用mysql同樣使用mycat。對於開發人員來講根本感受不到mycat的存在。算法

MyCat支持的數據庫:

MyCat下載及安裝

MySQL安裝與啓動

JDK:要求jdk必須是1.7及以上版本
MySQL:推薦mysql是5.5以上版本
MySQL安裝與啓動步驟以下:( 步驟1-5省略 )sql

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

2. 查詢以前是否安裝過MySQL
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…數據庫

  1. 將Mycat-server-1.4-release-20151019230038-linux.tar.gz上傳至服務器
  2. 將壓縮包解壓縮。建議將mycat放到/usr/local/mycat目錄下
tar -xzvf Mycat-server-1.4-release-20151019230038-linux.tar.gz
mv mycat /usr/local
複製代碼
  1. 進入mycat目錄的bin目錄,啓動: ./mycat start 中止:./mycat stop

mycat 支持的命令{ console | start | stop | restart | status | dump }
Mycat的默認端口號爲:8066安全

MyCat分片

什麼是分片

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

數據的切分(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
    複製代碼
  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個讀節點的配置

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

擴展思考

  1. 連表查詢怎麼作
  2. 分片策略是每一個表須要配嗎?若是不配置的話會怎麼樣?
  3. 分片策略有哪些,都應對什麼場景比較多
  4. 支持事務嗎?怎麼支持的?
  5. 查詢誇庫時, 返回的結果集是怎麼樣的?效率怎麼樣呢?
  6. 不一樣的分片策略下,實例擴展怎麼操做
  7. 缺點是怎麼樣的

相關文章
相關標籤/搜索