最近好不容易抽空研究了下Cobar,感受這個產品確實很不錯(在文檔方面比Amoeba強多了),特此推薦給你們。Cobar是阿里巴巴研發的關係型數據的分佈式處理系統,該產品成功替代了原先基於Oracle的數據存儲方案,目前已經接管了3000+個MySQL數據庫的schema,平均天天處理近50億次的SQL執行請求。
首先,使用Cobar的核心功能以下:
分佈式:
Cobar的分佈式主要是經過將表放入不一樣的庫來實現:
1. Cobar支持將一張表水平拆分紅多份分別放入不一樣的庫來實現表的水平拆分
2. Cobar也支持將不一樣的表放入不一樣的庫
3. 多數狀況下,用戶會將以上兩種方式混合使用
這裏須要強調的是,Cobar不支持將一張表,例如test表拆分紅test_1, test_2, test_3.....放在同一個庫中,必須將拆分後的表分別放入不一樣的庫來實現分佈式。
HA:
在用戶配置了MySQL心跳的狀況下,Cobar能夠自動向後端鏈接的MySQL發送心跳,判斷MySQL運行情況,一旦運行出現異常,Cobar能夠自動切換到備機工做。但須要強調的是:
1. Cobar的主備切換有兩種觸發方式,一種是用戶手動觸發,一種是Cobar的心跳語句檢測到異常後自動觸發。那麼,小心跳檢測到主機異常,切換到備機,若是主機恢復了,須要用戶手動切回主機工做,Cobar不會在主機恢復時自動切換回主機,除非備機的心跳也返回異常。
2. Cobar只檢查MySQL主備異常,不關心主備之間的數據同步,所以用戶須要在使用Cobar以前在MySQL主備上配置雙向同步,詳情能夠參閱MySQL參考手冊。
其次,咱們也須要注意Cobar的功能約束:
1) 不支持跨庫狀況下的join、分頁、排序、子查詢操做。
2) SET語句執行會被忽略,事務和字符集設置除外。
3) 分庫狀況下,insert語句必須包含拆分字段列名。
4) 分庫狀況下,update語句不能更新拆分字段的值。
5) 不支持SAVEPOINT操做。
6) 暫時只支持MySQL數據節點。
7) 使用JDBC時,不支持rewriteBatchedStatements=true參數設置(默認爲false)。
8) 使用JDBC時,不支持useServerPrepStmts=true參數設置(默認爲false)。
9) 使用JDBC時,BLOB, BINARY, VARBINARY字段不能使用setBlob()或setBinaryStream()方法設置參數。
而後,咱們來分析一下Cobar邏輯層次圖:
* dataSource:數據源,表示一個具體的數據庫鏈接,與物理存在的數據庫schema一一對應。
* dataNode:數據節點,由主、備數據源,數據源的HA以及鏈接池共同組成,能夠將一個dataNode理解爲一個分庫。
* table:表,包括拆分表(如tb1,tb2)和非拆分表。
* tableRule:路由規則,用於判斷SQL語句被路由到具體哪些datanode執行。
* schema:cobar能夠定義包含拆分表的schema(如schema1),也能夠定義無拆分表的schema(如schema2)。
Cobar支持的數據庫結構(schema)的層次關係具備較強的靈活性,用戶能夠將表自由放置不一樣的datanode,也可將不一樣的datasource放置在同一MySQL實例上。在實際應用中,咱們須要經過配置文件(schema.xml)來定義咱們須要的數據庫服務器和表的分佈策略,這點咱們將在後面的安裝和配置部分中介紹到。
接着,咱們來介紹Cobar的安裝和配置步驟:
下面咱們將使用一個最簡單的分庫分表的例子來講明Cobar的基本用法,數據庫schema以下圖(該實例也可參考:Cobar產品首頁)。
1) 系統對外提供的數據庫名是dbtest,而且其中有兩張表tb1和tb2。
2) tb1表的數據被映射到物理數據庫dbtest1的tb1上。
3) tb2表的一部分數據被映射到物理數據庫dbtest2的tb2上,另一部分數據被映射到物理數據庫dbtest3的tb2上。
一、環境準備
操做系統:Linux或者Windows (推薦在Linux環境下運行Cobar)
MySQL:http://www.mysql.com/downloads/ (推薦使用5.1以上版本)
JDK:http://www.oracle.com/technetwork/java/javase/downloads/ (推薦使用1.6以上版本)
Cobar:http://code.alibabatech.com/wiki/display/cobar/release/ (下載tar.gz或者zip文件)
二、數據準備
假設本文MySQL所在服務器IP爲192.168.0.1,端口爲3306,用戶名爲test,密碼爲空,咱們須要建立schema:dbtest一、dbtest二、dbtest3,table:tb一、tb2,SQL以下:前端
#建立dbtest1 drop database if exists dbtest1; create database dbtest1; use dbtest1; #在dbtest1上建立tb1 create table tb1( id int not null, gmt datetime); #建立dbtest2 drop database if exists dbtest2; create database dbtest2; use dbtest2; #在dbtest2上建立tb2 create table tb2( id int not null, val varchar(256)); #建立dbtest3 drop database if exists dbtest3; create database dbtest3; use dbtest3; #在dbtest3上建立tb2 create table tb2( id int not null, val varchar(256));
三、配置Cobar
Cobar解壓以後有四個目錄:
bin/:可執行文件目錄,包含啓動(start)、關閉(shutdown)和重啓(restart)腳本
lib/:邏輯類庫目錄,包含了Cobar所需的jar包
conf/:配置文件目錄,下面會詳細介紹
logs/:運行日誌目錄,最主要的log有兩個:程序日誌(stdout.log)和控制檯輸出(console.log)
配置文件的用法以下:
log4j.xml:日誌配置,通常來講保持默認便可
schema.xml:定義了schema邏輯層次圖中的全部元素,並利用這些元素以及rule.xml中定義的規則組建分佈式數據庫系統
rule.xml:定義了分庫分表的規則
server.xml:系統配置文件
咱們在schema.xml中配置數據庫結構(schema)、數據節點(dataNode)、以及數據源(dataSource)。java
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE cobar:schema SYSTEM "schema.dtd"> <cobar:schema xmlns:cobar="http://cobar.alibaba.com/"> <!-- schema定義 --> <schema name="dbtest" dataNode="dnTest1"> <table name="tb2" dataNode="dnTest2,dnTest3" rule="rule1" /> </schema> <!-- 數據節點定義,數據節點由數據源和其餘一些參數組織而成。--> <dataNode name="dnTest1"> <property name="dataSource"> <dataSourceRef>dsTest[0]</dataSourceRef> </property> </dataNode> <dataNode name="dnTest2"> <property name="dataSource"> <dataSourceRef>dsTest[1]</dataSourceRef> </property> </dataNode> <dataNode name="dnTest3"> <property name="dataSource"> <dataSourceRef>dsTest[2]</dataSourceRef> </property> </dataNode> <!-- 數據源定義,數據源是一個具體的後端數據鏈接的表示。--> <dataSource name="dsTest" type="mysql"> <property name="location"> <location>192.168.0.1:3306/dbtest1</location> <!--注意:替換爲您的MySQL IP和Port--> <location>192.168.0.1:3306/dbtest2</location> <!--注意:替換爲您的MySQL IP和Port--> <location>192.168.0.1:3306/dbtest3</location> <!--注意:替換爲您的MySQL IP和Port--> </property> <property name="user">test</property> <!--注意:替換爲您的MySQL用戶名--> <property name="password">test</property> <!--注意:替換爲您的MySQL密碼--> <property name="sqlMode">STRICT_TRANS_TABLES</property> </dataSource> </cobar:schema>
咱們注意到,上述配置實際上已經把圖2中的數據庫結構配置好了。dbtest主要映射的是dnTest1庫(即192.168.0.1:3306/dbtest1庫),而其中的tb2表則是按照規則rule1,被分配到dnTest2庫(即192.168.0.1:3306/dbtest2庫)和dnTest3庫(即192.168.0.1:3306/dbtest3庫)中。此外,規則rule1的定義能夠在rule.xml中找到,代碼以下:node
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE cobar:rule SYSTEM "rule.dtd"> <cobar:rule xmlns:cobar="http://cobar.alibaba.com/"> <!-- 路由規則定義,定義什麼表,什麼字段,採用什麼路由算法。--> <tableRule name="rule1"> <rule> <columns>id</columns> <algorithm><![CDATA[ func1(${id})]]></algorithm> </rule> </tableRule> <!-- 路由函數定義,應用在路由規則的算法定義中,路由函數能夠自定義擴展。--> <function name="func1" class="com.alibaba.cobar.route.function.PartitionByLong"> <property name="partitionCount">2</property> <property name="partitionLength">512</property> </function> </cobar:rule>
結合schema.xml中的內容,咱們能夠看出分表的規則是,按照id字段把tb2表中的數據分配到dnTest2和dnTest3兩個分區中,其中id小於512的數據會被放到dnTest2庫的分區中,而其他的會被放到dnTest3庫的分區中,更多路由算法能夠參考《路由文檔》。最後,咱們來看一下server.xml的配置,代碼以下。mysql
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE cobar:server SYSTEM "server.dtd"> <cobar:server xmlns:cobar="http://cobar.alibaba.com/"> <!--定義Cobar用戶名,密碼--> <user name="root"> <property name="password">passwd</property> <property name="schemas">dbtest</property> </user> </cobar:server>
這裏的server.xml配置比較簡單,只配置了本地Cobar服務的數據庫結構、用戶名和密碼。在啓動Cobar服務以後,使用用戶名root和密碼passwd就能夠登陸Cobar服務。
四、運行Cobar
啓動Cobar服務很簡單,運用bin目錄下的start.sh便可(中止使用shutdown.sh)。啓動成功以後,能夠在logs目錄下的stdout.log中看到以下日誌:算法
10:54:19,264 INFO =============================================== 10:54:19,265 INFO Cobar is ready to startup ... 10:54:19,265 INFO Startup processors ... 10:54:19,443 INFO Startup connector ... 10:54:19,446 INFO Initialize dataNodes ... 10:54:19,470 INFO dnTest1:0 init success 10:54:19,472 INFO dnTest3:0 init success 10:54:19,473 INFO dnTest2:0 init success 10:54:19,481 INFO CobarManager is started and listening on 9066 10:54:19,483 INFO CobarServer is started and listening on 8066 10:54:19,484 INFO ===============================================
接着,咱們就可使用「mysql -h127.0.0.1 -uroot -ppasswd -P8066 -Ddbtest」命令來登陸Cobar服務了,再接下來的操做就和在其餘MySQL Client中同樣了。好比,咱們可使用「show databases」命令查看數據庫,使用「show tables」命令查看數據表,以下圖:
接着,咱們按照下圖中的SQL指定向數據表插入測試記錄。
能夠看到,這裏的tb2中包含了id爲一、二、513的3條記錄。而實際上,這3條記錄存儲在不一樣的物理數據庫上的,你們能夠到物理庫上驗證一下。
至於Cobar的鏈接和使用方法和MySQL同樣,Java程序中可使用JDBC(建議5.1以上的版本),PHP中可使用PDO。固然,Cobar還提供HA、集羣等高級的功能,更多信息請參考其《產品文檔》。此外,產品文檔中還爲咱們提供了詳細的PPT文檔《Cobar原理及應用.ppt》來介紹Cobar在實際生產環境中的使用方法,真可謂之用心良苦啊!
此外,特別解釋一下你們可能比較關心的心跳檢測問題,Cobar的心跳檢測主要用在如下兩個地方。
一、在配置數據節點的時候,咱們須要使用心跳檢測來探測數據節點的運行情況。Cobar中使用執行SQL的方式來進行探測,簡單且實用。例如,咱們能夠把前面實例中的schema.xml中的dataNode配置成下面的樣子。sql
... ... <!-- 數據節點定義,數據節點由數據源和其餘一些參數組織而成。--> <dataNode name="dnTest1"> <property name="dataSource"> <dataSourceRef>dsTest[0]</dataSourceRef> </property> <!--Cobar與後端數據源鏈接池大小設置--> <property name="poolSize">256</property> <!--Cobar經過心跳來實現後端數據源HA,一旦主數據源心跳失敗,便切換到備數據源上工做--> <!--Cobar心跳是經過向後端數據源執行一條SQL語句,根據該語句的返回結果判斷數據源的運行狀況--> <property name="heartbeat">select user()<property> </dataNode> ... ...
二、當咱們須要對Cobar做集羣(cluster),進行負載均衡的時候,咱們也須要用到心跳機制。不過此處的配置則是在server.xml中,代碼以下:數據庫
... ... <!--組建一個Cobar集羣,只需在cluster配置中把全部Cobar節點(注意:包括當前Cobar自身)都配置上即可--> <cluster> <!--node名稱,一個node表示一個Cobar節點,一旦配置了node,當前Cobar便會向此節點按期發起心跳,探測節點的運行狀況--> <node name="cobar1"> <!--Cobar節點IP, 表示當前Cobar將會向192.168.0.1上部署的Cobar發送心跳--> <property name="host">192.168.0.1</property> <!--節點的權重,用於客戶端的負載均衡,用戶能夠經過命令查詢某個節點的運行狀況以及權重--> <property name="weight">1</property> </node> <!--當前Cobar將會向192.168.0.2上部署的Cobar發送心跳--> <node name="cobar2"> <property name="host">192.168.0.2</property> <property name="weight">2</property> </node> <!--當前Cobar將會向192.168.0.3上部署的Cobar發送心跳--> <node name="cobar3"> <property name="host">192.168.0.3</property> <property name="weight">3</property> </node> <!--用戶還能夠將Cobar節點分組,以便實現schema級別的細粒度負載均衡--> <group name="group12"> <property name="nodeList">cobar1,cobar2</property> </group> <group name="group23"> <property name="nodeList">cobar2,cobar3</property> </group> </cluster> ... ...
最後,簡單看一下Cobar的實現原理。
首先是系統模塊架構。
從上圖中能夠看到,Cobar的前、後端模塊都實現了MySQL協議;當接受到SQL請求時,會依次進行解釋(SQL Parser)和路由(SQL Router)工做,而後使用SQL Executor去後端模塊獲取數據集(後端模塊還負責心跳檢測功能);若是數據集來自多個數據源,Cobar則須要把數據集進行組合(Result Merge),最後返回響應。整個過程應該比較容易理解,
下面是Cobar的網絡通信模塊架構。
從上圖中能夠看出,Cobar採用了主流的Reactor設計模式來處理請求,並使用NIO進行底層的數據交換,這大大提高系統的負載能力。其中,NIOAcceptor用於處理前端請求,NIOConnector則用於管理後端的鏈接,NIOProcessor用於管理多線程事件處理,NIOReactor則用於完成底層的事件驅動機制,就是看起來和Mina和Netty的網絡模型比較類似。若是有興趣,你們還能夠到Cobar站點的下載頁面(http://code.alibabatech.com/wiki/display/cobar/release)獲取該項目的源碼,真是太周到了,讓咱們爲富有開源精神的阿里人掌聲鼓勵一下!後端