不知大家是否已經留意到,在 TDengine 3.0 的官方文(wen)檔()中,有了這樣一(yi)個命令(ling) :show transactions。顧名思義,這是“事(shi)務”。
在(zai) Database 的(de)語境中,滿(man)足 ACID 屬(shu)性的(de)數(shu)據庫操(cao)作序列即可稱為(wei)事務(wu),它(ta)是數(shu)據庫的(de)一(yi)個不(bu)可拆分的(de)工作單元(yuan),包(bao)含著一(yi)個數(shu)據庫操(cao)作的(de)序列,這些操(cao)作要(yao)么(me)全(quan)部(bu)執(zhi)行,要(yao)么(me)全(quan)部(bu)不(bu)執(zhi)行。換個角度也可以說,事務(wu)是為(wei)了實(shi)現(xian) ACID 特性的(de)一(yi)種工具。
不(bu)過在(zai) TDengine 中,依托于“一(yi)個數(shu)據采集點一(yi)張表(biao)”的(de)(de)設計理念,針(zhen)對(dui)表(biao)的(de)(de)操作都(dou)是(shi)(shi)以(yi)隊列(lie)方式逐個進行的(de)(de),所以(yi)在(zai)絕大多數(shu)情況下都(dou)不(bu)需(xu)要(yao)事務機(ji)制。那(nei) TDengine 3.0 中的(de)(de)“事務”是(shi)(shi)用(yong)來解決(jue)什么問題的(de)(de)呢(ni)?答案就是(shi)(shi):3.0 中的(de)(de)事務機(ji)制并沒有應用(yong)在(zai)業務數(shu)據上,而是(shi)(shi)針(zhen)對(dui)數(shu)據庫的(de)(de)元數(shu)據的(de)(de),它的(de)(de)目(mu)的(de)(de)是(shi)(shi)利用(yong)事務的(de)(de) ACID 特性,來強化元數(shu)據的(de)(de)一(yi)致性,因此,普(pu)通(tong)用(yong)戶對(dui)此是(shi)(shi)無感知的(de)(de),但(dan)是(shi)(shi)對(dui) TDengine 的(de)(de)運維人員而言(yan),意義會(hui)更大一(yi)些。
大家都知道 TDengine 3.0 是一款高性能、云原生的分布式時序數據庫(Time Series Database),甚至(zhi)可以支持十億級別的表數量(liang),因此它的元數據量(liang)是十分(fen)龐大的。那么(me)如果(guo)使用了事務,會不會影響 TDengine 的高性(xing)能(neng)呢?
這里就需要結合 TDengine 2.x 時代的元數據架構來說起了。
一、2.x 的元數據架構
在(zai)(zai)(zai) 2.x 版本中(zhong)(zhong),管(guan)理(li)節(jie)點 mnode 中(zhong)(zhong)的(de)(de) sdb 模塊存(cun)(cun)儲了大量(liang)元數(shu)據,如(ru)集群信(xin)息(xi)(xi)、用戶信(xin)息(xi)(xi)、數(shu)據庫(ku)信(xin)息(xi)(xi)、超級表(biao)(biao)信(xin)息(xi)(xi)以(yi)及普(pu)通(tong)表(biao)(biao)信(xin)息(xi)(xi)等。這些(xie)不同類型的(de)(de)信(xin)息(xi)(xi),會(hui)在(zai)(zai)(zai)內存(cun)(cun)中(zhong)(zhong)分(fen)別(bie)以(yi)一個(ge)(ge) hash 表(biao)(biao)的(de)(de)形(xing)式(shi)來維護。其(qi)中(zhong)(zhong),一些(xie)元數(shu)據需要在(zai)(zai)(zai)管(guan)理(li)節(jie)點(mnode)和數(shu)據節(jie)點(dnode/vnode)中(zhong)(zhong)分(fen)別(bie)存(cun)(cun)儲,比如(ru)超級表(biao)(biao)、普(pu)通(tong)表(biao)(biao)。所以(yi),當對(dui)數(shu)據庫(ku)執行 DDL 操作(zuo)時,需要在(zai)(zai)(zai) mnode 上對(dui)這個(ge)(ge) hash 表(biao)(biao)操作(zuo)一次(ci),還(huan)要再去 dnode 中(zhong)(zhong)的(de)(de) vnode 也做一次(ci)。這里為了性(xing)能的(de)(de)優化,TDengine 選擇(ze)以(yi)異步的(de)(de)方式(shi)來完成(cheng)操作(zuo)。以(yi)刪表(biao)(biao)為例,當 mnode 內存(cun)(cun)中(zhong)(zhong)的(de)(de) hash 表(biao)(biao)刪掉了這個(ge)(ge)表(biao)(biao)后(hou),會(hui)立(li)即返(fan)回成(cheng)功。后(hou)續由 dnode/vnode 一側刪除(chu)自己的(de)(de)元數(shu)據,達(da)成(cheng)最終一致。
因為該流程的(de)(de)非(fei)強一致性,可(ke)能(neng)(neng)會導致在某些極特殊(shu)情況下(比如網絡不穩(wen)定(ding)),出現(xian) mnode 與 vnode 元數據不同步(bu)的(de)(de)情況(有(you)的(de)(de)用戶遇到過這(zhe)個錯誤信(xin)息:“Invalid table id”)。但是如果為了強一致性而在 2.x 中(zhong)引入事務機制,那么(me)對(dui)于存在超(chao)大規(gui)模 DDL 操作的(de)(de)場景來說(shuo)(如刪除一張擁(yong)有(you)百萬千萬子表的(de)(de)超(chao)級表),這(zhe)種分布式的(de)(de)事務對(dui)數據庫的(de)(de)性能(neng)(neng)損耗(hao)又將非(fei)常(chang)之大。
那(nei)么應該如何解決(jue)這個問(wen)(wen)題(ti)呢?我們的思路是(shi):利用“分(fen)布式事務”,解決(jue) mnode 和 dnode 同步時的問(wen)(wen)題(ti),但是(shi)又(you)不能讓(rang)其(qi)影(ying)響到數據庫的性(xing)能。
二、3.0 的事務引入
以此為依據,TDengine 在 3.0 中選擇把開銷最大的普通表元數據從 mnode 中移除,完全只放在各個 vnode 中分布式存儲,這樣除了防止了上述 mnode 和 vnode 普通表元數據不一致的現象發生,更使得 TDengine 不再具有單點性能瓶頸,解決了業界的“高基數”難題,從而可以支持十億級別的時間線。在其余的元數據模塊中,我們則引入了事務機制,確保了這部分元數據的 ACID 特性。
下圖是(shi)一個兩階段提交的(de)流(liu)程,其中 Coordinator(協調者)就(jiu)是(shi) mnode,而 Participants(參與者) 就(jiu)是(shi) dnode/vnode。
創建事(shi)(shi)務(wu)后(hou),協(xie)調者(zhe)本地準(zhun)備(bei)事(shi)(shi)務(wu)所需的必要數據,redo、undo 日志等。然后(hou)向參與者(zhe)們(men)發送(song)事(shi)(shi)務(wu)執(zhi)行(xing)請求,如(ru)果參與者(zhe)們(men)的事(shi)(shi)務(wu)執(zhi)行(xing)結果皆為(wei)成功,那(nei)么則進入提交階段(duan),由協(xie)調者(zhe)提交事(shi)(shi)務(wu)。

需要注意的是(shi):如果作為(wei)(wei)(wei)協調者的 mnode 宕機,那么其他 mnode 在成為(wei)(wei)(wei) leader 之后,會作為(wei)(wei)(wei)新(xin)的協調者繼續驅動事(shi)務的執行。也就是(shi)說,Raft 協議保(bao)證(zheng)了事(shi)務的一致(zhi)性和(he)持久(jiu)性。
在(zai)現在(zai)的(de)(de) 3.0 架(jia)構中,為(wei)了(le)(le)避免不(bu)同(tong)(tong)的(de)(de)事務(wu)操作共享(xiang)資源,管理(li)節(jie)點(dian)針(zhen)對不(bu)同(tong)(tong)類型(xing)的(de)(de)元數(shu)據(ju)把事務(wu)分成了(le)(le)幾個級(ji)(ji)別(bie)(bie)(bie)(bie),分別(bie)(bie)(bie)(bie)為(wei)無沖突級(ji)(ji)別(bie)(bie)(bie)(bie)、全局級(ji)(ji)別(bie)(bie)(bie)(bie)、數(shu)據(ju)庫級(ji)(ji)別(bie)(bie)(bie)(bie)以(yi)及數(shu)據(ju)庫內(nei)部級(ji)(ji)別(bie)(bie)(bie)(bie)。如(ru)果在(zai)內(nei)存中仍有未(wei)完(wan)成且具(ju)有相同(tong)(tong)沖突類型(xing)的(de)(de)事務(wu),后(hou)執(zhi)行(xing)(xing)的(de)(de)事務(wu)將會等待前者(zhe)執(zhi)行(xing)(xing)完(wan)畢(bi)再執(zhi)行(xing)(xing)。

最終(zhong),一個事(shi)務的(de)運(yun)行(xing)(xing)狀態與行(xing)(xing)為是由該(gai)類元數(shu)據本身的(de)沖突級別(bie)和(he)失敗策略等因素(su)決定(ding)的(de),而這一切(qie)是對(dui)用戶無感知的(de)。用戶只(zhi)需(xu)知道事(shi)務在執行(xing)(xing)階(jie)段具有 PREPARE,REDO_ACTION,COMMIT,COMMIT_ACTION,ROLLBACK,UNDO_ACTION,FINISHED 7 個階(jie)段。

其中,比(bi)較關(guan)鍵的(de)(de)(de)(de)(de)地方是:在(zai) PREPARE 階(jie)段(duan),事務(wu)的(de)(de)(de)(de)(de)基本信息在(zai)不同的(de)(de)(de)(de)(de) mnode 間達(da)成一(yi)致(zhi);然后在(zai) REDO_ACTION 階(jie)段(duan),執(zhi)行 mnode 的(de)(de)(de)(de)(de)本地操作、以及涉及的(de)(de)(de)(de)(de) vnode 的(de)(de)(de)(de)(de)遠端操作。當(dang) REDO_ACTION 的(de)(de)(de)(de)(de)所有操作都完(wan)成后,進入 COMMIT 階(jie)段(duan)。注:REDO_ACTION 不止包含(han)了第(di)一(yi)次執(zhi)行任(ren)務(wu),還(huan)包括執(zhi)行失敗后的(de)(de)(de)(de)(de)重(zhong)做。COMMIT 階(jie)段(duan)則負責把(ba)數據最終寫(xie)入到(dao) SDB 對應的(de)(de)(de)(de)(de)表中,完(wan)成持久化。在(zai)最后的(de)(de)(de)(de)(de) FINISHED 階(jie)段(duan),清理(li) SDB 模塊中事務(wu)表的(de)(de)(de)(de)(de)相關(guan)內存,完(wan)成整個任(ren)務(wu)的(de)(de)(de)(de)(de)執(zhi)行或(huo)者回(hui)滾。

通過 show transactions,我們可以明確了(le)解到當前事務(wu)運行(xing)的(de)階段。除了(le)確保數(shu)據(ju)庫(ku)(ku)的(de)安全(quan)一致之外,也給(gei)了(le)數(shu)據(ju)庫(ku)(ku)運維人員更充足(zu)的(de)信息(xi)去(qu)診(zhen)斷數(shu)據(ju)庫(ku)(ku)的(de)當前狀態(tai)。不過,在(zai)絕大多數(shu)時間,show transactions 的(de)輸出(chu)是沒有結果的(de),因為元(yuan)數(shu)據(ju)體(ti)量較小,所以執行(xing)速度(du)都非常快。
總而言之(zhi),TDengine 3.0 的“事務”機(ji)制為(wei)集群信(xin)息、用戶信(xin)息、數據(ju)庫信(xin)息以及超級表(biao)信(xin)息等(deng)元數據(ju)帶來(lai)了(le) ACID 的特性保障。
而(er)在它(ta)背后的(de)把普通表元數(shu)據(ju)完全遷移到 vnode 的(de)架構(gou)變更(geng),使得(de) TDengine 不再具有(you)單點(dian)瓶頸,獲得(de)了超強(qiang)的(de)水平擴展能力(li),如果(guo)想獲得(de)更(geng)多的(de)數(shu)據(ju)處(chu)理(li)能力(li),只(zhi)需要加入更(geng)多的(de)數(shu)據(ju)節點(dian)即可。
在下一篇文(wen)章(zhang)中,我(wo)會繼(ji)續(xu)和大家分(fen)享該變(bian)更帶來(lai)的(de)(de)諸(zhu)多優勢,一起感受 TDengine 這(zhe)款開源、高性能、云原生的(de)(de)時(shi)序數據庫(ku)的(de)(de)架構變(bian)化之路。

加入物聯網大數據交流群


























