前言mysql
在開始講解淘寶的TDDL(Taobao Distribute Data Layer)技術以前,請容許筆者先吐槽一番。首先要開噴的是淘寶的社區支持作的無比的爛,TaoCode開源社區上面,幾乎歷來都是有人提問,無人響應。再者版本迭代速度也一樣差強人意,就目前而言TDDL5.0的版本已經全線開源(Group、Atom、Matrix)你們能夠在Github上下載源碼。sql
目錄數據庫
1、互聯網當下的數據庫拆分過程架構
2、TDDL的架構原型併發
3、下載TDDL的Atom層和Group層源代碼oracle
4、Diamond簡介框架
5、Diamond的安裝和使用函數
6、動態數據源層的Master/Salve讀寫分離配置與實現高併發
7、Matrix層的分庫分表配置與實現(此章節因爲特殊緣由暫時隱藏)性能
1、互聯網當下的數據庫拆分過程
對於一個剛上線的互聯網項目來講,因爲前期活躍用戶數量並很少,併發量也相對較小,因此此時企業通常都會選擇將全部數據存放在一個數據庫中進行訪問操做。但隨着後續的市場推廣力度不斷增強,用戶數量和併發量不斷上升,這時若是僅靠一個數據庫來支撐全部訪問壓力,幾乎是在自尋死路。因此一旦到了這個階段,大部分Mysql DBA就會將數據庫設置成讀寫分離狀態,也就是一個Master節點對應多個Salve節點。通過Master/Salve模式的設計後,徹底能夠應付單一數據庫沒法承受的負載壓力,並將訪問操做分攤至多個Salve節點上,實現真正意義上的讀寫分離。但你們有沒有想過,單一的Master/Salve模式又能抗得了多久呢?若是用戶數量和併發量出現量級上升,單一的Master/Salve模式照樣抗不了多久,畢竟一個Master節點的負載仍是相對比較高的。爲了解決這個難題,Mysql DBA會在單一的Master/Salve模式的基礎之上進行數據庫的垂直分區(分庫)。所謂垂直分區指的是能夠根據業務自身的不一樣,將本來冗餘在一個數據庫內的業務表拆散,將數據分別存儲在不一樣的數據庫中,同時仍然保持Master/Salve模式。通過垂直分區後的Master/Salve模式徹底能夠承受住不可思議的高併發訪問操做,可是否能夠永遠高枕無憂了?答案是否認的,一旦業務表中的數據量大了,從維護和性能角度來看,不管是任何的CRUD操做,對於數據庫而言都是一件極其耗費資源的事情。即使設置了索引,仍然沒法掩蓋由於數據量過大從而致使的數據庫性能降低的事實,所以這個時候Mysql DBA或許就該對數據庫進行水平分區(分表,sharding),所謂水平分區指的是將一個業務表拆分紅多個子表,好比user_table0、user_table一、user_table2。子表之間經過某種契約關聯在一塊兒,每一張子表均按段位進行數據存儲,好比user_table0存儲1-10000的數據,而user_table1存儲10001-20000的數據,最後user_table3存儲20001-30000的數據。通過水平分區設置後的業務表,必然可以將本來一張表維護的海量數據分配給N個子表進行存儲和維護,這樣的設計在國內一流的互聯網企業比較常見,如圖1-1所示:
圖1-1 水平分區
上述筆者簡單的講解了數據庫的分庫分表原理。接下來請你們認真思考下。本來一個數據庫可以完成的訪問操做,如今若是按照分庫分表模式設計後,將會顯得很是麻煩,這種麻煩尤爲體如今訪問操做上。由於持久層須要判斷出對應的數據源,以及數據源上的水平分區,這種訪問方式咱們稱之爲訪問「路由」。按照常理來講,持久層不該該負責數據訪問層(DAL)的工做,它應該只關心one to one的操做形式,因此淘寶的TDDL框架誕生也就順其天然了。
2、TDDL的架構原型
淘寶根據自身業務需求研發了TDDL(Taobao Distributed Data Layer)框架,主要用於解決分庫分表場景下的訪問路由(持久層與數據訪問層的配合)以及異構數據庫之間的數據同步,它是一個基於集中式配置的JDBC DataSource實現,具備分庫分表、Master/Salve、動態數據源配置等功能。
就目前而言,許多大廠也在出一些更加優秀和社區支持更普遍的DAL層產品,好比Hibernate Shards、Ibatis-Sharding等。若是你要問筆者還爲何還要對TDDL進行講解,那麼筆者只能很無奈的表示公司要這麼幹,由於不少時候技術選型並非筆者說了算,而是客戶說了算。當筆者費勁全部努力在google上尋找TDDL的相關使用說明和介紹時,內心一股莫名的火已經開始在蔓延,對於更新緩慢(差很少一年沒更新過SVN),幾乎沒社區支持(提問從不響應)的產品來講,除了蝸居在企業內部,一定走不了多遠,最後的結局註定是悲哀的。好了,既然抱怨了一番,不管如何仍是要堅持講解完。TDDL位於數據庫和持久層之間,它直接與數據庫創建交道,如圖1-2所示:
圖1-2 TDDL所處領域模型定位
傳說淘寶很早之前就已經對數據進行過度庫分表處理,應用層鏈接多個數據源,中間有一個叫作DBRoute的技術對數據庫進行統一的路由訪問。DBRoute對數據進行多庫的操做、數據的整合,讓應用層像操做一個數據源同樣操做多個數據庫。可是隨着數據量的增加,對於庫表的分法有了更高的要求,例如,你的商品數據到了百億級別的時候,任何一個庫都沒法存放了,因而分紅2個、4個、8個、16個、32個……直到1024個、2048個。好,分紅這麼多,數據可以存放了,那怎麼查詢它?這時候,數據查詢的中間件就要可以承擔這個重任了,它對上層來講,必須像查詢一個數據庫同樣來查詢數據,還要像查詢一個數據庫同樣快(每條查詢要求在幾毫秒內完成),TDDL就承擔了這樣一個工做(其餘DAL產品作得更好),如圖1-3所示:
圖1-3 TDDL分庫分表查詢策略
上述筆者描述了TDDL在分庫分表環境下的查詢策略,那麼接下來筆者有必要從淘寶官方copy它們本身對TDDL優勢的一些描述,真實性不敢保證,畢竟沒徹底開源,和社區零支持,你們看一看就算了,別認真。
淘寶人自定的TDDL優勢:
1、數據庫主備和動態切換;
2、帶權重的讀寫分離;
3、單線程讀重試;
4、集中式數據源信息管理和動態變動;
5、剝離的穩定jboss數據源;
6、支持mysql和oracle數據庫;
7、基於jdbc規範,很容易擴展支持實現jdbc規範的數據源;
8、無server,client-jar形式存在,應用直連數據庫;
9、讀寫次數,併發度流程控制,動態變動;
10、可分析的日誌打印,日誌流控,動態變動;
注意:
TDDL必需要依賴diamond配置中心(diamond是淘寶內部使用的一個管理持久配置的系統,目前淘寶內部絕大多數系統的配置)。
接下來,筆者將會帶領各位一塊兒分析TDDL的體系架構。TDDL其實主要能夠劃分爲3層架構,分別是Matrix層、Group層和Atom層。Matrix層用於實現分庫分表邏輯,底層持有多個Group實例。而Group層和Atom共同組成了動態數據源,Group層實現了數據庫的Master/Salve模式的寫分離邏輯,底層持有多個Atom實例。最後Atom層(TAtomDataSource)實現數據庫ip,port,password,connectionProperties等信息的動態推送,以及持有原子的數據源分離的JBOSS數據源)。
圖1-4 TDDL體系結構
章節的最後,咱們還須要對TDDL的原理進行一次剖析。由於咱們知道持久層只關心對數據源的CRUD操做,而多數據源的訪問,並不該該由它來關心。也就是說TDDL透明給持久層的數據源接口應該是統一且「單一」的,至於數據庫到底如何分庫分表,持久層無需知道,也無需編寫對應的SQL去實行應對策略。這個時候對TDDL一些疑問就出現了,TDDL須要對SQL進行二次解析和拼裝嗎?答案是不解析僅拼裝。說白了TDDL只須要從持久層拿到發出的SQL
再按照一些分庫分表條件,進行特定的SQL擴充以此知足訪問路路由操做。
如下是淘寶團隊對TDDL的官方原理解釋:
一、TDDL除了拿到分庫分表條件外,還須要拿到order by、group by、limit、join等信息,SUM、
MAX、MIN等聚合函數信息,DISTINCT信息。具備這些關鍵字的SQL將會在單庫和多庫狀況下進行,語義是不一樣的。TDDL必須對使用這些關鍵字的SQL返回的結果作出合適的處理;
二、TDDL行復制須要從新拼寫SQL,帶上sync_version字段;
三、不經過sql解析,由於TDDL遵照JDBC規範,它不可能去擴充JDBC規範裏面的接口,因此只能經過SQL中加額外的字符條件(也就是HINT方式)或者ThreadLocal方式進行傳遞,前者使SQL過長,後者難以維護,開發debug時不容易跟蹤,並且須要斷定是在一條SQL執行後失效仍是1個鏈接關閉後才失效;
四、TDDL如今也同時支持Hint方式和ThreadLocal方式傳遞這些信息;