簡介:TDDL(Tabao Distributed Data Layer)是淘寶開源的一個用於存取資料庫的中介軟體,整合了分庫分表,主備,讀寫分離,權重調配,動態資料庫設定等功能。本文以2007年TDDL初誕生時的視角,介紹TDDL是如何一步步設計成型的,希望能幫助同學們簡單收穫:常規資料庫效率問題解決思路、TDDL框架設計基本思路以及分散式資料庫設計思路等。
一覺醒來,我還是照常去上班,走到西溪溼地附近,馬路沒有,高樓沒有,有的是小山坡和金色的稻田。一番打聽之後,才知道此時沒有什麼西溪園區。沒辦法,硬著頭皮去濱江上班,一刷卡,才發現我並不是我,我現在的身份是淘寶資料庫團隊的核心成員。
此時全國上下在迎接著奧運的到來,一片祥和。淘寶網成交額突破400億,日活使用者達1000萬。工程師們都非常興奮,磨刀霍霍。但是也遇到了棘手的問題。
1.2.1 使用者體驗與反饋
使用者普遍反饋逛淘寶卡頓,操作延遲特別明顯。
1.2.2 分析核心原因
1.2.3 總結問題
高築牆,廣積糧,積極做好準備。
提煉核心:
為實現以上兩大目標,我能做什麼?
提煉常見的通用方法:
sql優化
下推的目的:提前過濾資料 -> 減少網路傳輸、平行計算。
建立索引
分庫分表
讀寫分離
快取的使用
等等。
必須支援動態擴容。
必須走分散式化路線,百分百不動搖。
3.3.1 分析我們的架構定位
(1)大前提
說明:大修改就意味著不穩定,因此:我們要做到儘可能少的修改原來的程式碼。在程式需要進行拓展的時候,不能去修改原有的程式碼,實現一個熱插拔的效果。
(2)當前架構現狀
淘寶網主要使用hibernate/ibatis傳統框架:
(3)分析我們的架構定位
淘寶資料庫團隊當時使用對映框架(hibernate/ibatis)作為資料庫互動入庫,為了不讓他們修改程式碼,那我們只能在ibatis/hibenate這類對映框架之下。
同時jdbc是與底層資料庫互動的Java資料庫連線驅動程式,是基礎能力,我們要使用它,而不是改造它。
結論:我得把TDDL安插於ibatis/jdbc之間,於是有了第一張架構圖:
結合我們的目標,通用方法,大前提以及架構定位,分析下我們能做和不能做的。
不能做的:
能做的:
為達到語法優化的目的,我們需要具備什麼能力?
簡單來說:
專業點來說:語意分析能力。
因此:我們需要設計一個sql解析器,sql優化器。
4.1.1 解析器
解析器的核心是詞法分析、語法語意分析,也就是說來了一條 select/update/insert/delete語句,你能認識它,而且你知道下一步該怎麼處理,同時為後面的優化器打下基礎。
核心:將sql解析為一棵語法樹。
例:
SELECT id, member_id FROM wp_image WHERE member_id = ‘123’
sql語法樹:
4.1.2 優化器
核心:
(1)語法優化
a. id = 1 + 1 => id = 2
1 = 1 and id = 1 => id = 1
0 = 1 and id = 1 => 空結果
id > 1 or id < 5 => 永真式
id > 1 and id = 3 => id = 3
id = ‘1’ => id為數位型別,自動Long.valueof(1)
create=‘2015-02-14 12:12:12’ => create為timestamp型別,解析為時間型別
(2)下推優化
select from (A) o where o.id = 1
=>
select from (A.query(id = 1))
說明:提前條件過濾,提前獲取資料,減少後期計算/IO/網路成本。
A join B on A.id = B.id where A.name = 1 and B.title = 2
=>
A.query(name = 1) join B.query(title = 2) on A.id = B.id
說明:提前過濾,減輕後期join計算成本,達到「小表驅動」的目的。
A join B on A.id = B.id where A.id = 1 => B.id = 1
=>
A join B.query(B.id=1) on A.id = B.id
說明:同理,提前過濾。
4.1.3 總結
單庫單表的問題:
幾年前,業務簡單,應用的資料比較少,表結構也不復雜。只有一個資料庫,資料庫中的表是一張完整的表。而到了今天,2007年了,業務複雜起來了,資料量爆增,單表資料破千萬甚至上億條,一條DML語句,死慢死慢的。這種情況下加索引已不再有顯著的效果。
這個時候,資料庫效率瓶頸不是靠加索引,sql優化能搞定的。
正確出路:分表分庫,通過將表拆分,來降低單表資料量,進而提高資料庫操作效率。
分表分為:
分庫分為:
由於TDDL不參與業務,而垂直分庫分表是強業務相關的,因此TDDL暫不參與垂直分庫分表,只在水平分庫分表方向上努力。
4.2.1 垂直分表
垂直拆分是將一張表垂直拆成多個表。往往是把常用的列獨立成一張主表。不常用的列以及特別長的列拆分成另一張拓展表。
簡單垂直分表舉例
核心要素:
它帶來的提升是:
4.2.2 水平分表
水平分表是在同一個資料庫內,把同一個表的資料按一定規則拆到多個表中。
簡單點的技巧:按照列舉型別區分。
作用總結:
4.2.3 垂直分庫
垂直分庫是指按照業務將表進行分類,分佈到不同的資料庫上面,每個庫可以放在不同的伺服器上,它的核心理念是專庫專用。
作用總結:
4.2.4 水平分庫(TDDL 核心)
水平分庫是把同一個表的資料按一定規則拆到不同的資料庫中,每個庫可以放在不同的伺服器上。
作用總結:
水平分庫核心要解決的問題:
4.2.5 水平分庫——問題解決
(1)自動路由演演算法
sql轉發:在水平拆分後,資料被分散到多張表裡。原來的一個sql需要拆解,進行轉發路由。
例:
select * from tb1 where member_id in ('test1234', 'pavaretti17', 'abcd');
=>
select * from tb1 where member_id in ('test1234', 'pavaretti17', 'abcd');
select * from tb1 where member_id in ('abcd');
其中拆分和尋找的演演算法:怎麼知道對應哪個表?即自動路由演演算法。常見的有:固定雜湊演演算法和一致性雜湊演演算法。
a)固定雜湊演演算法
b)一致性雜湊演演算法
一致性雜湊演演算法在1997年由麻省理工學院提出,是一種特殊的雜湊演演算法,目的是解決分散式快取的問題。
一致性雜湊演演算法的優勢:
由於一致性雜湊演演算法的優勢,此演演算法幾乎是所有分散式場景下使用的方案,包括mysql的分散式、redis的分散式等。
(2) 結果合併
昇華:引入fork-Join,提升操作速度(多執行緒並行重點場景,程式碼中也很常用哦)。
(3)全域性唯一主鍵
演演算法:基於資料庫更新+記憶體分配。在資料庫中維護一個ID,獲取下一個ID時,會對資料庫進行ID=ID+100 WHERE ID=XX,拿到100個ID後,在記憶體中進行分配。
例:
水平分庫分表:一拆三場景。
主鍵分隔值:1000。
這種產生全域性唯一id的方式相當有效,保證基本的全域性唯一特性和高效能的同時,可以對生成id的資料庫分機架分機房部署達到容災的目的。
4.2.6 分表分庫總結
架構師角度:
個人開發角度:
之所以先垂直拆分才水平拆分,是因為垂直拆分後資料業務清晰而且單一,更加方便指定水平的標準。
分散式化是大潮,是大規模伺服器最後都要走的一步。
4.3.1 讀寫分離
設計讀寫分離的資料庫,有兩大意義:
說明:myisam查詢效率高於預設的innodb效率。參考:myisam和innodb的區別。
核心問題:
4.3.2 容災
主備倒換:提高可靠性 > 應對個別資料庫宕機場景,尤其主庫宕機。
說明:DB2主庫宕機後,自動將主庫轉為DB3。
核心問題:
4.3.3 資料備份與同步
當只有單機或者一份資料時,一但資料庫出問題,那麼整體服務將不可用,而且更嚴重的是會造成資料損害丟失不可逆。
在讀寫分離與主備倒換的場景下,核心要解決的是多個資料庫的資料同步與備份問題。
當前主流的是採用紀錄檔備份方式(redis也類似)。
實現原理:binlog紀錄檔備份。
說明:
4.3.4 動態擴容
動態擴容的意義在於:隨著後期業務量增大,資料庫個數可以通過增多的方式來應對,而相對的改造代價很小。
擴容前:
擴容後:
核心內容:
下圖介紹sql從流入TDD到流入資料庫,期間TDDL各模組對Sql的處理。
下圖介紹了TDDL三層的位置以及作用。
TDDL 核心能力,核心組建示意圖,其中標出了各模組核心要解決功能,核心演演算法等。
參考
TDDL 官方檔案
http://mw.alibaba-inc.com/products/tddl/_book/
TDD產品原理介紹
http://gitlab.alibaba-inc.com/middleware/tddl5-wiki/raw/master/docs/Tddl_Intro.ppt
TDDL(07-10年)初始版本介紹
https://wenku.baidu.com/view/9cb630ab7f1922791788e825.html
阿里雲SQL調優指南
https://help.aliyun.com/document_detail/144293.html
一致性雜湊演演算法原理
https://www.cnblogs.com/lpfuture/p/5796398.html
TDDL初期原始碼(碼雲)
https://gitee.com/justwe9891/TDDL
MyISAM與InnoDB 的區別(9個不同點)
https://blog.csdn.net/qq_35642036/article/details/82820178
原文連結:https://developer.aliyun.com/article/773227?
版權宣告:本文內容由阿里雲實名註冊使用者自發貢獻,版權歸原作者所有,阿里雲開發者社群不擁有其著作權,亦不承擔相應法律責任。具體規則請檢視《阿里雲開發者社群使用者服務協定》和《阿里雲開發者社群智慧財產權保護指引》。如果您發現本社群中有涉嫌抄襲的內容,填寫侵權投訴表單進行舉報,一經查實,本社群將立刻刪除涉嫌侵權內容。