1. 程式人生 > >跨時代的分散式資料庫 – 阿里雲DRDS詳解

跨時代的分散式資料庫 – 阿里雲DRDS詳解

隨著網際網路時代的到來,計算機要管理的資料量成指數級別的飛速上漲。而我們完全無法對使用者數做出準確的預估,我們的系統所需要支援的使用者數很可能在短短的一個月內突然爆發式的增長几千倍,資料也很可能快速的從原來的幾百GB飛速上漲到了幾百個TB。如果在這爆發的關鍵時刻,系統不穩定或無法訪問,那麼對於業務將會是毀滅性的打擊。

伴隨著這種對於系統性能、成本以及擴充套件性的新需要,以Hbase、MongoDB為代表的NoSQL資料庫和以阿里DRDS、VoltDB、ScaleBase為代表的分散式NewSQL資料庫如雨後春筍一般的不斷湧現出來。DRDS就是其中的翹楚,今天我們一起來揭開它神祕的面紗。

本篇文章來自阿里巴巴的高階專家王晶昱,他是淘寶分散式資料層(TDDL)作者,曾經參與過淘寶大部分的資料庫架構升級工作,具備豐富的一線實戰經驗。本文將會介紹DRDS的技術理念、發展歷程,技術特性介紹等內容。

DRDS的前世今生

阿里分散式資料庫(DRDS)的前身是淘寶分散式資料庫層(TDDL),他淘寶內部使用最為廣泛的一套分散式資料庫中介軟體。如果您看過子柳校長寫過的《淘寶技術這十年》,也就一定會對裡面的 “頭都大了”( TDDL) 有一定印象吧。

從上世紀70年代關係資料庫創立開始,其實大家在資料庫上的追求就從未發生過變化:更快的存取資料,可以按需擴縮以承載更大的訪問量和更大的資料量,開發容易,硬體成本低,我們可以把這叫做資料庫的領域的聖盃。

為了支撐更大的訪問量和資料量,我們必然的需要分散式的資料庫系統,然而分散式系統又必然的會面對強一致性所帶來的延遲提高的問題,因為網路通訊本身比單機內通訊代價高很多,這種通訊的代價就會直接增加系統單次提交的延遲。延遲提高會導致鎖持有時間變長,使得高衝突條件下分散式事務的效能不升反降(這個具體可以瞭解一下Amdahl定律),甚至效能距離單機資料庫都還有明顯的差距。

從上面的說明,我們可以發現,問題的關鍵並不是分散式事務做不出來,而是做出來了卻因為效能太差而沒有什麼卵用。資料庫領域的高手們努力了40年,但至今仍然沒有人能夠很好地解決這個問題,google spanner的開發負責人就經常在他的blog上談論延遲的問題,相信也是飽受這個問題的困擾。

面對這個難題,傳統的關係資料庫選擇了放棄分散式的方案,因為在上個世紀70~80年代,我們的資料庫主要被用來處理企業內的各類資料,面對的使用者不過幾千人,而資料量最多也就是TB級別。用單臺機器來處理事務,用個磁碟陣列處理一下磁碟容量不夠的問題,基本上就能解決一切問題了。

然而,資訊化和網際網路的浪潮,改變了這一切,我們突然發現,我們服務的物件發生了根本性變化,從原來的幾千人,變成了現在的幾億人,資料量也從TB級別到了PB級別甚至更多。存在單點的單機系統無論如何努力,都會面對系統處理能力的天花板。原來的這條路,看起來是走不下去了,我們必須想辦法換一條路來走。

然而,分散式資料庫所面對的強一致性難題卻像一座高山,人們努力了無數個日日夜夜,但能翻越這座山的日子看來卻仍然遙遙無期。

於是,有一群人覺得,這件事看來不怎麼靠譜,那徹底繞開這個問題是不是個更好的選擇? 我們發現確實有那麼一些場景是不需要強一致事務的,甚至連SQL都可以不要,例如日誌流水的記錄與分析這類場景就很明顯。而去掉了事務和SQL,系統做擴充套件性和效能就更容易做起來,這就是NoSQL系統的起源。

雖然NoSQL解決了效能和擴充套件性問題,但是這種繞開問題的方法給應用帶來了很多的困擾,系統的開發成本也有很大的提升。這時候就有另外一群人,他們覺得使用者需要SQL,覺得使用者也需要事務,問題的關鍵在於我們要努力的往聖盃的方向不斷地前進。在保持系統的擴充套件性和效能的前提下,付出儘可能小的代價來滿足業務對資料庫的需要。 這就是NewSQL這個理念的由來。

DRDS也是一個NewSQL的系統,他與ScaleBase、VoltDB等系統類似,都希望能夠找到一條又能保持系統的高擴充套件性和高效能,又能儘可能的保持傳統資料庫的ACID事務和SQL特性的分散式資料庫系統。

DRDS 發展歷程

在一開始,TDDL的主要功能就是做資料庫切分的,一個或一組SQL請求提交到TDDL,TDDL進行規則運算後得知SQL應該被分發到哪個機器,直接將SQL轉發到對應機器即可(如下圖)。

開始的時候,這種簡單的路由策略是能夠滿足使用者的需要的,我們開始的那些應用就是通過這樣非常簡單的方式就完成了他所有的應用請求。我們也認為,這種方案簡單可靠,已經足夠好用了。

然而,當我們服務的應用從十幾個增長到幾百個的時候,大量的中小應用加入,大家紛紛表示,原來的方案限制太大,很多應用其實只是希望做個讀寫分離,希望能有更好的SQL相容性。

於是,我們做了第一次重大升級,在這次升級裡,我們提出了一個重要的概念就是三層架構,Matrix對應資料庫切分場景,對SQL有一定限制,Group對應讀寫分離和高可用場景,對SQL幾乎沒有限制。如圖所示:

這種做法立刻得到了大家的認可,TDDL所提供的讀寫分離、分庫分表等核心功能也成為了阿里集團內資料庫領域的標配元件,在阿里的幾乎所有應用上都有應用。最為難得的是,這些功能從上線後,到現在已經經歷了多年雙11的嚴酷考驗,從未出現過嚴重故障(p0,p1級別故障屬於嚴重故障)。資料庫體系作為整個應用系統的重中之重,能做到這件事真的是非常的不容易。

隨著核心功能的穩定,自2010年開始,我們的全部精力就開始關注於TDDL的後端運維繫統的完善與改進性工作。在DBA團隊的給力配合下,圍繞著TDDL,我們成功的做到了線上資料動態擴縮、非同步索引等關鍵特徵,同時也比較成功的構建了一整套的分散式資料庫服務管控體系,使用者可以基本上完全自助的完成整套資料庫環境的搭建與初始化工作。

大概是在2012年的時候,我們在阿里雲團隊的支援下,開始嘗試將TDDL這套體系輸出到阿里雲上,也有了個新的名字:阿里分散式資料庫服務(DRDS),希望能夠用我們的技術服務好更多的人。

不過當我們滿懷自信的把自己的軟體拿到雲上的時候,卻發現我們的軟體距離使用者的要求差距很大。在內部因為有DBA的同學們幫助進行SQL review,所以SQL的複雜度都是可控的。然而,到了雲上,我們看了各種渠道提過來的相容性需求。經常是不自覺的發出這樣的感嘆:“啊?原來這種語法MySQL也是可以支援的?” T_T …

於是,我們又進行了架構升級,這次是以相容性為核心目標的系統升級工作,希望能夠在分散式場景下支援各類複雜的SQL,同時也將阿里這麼多年來在分散式事務上的積累也都帶到了DRDS裡面。

這次架構升級,我們的投入史無前例,用了三年多才將整個系統落地完成。我們先在內部以我們自己的業務作為首批使用者上線,經過了內部幾百個應用的嚴酷考驗以後,我們才敢拿到雲上,給到我們的終端使用者使用。

目前,我們正在將TDDL中更多的積累輸出到雲上,同時也在努力的優化我們的使用者介面。PS:其實使用者介面優化對我們這種專注於高效能後端技術的團隊來說,才是最大的技術挑戰啊,連我也去學了AngularJS參與了使用者UI編寫啊。

DRDS 主要功能介紹

發展歷史看完了,下面就由我來介紹一下目前我們已經輸出到雲上的主要功能吧。

分散式SQL執行引擎

分散式SQL引擎主要的目的就是實現與單機資料庫SQL引擎的完全相容。目前我們的SQL引擎能夠做到與MySQL的SQL引擎全相容,包括各類join和各類複雜函式等。他主要包含SQL解析、優化、執行和合並四個流程,如下圖綠色部分:

雖然SQL是相容的,但是分散式SQL執行演算法與單機SQL的執行演算法卻完全不同,原因也很簡單,網路通訊的延遲比單機內通訊延遲的大得多。舉個例子說明一下,我們要從一張紙A上抄寫全部內容到另外一張紙B上,單機系統就好比兩張紙都在同一個辦公室裡,而分散式資料庫則就像是一張紙在北京,一張紙在杭州。

自然的,如果兩張紙在同一個辦公室,因為傳輸距離近,逐行抄寫的效率是可以接受的。而如果距離是北京到杭州,用逐行抄寫的方式就立刻顯得代價太高了,如果千辛萬苦的飛去杭州,卻只能寫下一行資料,那這麼抄寫明顯的效率太低了~在這種情況下,還是把紙A上的資訊拍個照片,把這張照片帶到杭州再去抄寫明顯更簡單一些。這就是分散式資料庫特別強調吞吐調優的原因,只要是涉及到跨機的所有查詢,都必須儘可能的積攢一批後一起傳送,以減少系統延遲提高帶來的不良影響。

按需資料庫叢集平滑擴縮

DRDS允許應用按需將新的單機儲存加入或移出叢集,DRDS則能夠保證應用在遷移流程中實現不停機擴容縮容。

在內部的資料庫使用實踐中,這個功能的一個最重要應用場景就是雙11了。在雙11之前,我們會將大批的機器加入到我們的資料庫叢集中,抗過了雙11,這批機器就會下線。

當DRDS來到雲上,我們發現雙11其實不僅僅只會影響阿里內部的系統。在下游的各類電商輔助性系統其實也會面對巨大壓力。在雙11前5天,網聚寶的熊總就找到我說,擔心撐不過雙11的流量,怕系統掛。於是我們就給他介紹了這個自動擴容的功能怎麼用,他買了一個月的資料庫,掛接在DRDS上。資料庫能力立刻翻倍,輕鬆抗過了雙11,也算是我印象比較深刻的一個案例了。

因為我們完全無法預測在什麼時間點系統會有爆發性的增長,而如果在這時候系統因為技術原因不能使用,那麼就會給整個業務帶來毀滅性的影響,風口一旦錯過,那就追悔莫及了。我想這就是雲端計算特別強調可擴充套件能力的原因吧。

小表廣播

小表廣播也是我們在分散式資料庫領域內最常用的工具之一,他的核心目的其實都是一個 – 儘可能讓查詢只發生在單機

讓我們用一個例子來說明,小表廣播的一般使用場景吧:

上面這是兩張表,如果我想知道買家id等於0的使用者在商城裡面買了哪些商品的話,我們一般會先將這兩個表join起來,然後再用 where 平臺名=”商城” and buyerID = 0 找到符合要求的資料。然而這種join的方式,會導致大量的針對左表的網路IO。如果要取出的資料量比較大,系統的延遲會有明顯的上升。

這時候,為了提升效能,我們就必須要減少跨機join的網路代價。我們比較推薦應用做如下處理,將左表複製到右表的每一個庫上。這樣,join操作就由分散式join一下變回到本地join,系統的效能就有很大的提升了。

分散式事務套件

在阿里巴巴的業務體系中存在著非常多的需要事務類的場景,下單減庫存,賬務,都是事務場景最集中的部分。

而我們處理事務的方法卻和傳統應用處理事務的方案不大一樣,我們非常強調事務的最終一致性和非同步化。利用這種方式,能夠極大的降低分散式系統中鎖持有的時間,從而極大地提升系統的效能。

這種處理機制是我們分散式事務能夠以極低成本大量執行的最核心法門。在DRDS平臺內,我們將這些方案產品化為了DRDS的分散式事務解決套件。

利用他們,能夠讓你以比較低的成本,實現低延遲,高吞吐的分散式事務場景。

DRDS的未來

阿里分散式資料庫服務DRDS上線至今,大家對這款產品的熱情超出了我們的預期,短短的半年內已經有幾千個申請。

儘管還在公測期,但是大家就已經把關係到身家性命的寶貴資料業務放到了DRDS上,我能夠感受到這份沉甸甸的信賴,也不想辜負這份信賴。

經過阿里內部幾千個應用的不斷歷練,DRDS已經積累出了一套強大的分散式SQL執行引擎和和一整套分散式事務套件。

我也相信,這些積累能夠讓使用者在基本保持單機資料庫的使用習慣的前提下,享受到分散式資料庫高效能可擴充套件的好處。

在平時的DRDS支援過程中,我面對最多的問題就是,DRDS能不能夠在不改變任何原有業務邏輯和程式碼的前提下,實現可自由伸縮和擴充套件呢?十分可惜的是,關係資料庫發展至今,還沒有找到既能保留傳統資料庫一切特性,又能實現高效能可擴充套件資料庫的方法。

然而,雖不能至,吾心嚮往之!我們會以“可擴充套件,高效能”為產品核心,堅定地走在追尋聖盃的路上,並堅信最終我們一定能夠找尋到他神聖的所在。