資料庫中介軟體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,看下實際執行中是否有問題(嚴格測試),如果無法支援得想替代方案或者改原始碼。
其他特性或者功能目前本人也沒有用過,以後如果有用到後再來補充。