云原生(sheng)數據庫(ku)(ku) (Cloud Native Database) 是指充分利(li)用(yong)(yong)了(le)(le)云計算平臺以及分布式系(xi)統的(de)優勢而設計的(de)數據庫(ku)(ku)。云原生(sheng)數據庫(ku)(ku)提供了(le)(le)按(an)照實際使用(yong)(yong)資源(yuan)量來計費的(de)能(neng)力,以降(jiang)低運營(ying)成本。此(ci)外(wai),它提供了(le)(le)快(kuai)速開發(fa)原型、研(yan)發(fa)、測(ce)試以及部署(shu)新的(de)應(ying)用(yong)(yong)的(de)能(neng)力,可以大大縮短新的(de)應(ying)用(yong)(yong)從設計開發(fa)到進入市(shi)場的(de)時間(jian)。
作為一個云原生,而不只是能在云上運行的時序數據庫(Time Series Database),TDengine 具(ju)備云(yun)原生數據庫(ku)的幾大特點:水平(ping)擴(kuo)展性(Scalability)、彈性(Elasticity)、韌性(Resiliency)、可觀測性(Observability)以(yi)及運(yun)維(wei)自(zi)動化(Automation)。
在我們討(tao)論(lun)這些(xie)特(te)性之前,可以先簡(jian)單(dan)了解一下(xia) TDengine 的(de)分布(bu)式設計。
分布式設計
在 3.0 版本之后(hou),TDengine 具備(bei)完全的分(fen)布(bu)式架構,提供(gong)高可用的水(shui)平擴展(zhan)能(neng)力。如(ru)果需要(yao)獲得更高的處(chu)理能(neng)力,只需要(yao)多增(zeng)加節點(dian)即可。

一(yi)個完整的 TDengine 系統(tong)運行(xing)在一(yi)到多個物理節點(一(yi)臺服務器、虛擬機或容(rong)器)上的。邏輯上,它包含數(shu)據節點(dnode)、TDengine 應用(yong)驅動(dong)(dong)(taosc)以及應用(yong)(app)。系統(tong)中存在一(yi)到多個數(shu)據節點,這些數(shu)據節點組成(cheng)一(yi)個集群(cluster)。應用(yong)通過 taosc 的 API 與(yu) TDengine 集群進行(xing)互動(dong)(dong)。下面對每個邏輯單元進行(xing)簡(jian)要(yao)介(jie)紹。
數據節點(dnode): dnode 是 TDengine 服務(wu)器側執行(xing)代(dai)碼 taosd 在物理節(jie)(jie)點(dian)上的(de)一(yi)個運(yun)行(xing)實例(li),一(yi)個工作的(de)系統必(bi)須有至少一(yi)個數據節(jie)(jie)點(dian)。dnode 包含零到多(duo)個邏輯(ji)的(de)虛擬(ni)節(jie)(jie)點(dian)(vnode),零或(huo)者(zhe)(zhe)至多(duo)一(yi)個邏輯(ji)的(de)計算節(jie)(jie)點(dian)(qnode),零或(huo)者(zhe)(zhe)至多(duo)一(yi)個邏輯(ji)的(de)管理節(jie)(jie)點(dian)(mnode)。
虛擬節點(vnode): 為更好地支持(chi)數(shu)據(ju)(ju)(ju)分片(pian)、負載(zai)均衡(heng),防止數(shu)據(ju)(ju)(ju)過熱或傾斜(xie),數(shu)據(ju)(ju)(ju)節(jie)點被虛擬化(hua)成(cheng)多個(ge)虛擬節(jie)點(vnode,圖(tu)中(zhong) V2,V3,V4 等)。每個(ge) vnode 都是一(yi)個(ge)相(xiang)對(dui)獨立的(de)(de)工作單元,是時序數(shu)據(ju)(ju)(ju)存(cun)儲的(de)(de)基本單元,具有獨立的(de)(de)運行線程(cheng)、內存(cun)空間與持(chi)久(jiu)化(hua)存(cun)儲的(de)(de)路徑。一(yi)個(ge) vnode 包(bao)含一(yi)定數(shu)量(liang)的(de)(de)表(數(shu)據(ju)(ju)(ju)采集點)的(de)(de)數(shu)據(ju)(ju)(ju),包(bao)括(kuo)時序數(shu)據(ju)(ju)(ju)和元數(shu)據(ju)(ju)(ju)。一(yi)個(ge) vnode 就是一(yi)個(ge)片(pian) (shard)。
計算節點(qnode):計算(suan)(suan)(suan)節(jie)(jie)點僅(jin)僅(jin)負(fu)責(ze)計算(suan)(suan)(suan)。當一(yi)個(ge)(ge)查詢執行(xing)時,依賴(lai)執行(xing)計劃(hua),調度器會安排(pai)一(yi)個(ge)(ge)或多(duo)(duo)個(ge)(ge) qnode 來一(yi)起執行(xing)。qnode 能(neng)從 vnode 獲取數據,也(ye)可以將自己的計算(suan)(suan)(suan)結果發給其他 qnode 做(zuo)進一(yi)步的處理(li)。一(yi)個(ge)(ge)集群(qun)里允許(xu)有多(duo)(duo)個(ge)(ge) qnode,它的啟動(dong)和停(ting)止完全由 mnode 根據系統資(zi)源和性能(neng)要求來決定。通(tong)過引入獨立(li)的計算(suan)(suan)(suan)節(jie)(jie)點,TDengine 實現了存(cun)儲和計算(suan)(suan)(suan)分離(li)。
管理節點(mnode): 一(yi)個(ge)虛擬(ni)的(de)(de)邏輯單元(yuan),負(fu)責(ze)所有數(shu)據節(jie)(jie)點運行狀態(tai)的(de)(de)監(jian)控和維護,以及(ji)節(jie)(jie)點之間(jian)的(de)(de)負(fu)載均衡(圖中 M)。同(tong)時,管(guan)(guan)理(li)節(jie)(jie)點也負(fu)責(ze)元(yuan)數(shu)據(包含用戶、數(shu)據庫,但(dan)不包含表、靜(jing)態(tai)標簽等(deng))的(de)(de)存儲(chu)和管(guan)(guan)理(li),因此(ci)也稱為 Meta Node。一(yi)個(ge)集群里(li)只(zhi)有一(yi)個(ge)管(guan)(guan)理(li)節(jie)(jie)點,但(dan)為提高管(guan)(guan)理(li)節(jie)(jie)點的(de)(de)高可用性(xing),允許有三個(ge)副本。
taosc:taosc 是(shi) TDengine 給應(ying)用(yong)提(ti)供(gong)的驅動程(cheng)序(driver),負責處理應(ying)用(yong)與集(ji)(ji)群的接(jie)口(kou)交互,提(ti)供(gong) C/C++ 語(yu)言原(yuan)生接(jie)口(kou),內(nei)嵌于 JDBC、C#、Python、Go、Node.js 語(yu)言連接(jie)庫里。應(ying)用(yong)都是(shi)通過 taosc 而不是(shi)直接(jie)連接(jie)集(ji)(ji)群中的數據節(jie)點來與整個集(ji)(ji)群交互的。
水平擴展性(Scalability)
TDengine 是(shi)通過數據(ju)采集點以(yi)及時間兩(liang)個維度(du),對大數據(ju)進行(xing)切分(fen)(fen),實現水平擴展的,它既支(zhi)持(chi)分(fen)(fen)片(pian),也支(zhi)持(chi)分(fen)(fen)區(qu)。

分片:在(zai) TDengine 的(de)設計與實現里(li),一(yi)個(ge)(ge)集(ji)(ji)群有(you)多個(ge)(ge)數(shu)(shu)(shu)據節點(dian),每個(ge)(ge)數(shu)(shu)(shu)據節點(dian)可以有(you)一(yi)個(ge)(ge)或多個(ge)(ge)虛(xu)擬(ni)(ni)節點(dian)(vnode),每個(ge)(ge)虛(xu)擬(ni)(ni)節點(dian)里(li)存儲了一(yi)定數(shu)(shu)(shu)量(liang)的(de)數(shu)(shu)(shu)據采集(ji)(ji)點(dian)的(de)數(shu)(shu)(shu)據,而一(yi)個(ge)(ge)數(shu)(shu)(shu)據采集(ji)(ji)點(dian)的(de)時(shi)序(xu)數(shu)(shu)(shu)據和元數(shu)(shu)(shu)據永遠只(zhi)存放在(zai)一(yi)個(ge)(ge) vnode 里(li)。這樣如果有(you)很多數(shu)(shu)(shu)據采集(ji)(ji)點(dian),通過一(yi)致性 Hash,這些(xie)數(shu)(shu)(shu)據采集(ji)(ji)點(dian)的(de)數(shu)(shu)(shu)據將會(hui)分布在(zai)多個(ge)(ge) vnode 上,分布在(zai)多個(ge)(ge)節點(dian)里(li)。
分區:除將(jiang)數(shu)(shu)(shu)據(ju)(ju)(ju)分片(pian)之(zhi)外,TDengine 還將(jiang)一(yi)個 vnode 里存(cun)(cun)(cun)儲(chu)的(de)時(shi)(shi)(shi)(shi)序(xu)(xu)數(shu)(shu)(shu)據(ju)(ju)(ju)按照時(shi)(shi)(shi)(shi)間(jian)段(duan)(duan)(duan)進行切分。每個時(shi)(shi)(shi)(shi)間(jian)段(duan)(duan)(duan)的(de)數(shu)(shu)(shu)據(ju)(ju)(ju)都一(yi)定保存(cun)(cun)(cun)在(zai)一(yi)起(qi),不(bu)同時(shi)(shi)(shi)(shi)間(jian)段(duan)(duan)(duan)的(de)數(shu)(shu)(shu)據(ju)(ju)(ju)不(bu)會有交(jiao)集,時(shi)(shi)(shi)(shi)間(jian)段(duan)(duan)(duan)可(ke)以(yi)(yi)是一(yi)天,幾(ji)天,一(yi)周,由用戶(hu)自己定義。按照時(shi)(shi)(shi)(shi)間(jian)段(duan)(duan)(duan)切分時(shi)(shi)(shi)(shi)序(xu)(xu)數(shu)(shu)(shu)據(ju)(ju)(ju)有很多(duo)好處,查詢數(shu)(shu)(shu)據(ju)(ju)(ju)時(shi)(shi)(shi)(shi),根據(ju)(ju)(ju)時(shi)(shi)(shi)(shi)間(jian)段(duan)(duan)(duan),可(ke)以(yi)(yi)直(zhi)接(jie)定位要(yao)查找(zhao)的(de)文件(jian),從而加快查詢速度。另外一(yi)方面,可(ke)以(yi)(yi)高效(xiao)地實現(xian)數(shu)(shu)(shu)據(ju)(ju)(ju)保留(liu)策略。超(chao)過最長保留(liu)時(shi)(shi)(shi)(shi)間(jian)的(de)數(shu)(shu)(shu)據(ju)(ju)(ju),直(zhi)接(jie)刪除一(yi)個時(shi)(shi)(shi)(shi)間(jian)段(duan)(duan)(duan)對應的(de)文件(jian)即可(ke)。而且按照時(shi)(shi)(shi)(shi)間(jian)段(duan)(duan)(duan)切分數(shu)(shu)(shu)據(ju)(ju)(ju),還可(ke)以(yi)(yi)方便(bian)實現(xian)多(duo)級存(cun)(cun)(cun)儲(chu),冷熱數(shu)(shu)(shu)據(ju)(ju)(ju)放在(zai)不(bu)同存(cun)(cun)(cun)儲(chu)介質上,進一(yi)步(bu)降低存(cun)(cun)(cun)儲(chu)成本。
高基數:在 TDengine 的(de)(de)設(she)計中(zhong),每個(ge)數(shu)據(ju)(ju)采集(ji)點(dian)的(de)(de)元數(shu)據(ju)(ju)沒(mei)有存(cun)放在中(zhong)心點(dian),而是分布在各(ge)個(ge) vnode 里。當應(ying)(ying)用要將(jiang)數(shu)據(ju)(ju)插入到一(yi)張(zhang)表(biao)或對(dui)(dui)一(yi)張(zhang)表(biao)做查詢操(cao)作時(shi),基于(yu)(yu)表(biao)名的(de)(de) hash 值,插入或查詢請求(qiu)將(jiang)被(bei)直接發(fa)送(song)到對(dui)(dui)應(ying)(ying)的(de)(de) vnode,由于(yu)(yu)沒(mei)有中(zhong)心點(dian),不會(hui)有任何瓶頸。對(dui)(dui)于(yu)(yu)多個(ge)點(dian)的(de)(de)聚合計算(suan),查詢的(de)(de)請求(qiu)將(jiang)被(bei)同時(shi)發(fa)往相關(guan)的(de)(de) vnode,每個(ge) vnode 都會(hui)執(zhi)行對(dui)(dui)應(ying)(ying)的(de)(de)聚合操(cao)作,然后將(jiang)結(jie)果返(fan)回給 taosc 或 qnode,做進一(yi)步的(de)(de)聚合。
TDengine 具有超強的(de)(de)水平擴展能(neng)力(li),為獲得更(geng)多的(de)(de)數(shu)據(ju)(ju)處理能(neng)力(li),只(zhi)需要加(jia)入更(geng)多的(de)(de)數(shu)據(ju)(ju)節點即可。通過測試,我們可以驗證(zheng)(zheng),在 10 億時間線,100 個數(shu)據(ju)(ju)節點的(de)(de)情況(kuang)下(xia),整個 TDengine 性能(neng)還能(neng)得到很好的(de)(de)保證(zheng)(zheng)。時序數(shu)據(ju)(ju)處理里的(de)(de)“高(gao)基(ji)數(shu)”問題完全得到了解決。
彈性(Elasticity)
在 IoT 或 IIoT 情況下,系(xi)(xi)統需(xu)要快速將最新數據(ju)(ju)返回給應用程序。例(li)如,車隊管理系(xi)(xi)統總是想知道每輛卡車的當前 GPS 位作為(wei)一個云原生數據(ju)(ju)庫,TDengine 不僅提供 scale up 的能(neng)力(li),也提供 scale down 的能(neng)力(li),從而(er)讓(rang)系(xi)(xi)統具有彈性。
為支(zhi)持存儲的(de)彈性(xing),如果插入的(de)延(yan)時已經超過一(yi)(yi)定閾值或(huo)者性(xing)能不夠,TDengine 會將一(yi)(yi)個 vnode 拆分成兩個,從而分配(pei)更(geng)多的(de)系統資(zi)源給數據寫(xie)入操作。另一(yi)(yi)方面(mian),在(zai)能夠保證延(yan)時與性(xing)能的(de)情況下,TDengine 也可以把多個 vnode 合并成一(yi)(yi)個,以節省(sheng)系統資(zi)源。
為支持計算的彈性,TDengine 引入了計算節點 qnode。對于(yu)簡(jian)單(dan)的查詢,比(bi)如獲得某張表(biao)的原始(shi)數據(ju)或卷曲數據(ju)(rollup data),對應的 vnode 將完成(cheng)所有的操作(zuo),無需 qnode 的參與。但對于(yu)一(yi)個(ge)需要(yao)排序、分組或其(qi)他需要(yao)計算資(zi)源的操作(zuo),查詢的執行過程(cheng)中(zhong),一(yi)個(ge)或多個(ge) qnode 將被調(diao)用(yong)。在(zai)具體的部署中(zhong),qnode 可以運行在(zai)容(rong)器里,它(ta)的啟停完全由 mnode 根據(ju)系統(tong)負載情況決(jue)定。
通過引(yin)入(ru) qnode,TDengine 成為(wei)一個(ge)理(li)想(xiang)的(de)時序數(shu)據分(fen)析(xi)平臺,包(bao)括實時數(shu)據分(fen)析(xi)和批分(fen)析(xi)。在云計算(suan)的(de)環境里(li),計算(suan)資源是近(jin)似無限的(de),但又可以彈(dan)性的(de)伸縮(suo)。

韌性(Resilience)
TDengine 的韌性是通過其高(gao)可靠與(yu)高(gao)可用設計來(lai)實現的。
對于(yu)數據(ju)庫,存(cun)儲的高(gao)(gao)可靠(kao)是最高(gao)(gao)優先級的。TDengine 采(cai)用(yong) Database 實現中(zhong)傳統(tong)的方法 WAL(Write Ahead Log) 來保證即使系統(tong)宕機,數據(ju)仍(reng)然可以(yi)恢復而(er)不會丟失,從而(er)實現數據(ju)的高(gao)(gao)可靠(kao)。在設(she)計(ji)中(zhong),新寫入(ru)的數據(ju)總是先寫入(ru) WAL,然后寫入(ru)內(nei)存(cun),轉發(fa)給(gei)其(qi)他(ta)節點(dian),再(zai)給(gei)應(ying)用(yong)發(fa)回確認(ren)的。寫入(ru)流(liu)程如下圖(tu)所示:

TDengine 通過多副本(ben)以及(ji) RAFT 一(yi)(yi)(yi)致性協議,保(bao)證(zheng) vnode 和 mnode 的(de)高可用性。對(dui)于元數(shu)據(ju),TDengine 采(cai)取(qu)的(de)是(shi)強一(yi)(yi)(yi)致性,而對(dui)于時(shi)序數(shu)據(ju),TDengine 采(cai)取(qu)的(de)是(shi)弱一(yi)(yi)(yi)致性,這樣保(bao)證(zheng)時(shi)序數(shu)據(ju)的(de)寫入效率。
在不同數據節點上的 vnode 可以形成一個虛擬節點組。虛(xu)擬(ni)(ni)節(jie)點(dian)(dian)(dian)組里,數(shu)據(ju)是通過 RAFT 協議來保證數(shu)據(ju)一致的(de),一般虛(xu)擬(ni)(ni)節(jie)點(dian)(dian)(dian)組有 3 個虛(xu)擬(ni)(ni)節(jie)點(dian)(dian)(dian)。數(shu)據(ju)寫(xie)入操(cao)作(zuo)總是在 Leader 節(jie)點(dian)(dian)(dian)上進行,但是查詢(xun)可(ke)以(yi)(yi)在 Leader 和 Follower 節(jie)點(dian)(dian)(dian)上同(tong)時進行,以(yi)(yi)提(ti)升查詢(xun)能力(li)。當(dang) Leader 節(jie)點(dian)(dian)(dian)失敗,系統將自動選擇新(xin)的(de) Leader,只(zhi)要虛(xu)擬(ni)(ni)節(jie)點(dian)(dian)(dian)組里超過半數(shu)以(yi)(yi)上的(de)節(jie)點(dian)(dian)(dian)仍然(ran)工(gong)作(zuo),那么這(zhe)個虛(xu)擬(ni)(ni)節(jie)點(dian)(dian)(dian)組就可(ke)以(yi)(yi)繼續提(ti)供數(shu)據(ju)寫(xie)入和查詢(xun)操(cao)作(zuo),從(cong)而保證系統的(de)高可(ke)用。
對于(yu) mnode,為(wei)保證其(qi)高可(ke)用,整(zheng)個(ge)集群會部署三(san)個(ge) mnode,這三(san)個(ge) mnode 形成一個(ge)虛擬節點組,它們之間的(de)數據一致性通過(guo) RAFT 來實現,而且是強一致。只要超過(guo)半數的(de) mnode 工作(zuo),mnode 就可(ke)對外服務。
可觀測性(Observability)
TDengine 采集了各種指標來監(jian)測系統是否運行正常,這些指標包括(kuo) CPU、內存、磁盤、流量、請求次(ci)數、延時等。它提供了 Grafana 的看板 TDinsight,以實現這些指標的可(ke)視化與報警。關于更多 TDinsight 的信息(xi),請看。

TDengine 還提供了一個模塊 taosKeeper,它(ta)能(neng)夠(gou)將采(cai)集(ji)的(de)指標發送到(dao)其他監測(ce)工(gong)具,比如 Prometheus,這樣(yang)便(bian)于將 TDengine 的(de)監測(ce)集(ji)成到(dao)已有的(de)可(ke)觀測(ce)系統(tong)。
運維自動化(Automation)
TDengine 可(ke)以用(yong)二進制包或(huo) Docker 鏡像進行安裝。TDengine 集群(qun)可(ke)以在(zai) Kubernetes 環境(jing)通過 kubectl 命(ming)令或(huo) helm chart 來部署。數據(ju)節(jie)點的(de)增加或(huo)刪除可(ke)以通過執行 kubectl 或(huo) heml 命(ming)令進行。TDengine 集群(qun)的(de)管理完(wan)全可(ke)以通過腳本自(zi)動化進行,讓運營和維護變得簡單。關于 Kubernetes 部署,請參考相關文檔。
總結
通過分布式(shi)設(she)計(ji)、分區分片、存儲和(he)(he)計(ji)算(suan)分離,RAFT 一(yi)致性(xing)協議(yi)等手(shou)段,TDengine 這個時序數據處理平(ping)臺(tai)具(ju)備水平(ping)擴展性(xing)、彈(dan)性(xing)與(yu)韌性(xing)。通過支(zhi)持(chi)容器、Kubernetes 部署、全面的(de)(de)指標監測(ce)和(he)(he)自動(dong)化腳本,TDengine 可以方便地運行在(zai)私(si)有云(yun)、公有云(yun)或混合云(yun)上,從而充分利用云(yun)平(ping)臺(tai)的(de)(de)優勢(shi)。因此 TDengine 是(shi)一(yi)個云(yun)原生(sheng)時序數據庫(ku)(Cloud Native Time-Series Database),而不只是(shi)一(yi)個能在(zai)云(yun)上運行的(de)(de)數據庫(ku)。


























