1. 程式人生 > >資料庫 分庫分表中介軟體 Cobar 介紹

資料庫 分庫分表中介軟體 Cobar 介紹

最近好不容易抽空研究了下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上。

1、環境準備

作業系統: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檔案)

2、資料準備

假設本文MySQL所在伺服器IP為192.168.0.1,埠為3306,使用者名稱為test,密碼為空,我們需要建立schema:dbtest1、dbtest2、dbtest3,table:tb1、tb2,SQL如下:
  1. #建立dbtest1  
  2. dropdatabase if exists dbtest1;  
  3. createdatabase dbtest1;  
  4. use dbtest1;  
  5. #在dbtest1上建立tb1  
  6. createtable tb1(  
  7. id    intnotnull,  
  8. gmt   datetime);  
  9. #建立dbtest2  
  10. dropdatabase if exists dbtest2;  
  11. createdatabase dbtest2;  
  12. use dbtest2;  
  13. #在dbtest2上建立tb2  
  14. createtable tb2(  
  15. id    intnotnull,  
  16. val   varchar(256));  
  17. #建立dbtest3  
  18. dropdatabase if exists dbtest3;  
  19. createdatabase dbtest3;  
  20. use dbtest3;  
  21. #在dbtest3上建立tb2  
  22. createtable tb2(  
  23. id    intnotnull,  
  24. val   varchar(256));  

3、配置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)。
  1. <?xmlversion="1.0"encoding="UTF-8"?>
  2. <!DOCTYPE cobar:schema SYSTEM "schema.dtd">
  3. <cobar:schemaxmlns:cobar="http://cobar.alibaba.com/">
  4.   <!-- schema定義 -->
  5.   <schemaname="dbtest"dataNode="dnTest1">
  6.     <tablename="tb2"dataNode="dnTest2,dnTest3"rule="rule1"/>
  7.   </schema>
  8.   <!-- 資料節點定義,資料節點由資料來源和其他一些引數組織而成。-->
  9.   <dataNodename="dnTest1">
  10.     <propertyname="dataSource">
  11.       <dataSourceRef>dsTest[0]</dataSourceRef>
  12.     </property>
  13.   </dataNode>
  14.   <dataNodename="dnTest2">
  15.     <propertyname="dataSource">
  16.       <dataSourceRef>dsTest[1]</dataSourceRef>
  17.     </property>
  18.   </dataNode>
  19.   <dataNodename="dnTest3">
  20.     <propertyname="dataSource">
  21.       <dataSourceRef>dsTest[2]</dataSourceRef>
  22.     </property>
  23.   </dataNode>
  24.   <!-- 資料來源定義,資料來源是一個具體的後端資料連線的表示。-->
  25.   <dataSourcename="dsTest"type="mysql">
  26.     <propertyname="location">
  27.       <location>192.168.0.1:3306/dbtest1</location><!--注意:替換為您的MySQL IP和Port-->
  28.       <location>192.168.0.1:3306/dbtest2</location><!--注意:替換為您的MySQL IP和Port-->
  29.       <location>192.168.0.1:3306/dbtest3</location><!--注意:替換為您的MySQL IP和Port-->
  30.     </property>
  31.     <propertyname="user">test</property><!--注意:替換為您的MySQL使用者名稱-->
  32.     <propertyname="password">test</property><!--注意:替換為您的MySQL密碼-->
  33.     <propertyname="sqlMode">STRICT_TRANS_TABLES</property>
  34.   </dataSource>
  35. </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中找到,程式碼如下:
  1. <?xmlversion="1.0"encoding="UTF-8"?>
  2. <!DOCTYPE cobar:rule SYSTEM "rule.dtd">
  3. <cobar:rulexmlns:cobar="http://cobar.alibaba.com/">
  4.   <!