為了應(yīng)對這種敏態(tài)場景,傳統(tǒng)做法是人工介入,比如在建表的時候,需要人為指定一個shardkey做分表,但是一般這種方法SQL語法未必能夠兼容所有數(shù)據(jù)庫,另外也需要用戶自己去預(yù)判數(shù)據(jù)熱點,不是很靈活。同時還有一點,比如需要擴容的時候,一些普通的場景需要DBA(數(shù)據(jù)庫運維工程師)發(fā)起,可能會中斷這個業(yè)務(wù)的執(zhí)行。人工擴容沒有辦法及時處理。

想讓數(shù)據(jù)庫能夠具備一個自主應(yīng)對敏態(tài)場景能力,盡可能解放人力,讓用戶像使用單機數(shù)據(jù)庫一樣使用分布式數(shù)據(jù)庫。

首先介紹一下TDSQL的架構(gòu),這是一個TDSQL的整體架構(gòu),它是一個全分布式的,并且實現(xiàn)了存算分離的數(shù)據(jù)庫,它由三個模式構(gòu)成,首先最上面的是MySQL Engine,它是一個計算節(jié)點,它的一個目的是將SQL語句轉(zhuǎn)化成KV請求發(fā)送給存儲集群,它會做一些查詢?nèi)趸?/p>

下面這個是TDStore,它是一個Share Nothing存儲的分布式集群,它是一個KV的存儲模塊,用來接收Engine下發(fā)的一些KV請求,可以看到TDStore做了一個數(shù)據(jù)分片,把整個范圍的數(shù)據(jù)劃分成各個連續(xù)的Region,每一個Region其實是一個獨立的Raft pool,它的Raft pool每一個副本是打散在不同的TDStore上,這樣我們就實現(xiàn)了一個初步的負載均衡。TDStore同時提供了一個分布式事務(wù)的下沉,使用2副本保證一個分布式事務(wù)提交的原子性。

右邊這個模塊是一個全局的原數(shù)據(jù)管理模塊MC,它提供的是一個全局遞增的時間戳管理,還有它提供了一個全局的資源調(diào)度,比如說發(fā)現(xiàn)某一個TDStore壓力比較大,這個時候它就會向TDStore下發(fā)調(diào)度任務(wù),把它的一部分壓力均衡到另外一些壓力不怎么大的TDStore節(jié)點上,這樣就實現(xiàn)了一個比較初步的負載均衡,等于說對于這種敏態(tài)業(yè)務(wù)的支持是離不開MC的幫助的。

接下來簡單介紹一下TDSQL是如何去進行數(shù)據(jù)的調(diào)度以及負載均衡的,介紹一下Region調(diào)度原理。

Region目前的調(diào)度分為分裂、遷移和切主三種,剛剛提到過TDSQL其實是以Region做數(shù)據(jù)管理的,也就是說每個Region管理的是一段連續(xù)范圍的數(shù)據(jù),并且每個Region都是獨立的Raft Pool,所以這些Region的副本會散落在不同的TDSQL節(jié)點上,可能每一個TDSQL所包含的Region數(shù)量是有所差異的。同時SQL Engine是向Region Leader副本下發(fā)讀寫請求的,所以Region Leader副本要比follower副本承擔(dān)更多的壓力。由此可以得到一個初步結(jié)論:如果觀察到一個TDSQL節(jié)點包含了比較多的Region副本數(shù),或者它上面的Leader副本比較多,說明這個TDSQL就承擔(dān)了比較多的壓力。

這里舉一個具體的例子,這個圖上展現(xiàn)的是4個TDSQL構(gòu)成的存儲集群,其中包含三個Region,我們可以看到Region3比較大,表現(xiàn)上面的數(shù)據(jù)比較多,讀寫比較頻繁,所以是一個熱點Region。此前我們提到過。Region Leader要承擔(dān)更大的壓力,所以對于熱點Region3 Leader所在的TDSQL4節(jié)點壓力會更多一些,同時我們可以看到TDSQL1有3個副本,而其他的TDSQL都只負責(zé)兩個副本,所以TDSQL 1壓力也比較大。

因此我們最終想達到一個目的,我們想把TDSQL1和TDSQL4的一部分壓力轉(zhuǎn)到壓力比較小的TDSQL2上。

具體怎么實現(xiàn)的?

首先看一下Region分裂的大概原理。

首先我們的Region僅僅只是一個邏輯上的數(shù)據(jù)分區(qū),可以看到它展現(xiàn)的是一個大概分類流程,比如說一開始Region1范圍是A到E,包含了ABCD四個數(shù)據(jù),經(jīng)過分裂以后可以看到底層的ABCD四部分數(shù)據(jù)沒有變動,唯一變動的只是說新增了一個新的Region2,原來的Region1我們稱之為OLD Region,新產(chǎn)生的Region我們叫做New Region,可以看到Region1范圍變成A到C,包含的數(shù)據(jù)是RegionB 2個,Region2的范圍是C到E,它所管理的數(shù)據(jù)是Region D,也就是我們經(jīng)過分裂以后得到的兩個Region,他們分別承擔(dān)的是分裂之前的Region的50%的壓力,這樣下來等于說我們可以起到把一個壓力比較大的Region給分裂成兩個新Region,這樣就可以擺脫一個熱點Region的情況。

回到剛剛的例子,首先當(dāng)我們要觸發(fā)分裂的時候,MC會向Region的Leader下發(fā)一個計算分裂點,Leader收到以后會通過二分法找到整個Region范圍內(nèi)的數(shù)據(jù)中間點Key,把這個Key返回給MC,MC收到以后會重新向每一個Region副本下發(fā)分裂任務(wù),當(dāng)TDSQL收到分裂任務(wù)以后,它會在TDSQL上產(chǎn)生一個Region 4,相當(dāng)于Region 3的數(shù)據(jù)范圍變小了,把它的后半部分Region范圍單獨拆分出一個新的Region 4,這樣來看雖然Region的熱點沒有了,但是從TDSQL壓力來看,沒有太大變化,比如說TDSQL 4,現(xiàn)在它變成了有兩個Leader,一個副本的節(jié)點,而TDSQL更是承擔(dān)了4個副本的壓力,所以我們下一步的目的就是把TDSQL1和TDSQL4的壓力均衡到TDSQL2上。

通過Region遷移去分擔(dān)一部分TDSQL1的壓力,具體的方式就是MC會向要遷移的目標節(jié)點,也就是TDSQL2下發(fā)一個添加副本的任務(wù),TDSQL2收到以后會創(chuàng)建一個Region4的副本,等于短時間內(nèi)Region4從3副本變成4副本的Group,我們的MC會向TDSQL1下發(fā)一個銷毀副本的任務(wù),等于Region4就被銷毀掉了,Region4的副本數(shù)又恢復(fù)到3個。

經(jīng)過一番操作以后,可以看到TDSQL1變成一個Leader和2個Follower,它的壓力降低了很多。

下一步我通過切主的方式把TDSQL4的Leader切到TDSQL2上,可以看到所有的TDSQL都變成了有1個Leader和2個Follower的情況,等于它的負載就得到一個均衡。

當(dāng)然剛剛的演示僅僅是一個示意。實際在生產(chǎn)環(huán)境中,Region的數(shù)量還有TDSQL節(jié)點數(shù)量會有很多很多,同時針對同一個Region的分裂遷移和切主三種任務(wù),可能也不會是這么緊湊的接連執(zhí)行。這里有一個原因,如果沒有特殊處理,Region的分裂和切主可能會對事務(wù)執(zhí)行有一些影響,影響業(yè)務(wù)的正常進行。

接下來將重點考慮TDSQL是如何盡量優(yōu)化事務(wù)跟Region調(diào)度的并發(fā),去做到Region調(diào)度不殺事務(wù)(以下部分內(nèi)容比較技術(shù),詳情可參見Doit學(xué)院的有關(guān)視頻。)。

(本文基于騰訊云數(shù)據(jù)庫高級工程師劉暢演講速記整理而成,未經(jīng)本人審閱

分享到

songjy

相關(guān)推薦