1. 程式人生 > >資料庫中介軟體tddl與mycat使用總結

資料庫中介軟體tddl與mycat使用總結

做訂單中心專案的時候正好涉及到了資料庫中介軟體,翻了翻以前的筆記,整理下曾經學習使用過的兩款中介軟體,嗯,簡要總結下。

tddl是淘寶在幾年前推出的一款基於客戶端分片的資料庫訪問中介軟體,mycat(社群活躍)是開源社群基於服務端分片推出的資料庫中介軟體,具體的介紹百度上都有,這裡我主要根據自己的實際使用情況來總結下其異同以及優缺點:

1,基於客戶端分片的方案應該是資料庫分片方案中最快的,它以jar包的形式提供給客戶端使用,沒有中介軟體,僅需要客戶端進行一次計算(如取模等),但這同樣是其缺點,與業務端耦合了(不過tddl jar很輕量,應該還好)。還有個問題就是升級比較困難,如果jar升級了,需要挨個業務線去推動升級,可能阻力比較大,從該點看,tddl適合業務場景固定,功能變動可能性很小的地方

2,基於客戶端的分片不需要額外的proxy,不需要關注proxy機器的部署和維護,對於mycat來說,多了代理層,需要自己做負載均衡方案,因為代理層不是無狀態的。

3,tddl不能強制讀主,需要自己開發這個功能,mycat提供了強制讀主的hint

4,如果進行了讀寫分離,寫完後立即要進行讀操作,這時候從庫可能還沒有同步到資料,這種場景下是需要讀主的,tddl不支援這種場景,需要自己開發,mycat提供了策略解決這個問題,如下:

Mycat 心跳機制通過檢測 show slave status 中的 "Seconds_Behind_Master","Slave_IO_Running","Slave_SQL_Running",三個欄位來確定當前主從同步的狀態以及 Seconds_Behind_Master 主從複製時延。當 Seconds_Behind_Master > slaveThreshold 時,讀寫分離篩選器會過濾掉此 Slave 機器,防止讀到很久之前的舊資料。

5,tddl和mycat都支援帶有權重的讀寫分析操作

6,tddl以jar的方式提供訪問,只能給java使用,mycat沒有這個限制

7,mycat支援多個分片自動路由和聚合,tddl不支援,比如:select * from order,mycat會分發到所有的節點,然後將返回值進行聚合,所以諸如count,sum,max等函式在mycat下是支援的

8,join誇庫連表查詢tddl不支援,mycat可以跨庫支援兩個表的join(其實要想實現join,一種方式是採用caltlet,另一箇中方式就是er分片了(這種方式下也不能算做支援跨庫),還有就是全域性表(這個方案是個冗餘資料的方案,不具有可比性),如果純粹像原來單庫那樣查詢的話,會存在問題,見下面例子),多表的話要基於caltlet實現,需要自己開發,例子:

分庫資訊為db01,db02兩個庫,配置如下:

mod(2)方式分片,兩張表travelrecord和user,首先在mycat中insert一條資料到travelrecord:

接下來insert兩條資料到user:

然後執行sql:select * from travelrecord t join user u on u.travelrecord_id=t.id where t.id>1;得到如下結果:

可以看到滿足條件的只有一條記錄,這是應為traverecord_id=1054698916794208257只存在於一個分片上 。接下來我們採用er分片的方式,配置如下:

重新向兩張表插入資料,最終結果如下:

這是由於在插入user的時候選擇了與traverecord_id相同的分片,從這個角度看mycat實際上也不支援跨庫join查詢!!!最後我們來看下使用Catlet:

這個方案可以說算是真正支援跨庫join的方案,它其實是會分成兩條sql執行:

1,select *, id from travelrecord where id>1

2,select * from user where travelrecord_id in (1055292098535886849)

1055292098535886849為第一條sql的查出來的id,然後對結果進行聚合。

不過個人認為,既然都分片了,最好就不要在sql中使用join,想其他方案替代吧。如果一定要用的話,最好在生產應用前測試下使用Catlet方式的效能。

9, tddl支援既分庫又分表,而mycat當前(1.6)還不支援(需要自己開發?),tddl的分庫分表配置例子如下:

<bean id="userOrderRule" init-method="init" class="com.taobao.tddl.common.config.beans.TableRule">
        <property name="dbIndexes"
                  value="ds0,ds1"/>
        <property name="dbRuleArray">
            <list>
                <value>((int)(#user_id# /2))%2</value>
            </list>
        </property>
        <property name="tbRuleArray">
            <list>
                <value>#user_id# % 2</value>
            </list>
        </property>
        <property name="tbSuffix" value="resetForEachDB:[_00-_01]"/><!--兩張表-->
        <property name="disableFullTableScan" value="true"/>
    </bean>

上面的例子按照user_id/2%2進行分庫,user_id%2進行分表

10,mycat預設提供了多種分片的方式,tddl的支援的分片方式有限(可自己改程式碼實現自己的分片方式)

11,tddl只支援單庫事務,mycat號稱支援分散式事務(支援有限,基於session),首先來看如下的事務操作(普通的begin,commit):

兩個insert分別在兩個節點上進行,mycat在執行begin時,會設定autocommit=false,在執行insert時傳遞過去,分別讓兩個節點執行insert,commit提交後,再分別在兩個節點上執行commit。從這裡我們可以看出來,如果其中任意一個節點commit時失敗了,是沒法回滾另一個節點的(已經成功commit)。至於xa協議,實際上是開啟了mysql對xa的支援,mycat還是作為一個發號時令者,實際應用用的分散式事務需要採用專門的方案來解決,恩,比較少使用到xa。

12,tddl擴容時需要停機,修改配置檔案,然後重啟應用,mycat號稱可以線上擴容(基於zk),不過我們沒有使用過,以後如果有機會使用了再來補充

總之個人認為,在使用這些中介軟體時,需要根據你的業務場景,提取出涉及到的sql,看下實際執行中是否有問題(嚴格測試),如果無法支援得想替代方案或者改原始碼。

其他特性或者功能目前本人也沒有用過,以後如果有用到後再來補充。