一、 Cobar項目介紹
一)、Cobar背景概述
Cobar是提供分布式數據庫服務的中間件,由阿里巴巴中間件團隊開發,是阿里巴巴B2B前台應用訪問數據庫的統一入口,目前已在github上開源。
Cobar的分布式方案是分庫和分表,可以按照業務需求將數據庫中耦合度較低的表分到不同的分庫中,也可以按照具體表的增長速度和數據量水平切分到不同的分庫中,Cobar可以實現應用層與物理分庫的雙向透明,從而實現應用程序訪問分布式數據庫與訪問單庫無差別。 Cobar還可以配合MySQL的心跳和binlog實現備機的自動切換,保證數據節點的可靠性,從而實現高可用性。
但Cobar目前的版本是2013年發布的版本1.2.7,由於作者目前的工作重心不在Cobar,所以雖然會繼續更新,進度不會很快。
二)、Cobar架構
其中前端是NIO實現的,通過MySQL協議與應用程序交互,后端也是通過MySQL協議與物理數據庫交互。
三)、Cobar的約束
官方文檔對Cobar的適用場景和限制都有明確的說明。
- 使用jdbc時,使用mysql-jdbc-5.1以上版本,推薦5.1.6或者5.1.12版本。
- 不支持rewriteBatchedStatements=true參數設置。默認為false
- 不支持useServerPrepStmts=true參數設置。默認為false
- 不支持跨庫(數據節點)的關聯操作:join、分頁、排序、子查詢。
- BLOB, BINARY, VARBINARY字段不能使用。若特殊需求需要這三種字段,禁止使用PreparedStatement的setBlob()或setBinaryStream()方法設置參數。
- 不支持SAVEPOINT操作。
- 不支持SET語句的執行,事務和字符集設置語句除外。
- 對於拆分表(分庫表),不能更新已有記錄的拆分字段(分庫字段)值。
- 只支持MySQL數據節點。
- 對於拆分表,插入操作須給出列名,必須包含拆分字段。
二、應用背景
隨着業界的逐步去IOE化,分布式MySQL集群成為了一個實現高可用、高性能、可擴展的數據庫解決方案。
目前業內有很多MySQL集群方案供不同的使用場景選擇,比如:
1.雙主復制模式,不做數據拆分,可以綜合運用keepalived和MySQL實現。
2.如果需要做數據庫拆分,要求分布式事務,就可以考慮Cobar。
3.如果需要數據庫拆分,不需要分布式事務,需要讀寫分離,則可以使用同樣是阿里開源的中間件項目。
此外還有一些選擇,比如MySQL Proxy,使用lua編寫,但是官方維護已經終止;MySQL Cluster, 商用版也是收費的,社區版免費但是性能存疑;還有搜狐新近開源的C語言編寫的MySQL分布式中間件DBProxy。
三、Cobar詳細分析
為了對Cobar的功能以及約束有一定的認識,搭建了簡單的Cobar測試環境進行實驗。實驗中共使用了3種數據庫方案:
1.MySQL單庫方案
2.6節點Cobar方案
3.16節點Cobar方案
一)、環境搭建
Cobar的release版本中包含配置文件、jar包以及日志文件。
搭建Cobar環境需要根據情況配置rule.xml、schema.xml、server.xml。其中schema.xml定義了分庫分表的規則以及數據節點和數據源的信息。rule.xml定義了水平分表的路由規則,但是目前的路由算法是Cobar源碼中硬編碼定的,能夠配置的只是節點數等參數,如果需要根據業務需求定義路由算法,需要修改Cobar的源碼。server.xml定義Cobar服務的信息,包括其作為一個數據源時的用戶名密碼等,還定義了包含的schema。
bin目錄下的文件是用來啟動關閉cobar-server的,其中windows下用到的就是startup.bat,該批處理文件需要修改版本號以順利運行:
啟動Cobar后可以查看stdout.log,如果沒有報異常則啟動正常:
Cobar服務監聽8066端口,在MySQL命令行和JDBC連接中,8066作為默認端口。
二)、基本功能測試
本環節測試了基本的MySQL功能,查詢,插入等。
數據表分配如下:
在schema.xml中定義了該schema的默認datanode,定義了tb2分布在dbtest2、dbtest3中。默認datanode的作用是存放未指定的表,比如創建tb1,就會默認放在dbtest1中。
在rule.xml中為tb2定義了路由用的partitionCount和partitionLength,會按照特定字段進行分庫操作。
1.insert
insert命令能夠按照約定的路由規則插入特定的分庫中。
為了簡單測試cobar的插入效率,對tb2插入了10W條數據,結果顯示要比單機MySQL插入10W條數據稍慢,隨后測試16節點cobar插入10W條數據,速度已經和單機插入接近,如果多線程並發執行的話,cobar會有比較大的優勢。
2.select
對上一步插入的數據進行select操作,每個分庫結果會merge在一起但是merge的順序是不確定的。
同樣對cobar中的10W條數據進行查詢,結果顯示依舊是比單機慢:
Cobar:
單機MySQL:
三)、特定功能測試
正常業務中的SQL語句不會僅僅只是insert、select,會用到聚合函數、內外連接、子查詢等。官方文檔里已經明確說明不支持跨庫條件下的這些操作,具體測試如下。
1、order by
對數據id排序查詢,單庫中order by可以正常顯示,對cobar進行相同的操作,可以返回結果,每個分庫的結果集按照各自的order排序,最后merge的時候並不是全部排序,而是隨機聯接在一起。
2、sum count
sum常用來合計某些字段,count用來計數,都是比較常用的sql關鍵字。Cobar能夠返回sum/count的結果,但依舊是每個分庫各自統計。
用子查詢也不能合並分庫的sum,這兩個sql查出來的結果是相同的。
3、join
join也是極其常用的sql關鍵字,但是在cobar中如果切分規則不同的兩張表進行join,則構成了跨庫。Cobar會報錯,提示不存在共同分庫中的相應表。而如果兩張表采用相同的切分字段,相同的路由規則,那么兩者是能夠join的。
在測試環境中,tb1不是和tb4相同切分,如果和tb4 join,就會提示不存在dbtest3.tb1。
而如果和tb4切分相同的tb3和它join就可以實現。
4、exists
exists也可以用,但是也是要考慮在不在一個庫中
tb3和tb4是按照相同的分片規則分布在數據庫中的
5、子查詢
子查詢在跨庫情況下也是不能實現的,但是如果能夠限制過程中使用的都封閉在同一個分庫中,那么子查詢是可以成立的。
6、存儲過程
在嘗試插入10W條數據的時候,單機用到了存儲過程,總共用時50余秒,同樣語句用到cobar的時候,會顯示語法錯誤,官方提示沒有測試過存儲過程,不推薦使用。
四、應用Cobar的問題及解決方案
現實中有的業務是比較復雜的,功能實現中使用到的SQL語句也可能是很復雜的,可能遇到的問題如下:
一)、參數表
實際業務中會有一些讀操作很多而對寫要求不多的參數表,會頻繁地和其他表進行join,但是cobar不支持跨庫join,那么可行的方案就是在每個分庫中保留一份參數表,以便每個分庫都可以合法操作。
但這會帶來兩個問題:
1.參數表之間需要union操作,但是每個分庫中有一份相同表的結果就是union操作不能夠除去重復項。
可以在分表的schema外有一個單庫的schema,所有對參數表的增刪改操作都限制在該庫中,其所產生的變化都同步到每個分庫中。
2.不同分庫的參數表需要同步,那么如何保持參數表的數據一致性也是必須要考慮的問題。
二)、跨庫操作問題
1、分庫分表問題
Cobar不支持跨庫操作,但是很多操作已經證明只要是封閉在各自分庫中就是可以實現的,比如子查詢、join等。
那么關鍵的問題就是如何分庫分表,需要按照業務的耦合關系將數據庫拆分重組,將不能跨庫的操作盡量限制在一個庫中。
而且cobar當前的路由算法不一定能夠滿足復雜業務下的特異性分表方案,所以在有需求的情況下,還需要自定義cobar的路由算法,自定義路由算法需要extends PartitionFunction implements RuleAlgorithm。
2、sum/count
但是即使分庫分表方案設計完善,還是不能解決sum/count等功能的不完善,需要把每個分庫的結果再累加才是需要的結果。
解決這個問題有幾個方案:
1.在應用程序中處理,實現比較簡單,但是增加了模塊間的耦合度,破壞了數據層與應用層的透明。
2.修改cobar源碼,識別sql語句,在收到返回信息的時候進行處理。實現難度比較大,但是保持了模塊間的低耦合。
三)、壓力問題
本次測試用的是虛擬機,單台虛擬機安裝了8個MySQL實例,共實現了16個datanode,虛擬了10W條數據的簡單操作,但和生產環境下的硬件條件以及壓力情況是有很大區別的,只有在接近生產環境下真正進行了壓力測試,才能得出cobar性能好壞的結論。
四)、事務問題
分布式數據庫要實現事務是比較困難的,很多對數據一致性要求不是很嚴格的場景都放棄了強一致性,而力求達到最終一致性。Cobar對於單庫的事務是完全支持的,但是對於分布式事務不保證強一致性,分布式事務采用兩階段執行,即分為執行階段和提交階段。
執行階段:把前端連接上當前事務所使用到的后端連接綁定下來,並執行SQL語句。
- 提交階段:將commit命令分發到這些綁定的后端連接中。
- 在整個事務過程中,執行階段出錯,可以回滾。提交階段出錯不可以回滾。可以說只要是commit之前,執行出現不一致,cobar會自動回滾。
cobar的分布式事務具體做到什么程度,在實際應用前還是需要測試的。
五)、主從備份問題
Cobar支持基於MySQL的心跳(heartbeat)來實現主備機切換,當檢測到主機心跳異常,會自動或手動切換到備機,但是故障排除后切換回主機需要手動,除非備機心跳也異常。
主從復制的過程中一致性的保證也是需要注意的問題。
六)、數據遷移問題
當MySQL集群需要擴容時,就可能需要數據遷移,Cobar本身沒有對數據遷移有很大的支持,也不支持mysqldump備份,需要備份時,必須在每個物理分庫進行dump。數據遷移需要應用程序的DAO和Cobar還有后台遷移程序共同配合完成。
五、總結
通過對cobar的一系列探究,對其有了一定的認識,但是對於這個擁有800個源文件的頂尖數據庫開源項目來說,還遠遠不夠。單就應用來說,binlog同步的問題,事務一致性測試的問題,壓力測試的問題,路由算法的問題,數據遷移的問題都是需要深入探討研究的。
Cobar在阿里3年的穩定運行,能夠說明它是個成熟的項目,但是同時要意識到,它是契合阿里特定的業務的項目,任何的遷移都是需要論證的;而且在阿里的數據庫中間件中,cobar只是上下游中的一環,有可靠的VIP設備,有跨機房同步的數據同步中間件,有先進的分布式消息系統,才能使cobar揚長避短。
所以,cobar在實際項目中應用是可行的,但是應用過程中的問題是需要深入思考的。