數據庫中間件Cobar功能探究


一、 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在實際項目中應用是可行的,但是應用過程中的問題是需要深入思考的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM