天天看點

騰訊會議核心資料庫TDSQL,如何做到快速無損線上擴容?

引言

自去年12月底釋出後,騰訊會議40天更新14個版本,8天緊急擴容超過10萬台雲主機,投入的計算資源超100萬核。疫情複工期間,每周都有數萬家企業和政府相關機構使用騰訊會議複工複産,通過騰訊會議開拓了雲簽約、雲招标、雲面試、雲教育訓練等雲上協同場景。

騰訊會議這款雲視訊會議産品,日活躍賬戶數已超1000萬,成為目前中國最多人使用的視訊會議專用應用。目前,騰訊會議國際版也已經在超過100個國家和地區上線,助力全球戰疫。

作為騰訊會議核心資料庫,近期騰訊分布式資料庫 TDSQL 持續支撐騰訊會議應對快速增長的存儲容量和性能需求,為使用者提供高速流暢、穩定可靠的服務,在平穩應對流量突增,實作讓使用者無感覺的情況下進行快速無損線上擴容的場景方面提供了最佳實踐案例。

一、不停機無損線性水準擴容

面對流量突增場景,保障系統高可用的第一要務是進行系統擴容,滿足業務的性能和容量需求。

回顧騰訊會議資料庫面對流量突增的過程,作為騰訊會議的重要系統基礎支援,随着流量的持續暴漲,優化之後 TDSQL 進行了一輪快速的資料庫機器水準擴容實踐:

通過 TDSQL 政策豐富的讀寫分離技術,資料庫層面快速響應了持續增長的容量和性能需求。

為了盡可能的将讀請求分離,進一步降低對主節點的影響,TDSQL通過讀寫賬号分離、災備隻讀執行個體等措施,将純隻讀業務分離出來,進一步降低主節點的壓力提高整體的吞吐量。最終,25%的複雜查詢根據讀寫分離政策發往隻讀執行個體,快速達到降低主節點的負載的效果。

健壯的分布事務能力支撐,持續不斷地進行性能優化。

SQLEngine 作為協調節點,無狀态,能滿足業務層幾乎無限制的水準擴容需求。

不停機無損線性水準擴容,保障系統高可用、高性能,資料庫技術架構如何做到?中間有哪些看不見的坑,有沒有經過了實際驗證的最佳方案?

數字化轉型全局發展正在提速,流量洪峰漸成常态****,未來,我們需要怎樣的分布式技術架構系統?

以下我們一一拆解。

二、水準擴容的背景和挑戰

就擴容來說,比較常見的就是兩種方式,一種是垂直擴容,一種是水準擴容。這兩種有不同的特點,優缺點其實也非常明顯。

水準擴容即将資料從一台機器上拆分到多台機器,通過将一台實體機的請求分散到多台來實作吞吐量的提升。垂直擴容是将資料從一台低規格的實體機遷移到一台高規格的裝置,通過實體硬體的提升實作吞吐量的提升。

跟垂直擴容對比,分布式水準擴容最大的優點是解決了垂直擴容的瓶頸問題——理論上水準擴容可以進行無限擴容,它可以通過增加機器的方式來動态适應業務的需求。

水準擴容和垂直擴容相比,它可以解決垂直擴容的問題,但是會引入一些其他的問題。因為水準擴容比垂直擴容更加複雜,下面我們分析下可能遇見的問題,以及介紹TDSQL架構設計的解決方案:

第一,系統經過垂直擴容,其實資料總體還是存在一個節點,一主多備架構中,備機上也存儲着所有資料。而水準擴容過程中資料會進行拆分,這裡面臨的第一個問題是,資料如何進行拆分?因為如果拆分不好,當出現熱點資料時,存儲熱點資料的單獨節點也有可能成為性能的瓶頸。

第二,水準擴容會涉及到資料的搬遷、路由的改變。那麼整個過程中能否做到對業務沒有感覺?或者是對業務的侵入如何盡可能地降低?

第三,擴過程中的諸多步驟,如果其中一步失敗了,如何進行復原?同時,在整個擴容過程中,如何能保證切換過程中資料一緻性?

第四,由于擴容後資料拆分到了各個節點,如何能保證擴容後的性能?在整個水準擴容的過程中,不同的架構或者不同的方式,對性能影響都比較大。

第五,當資料已經拆分成多份,如何繼續保證資料庫分布式的特性?在分布式架構裡,如何保證資料跨節點過程中的全局的一緻性?這個就會涉及到分布式事務。

綜上考慮,水準擴容的優點很明顯,它解決了垂直擴容機器的限制。但是它更複雜,引入了更多的問題。那麼 TDSQL 是如何進行水準擴容,又是如何解決上述問題的呢?

三、TDSQL水準擴容實踐

1. TDSQL架構

首先看TDSQL的架構。TDSQL簡單來說包含幾部分:

第一部分是SQL引擎層:主要是作為接入端,屏蔽整個 TDSQL 後端的資料存儲細節。對業務來說,業務通路的是SQL引擎層。

接下來是由多個Set組成的資料存儲層:分布式資料庫中,資料存儲在各個節點上,每個Set我們當做一個資料單元,可以根據業務需要來部署一主兩備或者一主多備。對于對資料安全性要求更高的業務場景,可以一主三備甚至一主四備。

Scheduler子產品:主要負責整個系統叢集的監控、控制。在系統進行擴容或者主備切換時,Scheduler子產品相當于整個系統的大腦,來對系統進行控制。而對業務來說是無感覺的,業務隻需關注SQL引擎層,不需要關注Scheduler,不需要關注資料是怎麼跨節點,怎麼分成多少個節點等。

2. TDSQL水準擴容過程:一鍵擴容

整個擴容流程總結起來大概是:一開始資料都放在一個Set上,也就是在一個節點裡面。擴容則會把資料擴容到多個節點上。比如有256個Set,就會擴容到256台機器上。整個擴容過程有幾個要點:

一開始雖然資料是在一個節點上,在一台機器上,但是其實資料已經進行了拆分。

水準擴容,簡單來說是将這些分片遷移到其他的Set上,也就是其他的節點機器上,這樣就可以實作增加機器來提供系統性能。

總結來說,資料一開始已經切分好了,擴容過程相當于把分片遷到新的節點,整個擴容過程中,節點數是增加的,可以從1擴到2擴到4,甚至擴到最後可以到256,但是分片數是不變的。一開始256個分片在一個節點上,擴成兩個節點的話,有可能是每128個分片在一個節點上;擴到最後,可以擴到256個節點上,資料在256台機器,每台機器負責其中的一個分片。是以整個擴容簡單來說就是搬遷分片。

無論是在私有雲或公有雲上, TDSQL提供了一個統一的前台頁面,友善使用者使用管理整個資料庫系統。

四、TDSQL水準擴容背後的設計原理

為了保證分布式資料庫系統的資料強一緻性、快速線性水準擴容、高性能、高可用等,解決前文提到的問題,TDSQL架構方案進行了相應的設計。事實上,這些問題不管在哪個系統做水準擴容,都是需要解決的。

1. 設計原理:分區鍵選擇如何兼顧相容性與性能

水準擴容第一個問題是資料如何進行拆分。資料拆分是第一步,将影響後續整個使用過程。

在TDSQL中,資料拆分的邏輯放到一個建立表的文法裡面,需要業務去指定 “shardkey等于某個字段”——業務在設計表結構時需要選擇一個字段作為分區鍵,TDSQL會根據這個分區鍵進行資料拆分,而通路會根據分區鍵進行資料聚合。

我們是希望業務在設計表結構的時候能夠參與進來,指定一個字段作為shardkey。這樣一來,相容性與性能都能做到很好的平衡。

TDSQL也可以做到使用者建立表的時候不指定shardkey,由系統底層随機選擇一個鍵進行資料拆分,但這個會影響後續的使用效率,比如不能特别好地發揮分布式資料庫的使用性能。是以,業務層如果在設計表結構時能有少量參與,可以帶來非常大的性能優勢,讓相容性和性能得到平衡。

除此之外,如果由業務來選擇shardkey——分區鍵,在業務設計表結構的時候,我們可以看到多個表,可以選擇相關的那一列作為shardkey,這樣可以保證資料拆分時,相關的資料是放在同一個節點上的,這樣可以避免很多分布式情況下的跨節點的資料互動。

2. 設計原理:擴容中的高可用和高可靠性

擴容流程比較複雜,那麼整個擴容過程能否保證高可用或者高可靠性,以及對業務無感覺?TDSQL是怎麼做的呢?

(1)資料同步

第一步是資料同步階段。假設我們現在有兩個Set,然後我們發現其中一個Set現在的磁盤容量已經比較危險了,比如可能達到80%以上了,這個時候要對它進行擴容。

我們首先會建立一個執行個體,通過拷貝鏡像、建立執行個體、建立同步關系。建立同步的過程對業務無感覺,而且這個過程是實時同步。

(2)資料校驗

第二階段,則是持續地追平資料,同時持續進行資料校驗。這個過程可能會持續一段時間,對于兩個同步之間的延時差無限接近時——比如我們定一個5秒的門檻值,當我們發現已經追到5秒之内時,這個時候我們會進入第三個階段——路由更新階段。

(3)路由更新

路由更新階段當中,首先我們會當機寫請求,這個時候如果業務有寫過來的話,我們會拒掉,讓業務兩秒後重試——這個時候對業務其實是有秒級的影響。但是這個時間會非常短。

當機寫請求之後,第三個執行個體同步的時候很快就會發現資料全部追上來,并且校驗也沒問題,這個時候我們會修改路由,同時進行相關原子操作,在底層做到存儲層分區屏蔽,這樣就能保證SQL接入層在路由來不及更新的時資料也不會寫錯。因為底層做了改變,分區已經屏蔽了。這樣就可以保證資料的一緻性。

路由一旦更新好以後,第三個Set就可以接收使用者的請求——到了這裡,因為第一個Set和第三個Set已經建立了同步,是以它們兩個是擁有全量資料的。

(4)删除備援資料

最後一步則需要把這些備援資料删掉。删備援資料用的是延遲删除,保證删除過程中可以慢慢删,也不會造成比較大的IO波動,影響現網的業務。

整個删除過程中,我們做了分區屏蔽,同時會在SQL引擎層做SQL的改寫,這樣就能保證:我們在底層雖然有備援資料,但使用者來查的時候即使是一個全掃描,我們也能保證不會多一些資料。

可以看到整個擴容流程,資料同步,還有校驗和删除備援這幾個階段,時間耗費相對來說會比較長,因為要建同步的話,如果資料量比較大,整個拷貝鏡像或者是追binlog這段時間相對比較長。

但是這幾個階段對業務其實沒有任何影響,業務根本就沒感覺到現在新加了一個同步關系。那麼假如在建立同步關系時發現有問題,或者建立備機時出問題了,也完全可以再換一個備機,或者是經過重試,這個對業務沒有影響。

路由更新階段,理論上對業務寫請求難以避免會造成秒級的影響,但我們會将這個影響時間視窗期控制在非常短,因為本身當機寫請求是需要保證同步已經在5秒之内這樣一個比較小的門檻值,同步到這個階段以後,我們才能發起路由更新操作。

同時,我們對存儲層做了分區屏蔽來保證多個子產品之間,如果有更新不同時也不會有資料錯亂的問題。這是一個我們如何保證擴容中的高可用跟高可靠性的,整個擴容對業務影響非常小的原理過程。

3. 設計原理:分布式事務

剛才講的是擴容階段大概的流程,以及TDSQL是如何解決問題的。接下來我們再看擴容完成以後,如何解決剛才說的水準擴容以後帶來的問題。

首先是分布式事務:原子性、去中心化、性能線性增長。

系統本來隻有一個節點,擴容以後,資料是跨節點了,如何保證資料的原子性?我們基于兩階段的送出,實作了分布式事務。對業務屏蔽了整個處理邏輯背後的複雜性,對業務來說使用分布式資料庫就跟使用單機MySQL一樣。

如果業務這條SQL隻通路一個節點,那用普通的事務就可以;如果發現使用者的一條SQL或者一個事務操作了多個節點,我們會用兩階段送出。到最後會通過記日志來保證整個分布式事務的原子性。

同時我們對整個分布式事務在實作過程中做到完全去中心化,可以通過多個SQL來做TM,性能也可實作線性增長。除此之外,TDSQL也做了大量的各種各樣的異常驗證機制,有非常健壯的異常處理和全局的試錯機制,并且通過了TPCC的标準驗證。

4. 設計原理:如何實作擴容中性能線性增長

對于水準擴容來說,資料拆分到多個節點後主要帶來兩個問題:一個是事務原子性的問題,可以通過分布式事務來解決;此外還帶來了性能方面的問題。

垂直擴容中一般是通過更換更好的CPU等方法來實作性能線性增加。對于水準擴容,因為資料拆分到多個節點上,如何才能很好地利用到拆分下去的各個節點,進行并行計算,真正把水準分布式資料庫的優勢發揮出來,需要大量的操作、大量的優化措施。TDSQL做了這樣一些優化措施:

一是相關資料存在同一個節點上。建表結構的時候,我們希望業務能參與進來一部分,在設計表結構的時候指定相關的一些鍵作為shardkey,這樣我們就能保證後端的相關資料是在一個節點上的。如果對這些資料進行聯合查詢就不需要跨節點。

同樣,我們通過并行計算、流式聚合來實作性能提升——我們把SQL拆分分發到各個背景的節點,然後通過每個節點并行計算,計算好以後再通過SQL引擎來做二次聚合,然後傳回給使用者。

為了減少資料的拉取,我們會做一些下推的查詢——把更多的條件下推到DB上。此外我們也做了資料備援,通過資料備援保證盡量減少跨節點的資料互動。

我們簡單看一個聚合——TDSQL是如何做到水準擴容以後,對業務基本無感覺,使用方式跟使用單機MySQL一樣的。

對業務來說,假設有7條資料,業務不用管這個表具體資料是存在一個節點還是多個節點,隻需要插7條資料。系統會根據傳過來的SQL進行文法解析,并自動把這條資料進行改寫。7條資料,系統會根據分區鍵計算,發現這4個要發到第一個節點,另外3個發到第二個節點,然後進行改寫,改寫好之後插入這些資料。對使用者來說,就是執行了這麼一條,但是跨節點了,我們這邊會用到兩階段送出,進而變成多條SQL,進而保證一旦有問題兩邊會同時復原。

資料插錄完以後,使用者如果要做一些查詢——事實上使用者不知道資料是拆分的,對他來說就是一個完整的表,他用類似聚合函數等進行查詢。同樣,這條SQL也會進行改寫,系統會把這條SQL發到兩個節點上,同時加一些平均函數,進行相應的轉換。到了各個節點,系統會先做資料聚合,到這邊再一次做聚合。

增加這個步驟的好處是,這邊過來的話,我們可以通過做聚合——相當于在這裡不需要緩存太多的資料,并且做到流式計算,避免出現一次性消耗太多記憶體的情況。

以上是TDSQL水準擴容方案設計原理以及實踐過程的介紹。

結語

除了騰訊會議,疫情期間,TDSQL 還基于騰訊雲快速支援了多地區健康碼、市政防控平台小程式等高并發、籌備時間短的項目應用順利上線、穩定運作,服務群眾數億,日均調用數十億次。

基礎技術的積累讓我們今天擁有順利應對一切突發變化的能力,未來基于新型業務形态,我們的底層基礎技術也将不斷疊代演進,開啟下一個數字化時代。