在(zai) 8 月 13 日的(de) TDengine 開發(fa)者大(da)會上,濤思數據(ju)創(chuang)始(shi)人陶(tao)建輝進(jin)行了題為《高性能、云原生的(de)極簡時(shi)序數據(ju)處(chu)理平臺》的(de)主題演(yan)講(jiang)。在(zai)本次演(yan)講(jiang)中,他(ta)不僅分享了時(shi)序數據(ju)庫現階段(duan)的(de)技術痛點,還深入(ru)闡釋了打造 TDengine 3.0 的(de)原因以及實踐思路。本文根據(ju)演(yan)講(jiang)內(nei)容整(zheng)理而(er)成。
在 2017 年剛開始做時序數據庫(Time Series Database,TSDB)時,學物(wu)理的我想(xiang)當然地認為做好數據(ju)庫沒有大家說(shuo)的那么難,但做了 5 年后才(cai)發現,這真的不是一(yi)件(jian)很容(rong)易的事(shi)。下面我具體(ti)說(shuo)說(shuo)難在哪里:
- 水平擴展性(Scalability)問題。在 TDengine 剛開發沒多久時,我用一臺 128 核的機器對 TDengine 進行了測試,結果性能遠遠沒有達到預期,這件事情也讓我清楚地意識到,理想的水平擴展能力很難實現。
- 沒有真正的云原生化。我個人特別堅信云是未來,數據庫也一定要走向云原生(Cloud Native),但在深度研究市面上的數據庫產品后,我發現大部分數據庫都不是云原生,而僅僅是“云就緒”(Cloud Ready),即數據庫服務提供商在轉售云平臺。真正的云原生數據庫應該具備存算分離、計算和存儲能力彈性擴張、能夠在云上部署、自動化部署等特點。
- 復雜性(Complex)問題。2016 年我看到很多人在處理一些簡單的時序數據時,要把整個 Hadoop 系統搬過來,要加 HBase 層,還要把 Flink、Spark 等等全部加上,這對于研發人員來講就是個災難。但時至今日,這個復雜性也并沒有隨著時序數據庫的發展得到充分的解決,只有打造一個集 Kafka、Flink、Spark、Redis 等第三方工具功能于一體的極簡時序數據處理平臺,這一問題才有望充分解決。
- 數據分析能力跟不上。諸如 InfluxDB、Prometheus 等較為流行的 Time-Series Database,由于不支持 SQL,導致很多正常的數據服務、數據倉庫的分析方法都用不上。結合我過往不斷跨界的經驗,我發現了這個問題,所以 TDengine 早就支持了 SQL,不過仍然需要優化和加強。
發(fa)現并解決上述(shu)的(de)問題,便是我(wo)們打造 TDengine 3.0 的(de)初衷(zhong)。從去年 6 月開始,在 40 多(duo)個研(yan)發(fa)一年多(duo)的(de)努力下,TDengine 3.0 終于(yu)在今天正式和(he)大家(jia)見面了。
下面我們就一起看(kan)看(kan) TDengine 3.0 是什么樣子的(de)。
云原生時序數據庫
水平擴展

打造云原生時序(xu)數(shu)據(ju)庫,第一個(ge)要素就是(shi)必(bi)須是(shi)分布(bu)式架(jia)構(gou)。其(qi)實(shi) TDengine 以前也是(shi)分布(bu)式架(jia)構(gou),但為了實(shi)現云原生的(de)種種特性(xing),我們在此(ci)架(jia)構(gou)基礎上引入了一個(ge)新的(de)節(jie)點(dian)——計算節(jie)點(dian) Qnode。

那通過(guo)云原生(sheng)如何解決可擴(kuo)展性(xing)問題?還是通過(guo)分片(pian)分區(qu)來解決,數(shu)據(ju)切分的方法我們沒有做(zuo)太多改(gai)動,TDengine 一開(kai)始就是這么(me)做(zuo)的,在時(shi)間軸上以天或周為單位(wei)對數(shu)據(ju)進行(xing)切分,同時(shi)將定(ding)量設(she)備的數(shu)據(ju)分配(pei)給(gei)每個區(qu)(Vnode)進行(xing)處理。
跟 2.x 相比,3.0 最大的不同就是元數據的管理也變成了完全分布式的。這(zhe)也是(shi)我在此(ci)前版本中吸取了一個教訓而做出的改(gai)變(bian),最開(kai)始我沒想到元數據的管理如(ru)此(ci)之難(nan)。
有一次我們和涂鴉聊合作,他們要測五千萬個設備的數據,TDengine 2.0 在測試中就出現了高基數問題。在 2.x 的設計中,我們的元數據統一存放在 mnode 中,這在此次測試中就成為了一個瓶頸——在進行聚合操作時,光是把五千萬個設備中的標簽數據拉出來就需要很長時間,聚合速度可想而知。也因此,高基數成為了我們在 3.0 版本中解決的首要問題。
現在(zai)的(de) TDengine 管理(li)節點不(bu)再存儲每(mei)個(ge)(ge)設備或每(mei)張表(biao)的(de)元(yuan)數(shu)據了,而是把這(zhe)些元(yuan)數(shu)據還有時序數(shu)據完全存儲在(zai) vnode 里,之后會用 B+ 樹、一(yi)致性哈希來處(chu)理(li)。這(zhe)樣一(yi)來,我們在(zai)插入(ru)一(yi)個(ge)(ge)數(shu)據到任(ren)何(he)一(yi)個(ge)(ge)片或者一(yi)個(ge)(ge)區時都不(bu)再需(xu)要(yao)經(jing)過任(ren)何(he)中(zhong)間節點,徹(che)底(di)解決(jue)了高(gao)基數(shu)的(de)問題(ti)。
經過測試,TDengine 3.0 完全能夠支持 10 億個設備、100 臺服務器節點,同時(shi)(shi)整個啟動(dong)(dong)時(shi)(shi)間也很快,不到一分(fen)鐘整個集群(qun)就能啟動(dong)(dong)。盡(jin)管(guan)此前(qian)的(de) 2.6 也能支(zhi)持(chi)五千萬的(de)設(she)(she)備數,但啟動(dong)(dong)時(shi)(shi)間就大概要三四(si)十分(fen)鐘,設(she)(she)備數量多的(de)時(shi)(shi)候不太給力(li)。
中(zhong)國智能(neng)電表至少要有十億(yi)臺,給十億(yi)臺電表做聚(ju)合操(cao)作可(ke)以說相當(dang)不容易,解(jie)決(jue)高(gao)基(ji)數問(wen)題是很重要的,TDengine 發展到 3.0 版本才算是真正把這(zhe)個問(wen)題解(jie)決(jue)了。
彈性

云原生里面一(yi)(yi)(yi)個(ge)很重要的(de)東西就(jiu)是彈性(xing),它跟水平擴展的(de)彈性(xing)還略有不同,首(shou)先一(yi)(yi)(yi)定要把計(ji)算(suan)和存儲(chu)分離,我(wo)上面說 3.0 新增了一(yi)(yi)(yi)個(ge)計(ji)算(suan)節點 Qnode,它是專(zhuan)門用來做(zuo)計(ji)算(suan)的(de),但(dan)簡單查詢(xun) Vnode 就(jiu)可以直接操作了,如(ru)果牽(qian)扯(che)到 group by、order by 等復(fu)雜查詢(xun),就(jiu)需要在 Qnode 上進行了。
Qnode 的優點就是操作者可以動態地啟動、停止,也就(jiu)是說它(ta)的計(ji)算(suan)資源可以(yi)動態地進行操(cao)控(kong),這樣就(jiu)實現了存算(suan)分離。同時 Vnode 也可以(yi)進行拆分或合并(bing),保證存儲也可以(yi)彈(dan)性伸(shen)縮。
如(ru)果系統不能做到真正(zheng)的(de)彈性伸縮,就(jiu)一(yi)定不是云(yun)(yun)原(yuan)生(sheng)的(de),很(hen)多企業(ye)打(da)著云(yun)(yun)原(yuan)生(sheng)的(de)幌子,但實(shi)際上連云(yun)(yun)原(yuan)生(sheng)是什么都說不清(qing)楚(chu)。在我(wo)看來,云(yun)(yun)原(yuan)生(sheng)就(jiu)是要充分(fen)利(li)用云(yun)(yun)平臺(tai)的(de)優勢(shi),即計算資(zi)源、存儲資(zi)源、網絡(luo)資(zi)源,且(qie)要完全(quan)彈性,你想要就(jiu)馬上給你,不想要就(jiu)馬上釋放,這樣才能真正(zheng)實(shi)現成本的(de)節約。
韌性
云原生里還有一個重要概念叫韌性,簡單來講就是高可靠、高可用。TDengine 在(zai)設計之初(chu)就(jiu)考慮到了這(zhe)一(yi)點,其高可用就(jiu)是用多個副本(ben)來實現,但后面(mian)發現以(yi)前的同(tong)步(bu)算(suan)法還是存在(zai)漏洞,因此(ci) 3.0 就(jiu)完全采用了標準 RAFT 協議(yi)來實現數據復制,以(yi)此(ci)保證數據一(yi)致性。
除了高可用,合格(ge)的韌(ren)性還要保(bao)證(zheng)系統(tong)的高可靠,保(bao)證(zheng)機(ji)器即使宕機(ji)了依然(ran)還能(neng)重啟,且還能(neng)繼續工作,數據也不會(hui)丟(diu)失。
部署、維護
我們以(yi)前都是(shi)建議用戶到 Kubernetes 上部署(shu),但并沒有出(chu)詳細的(de)自(zi)動(dong)化流程,3.0 版本給(gei)出(chu)了詳細的(de) Kubernetes 部署(shu)文檔,只需修(xiu)改(gai)兩(liang)個(ge)配置文件,馬上就能部署(shu)整個(ge)集(ji)群,極(ji)其簡單。
除了(le)更加(jia)理解云原生,3.0 給我帶(dai)來(lai)的另一(yi)個(ge)收獲(huo)就是(shi)(shi)對(dui)于可(ke)觀測(ce)性(xing)的理解,可(ke)觀測(ce)性(xing)其實遠(yuan)遠(yuan)不只是(shi)(shi)監(jian)控,它包括了(le) logging、tracing、metrics,我們在 3.0 上實現了(le)整個(ge)架(jia)構,讓(rang)用戶對(dui) TDengine 所(suo)有集(ji)群的運行狀態(tai)都(dou)能(neng)真正監(jian)測(ce)到,讓(rang)系統維護(hu)變(bian)得更加(jia)簡單。在維護(hu)上,還有關鍵(jian)一(yi)點(dian)就是(shi)(shi)要(yao)做到自動化,一(yi)切都(dou)要(yao)腳本化,減少人工手動操作的成本。
極簡的時序數據處理平臺
在 TDengine 創建(jian)之初,打(da)造一款極簡的時(shi)序數(shu)(shu)(shu)(shu)據(ju)處理(li)平臺(tai)就是我的初衷。要知道,一個(ge)通(tong)用的架構往(wang)往(wang)是要先把采集(ji)數(shu)(shu)(shu)(shu)據(ju)送到 Kafka 或者各種消(xiao)息隊(dui)列里,消(xiao)費之后一部(bu)分(fen)數(shu)(shu)(shu)(shu)據(ju)再送到 Spark 或者 Flink 里做流計算處理(li),一部(bu)分(fen)數(shu)(shu)(shu)(shu)據(ju)送到數(shu)(shu)(shu)(shu)據(ju)庫做直接存儲,還有一部(bu)分(fen)則會傳輸(shu)到 Redis 做緩存,這樣一個(ge)數(shu)(shu)(shu)(shu)據(ju)處理(li)平臺(tai),里面要集(ji)成很多軟件,維(wei)護起來相當困(kun)難(nan)。
要打(da)造一款極簡的(de)時(shi)序數據處(chu)理平臺,首先要解(jie)決(jue)的(de)問題就是(shi)(shi)緩存,因為緩存對于物聯(lian)網、車聯(lian)網來講都是(shi)(shi)極其關鍵的(de),TDengine 早就具(ju)備(bei)了緩存功能,這(zhe)個也是(shi)(shi)很多用戶特別喜歡的(de)功能,非常(chang)方便(bian)。

對于 TDengine 3.0 來說,還有一個很大的改進是重構并優化了數據訂閱功能。TDengine 是用(yong) WAL 來(lai)(lai)做的訂(ding)閱,技術人(ren)員應該都知道(dao),WAL 本身就可(ke)以(yi)看作一個(ge)隊(dui)列,完(wan)全按照數(shu)據(ju)到(dao)達(da)順(shun)序來(lai)(lai)追(zhui)加寫入。在 TDengine 3.0 中,既可(ke)以(yi)訂(ding)閱一個(ge)數(shu)據(ju)庫,也可(ke)以(yi)訂(ding)閱一個(ge)自帶(dai)標簽(qian)的“超級表(biao)”,直(zhi)(zhi)接實現過(guo)濾,比如只(zhi)想訂(ding)閱功率超過(guo)多少的智能電表(biao)數(shu)據(ju),直(zhi)(zhi)接就能實現。訂(ding)閱完(wan)成后無需再拿(na)到(dao)應用(yong)端(duan)去過(guo)濾,極大提升了(le)數(shu)據(ju)傳輸的效率。
我(wo)們做產品的(de)(de)目的(de)(de)就是(shi)(shi)(shi)(shi)要(yao)讓大(da)家用起來簡(jian)單(dan),因此(ci)在做消(xiao)息隊(dui)列(lie)(lie)功(gong)能時,API 全(quan)部對標(biao)的(de)(de)都(dou)是(shi)(shi)(shi)(shi) Kafka,現在不光是(shi)(shi)(shi)(shi)初(chu)始化和每條(tiao)命令,連測(ce)試(shi)都(dou)完全(quan)一樣(yang)。以(yi)前經(jing)常有友商會對標(biao) TDengine,提出性能要(yao)超出 TDengine 一百(bai)倍之類的(de)(de)觀(guan)點,但(dan)標(biao)準就是(shi)(shi)(shi)(shi)自己定義的(de)(de),甚(shen)至(zhi)都(dou)沒有公開。但(dan)我(wo)們只采用國際(ji)通用的(de)(de)測(ce)試(shi)標(biao)準來測(ce),包括(kuo)消(xiao)息隊(dui)列(lie)(lie),直接用 Kafka 公開的(de)(de) benchmark 進行(xing)測(ce)試(shi),我(wo)們認為這樣(yang)才有說(shuo)服力,才是(shi)(shi)(shi)(shi)客(ke)觀(guan)的(de)(de)。歡迎大(da)家體驗(yan)。
TDengine 3.0 還有一個很大的改進就是繼續優化了流計算功能。之前 TDengine 就已(yi)經(jing)(jing)支持一個連續查詢的流(liu)計算,這種周(zhou)期性(xing)的查詢流(liu)計算還是(shi)很(hen)有用的,但(dan)是(shi)功(gong)能(neng)覆蓋卻還不(bu)夠。在 IoT 場景(jing)下做數據清洗(xi)、過(guo)濾時,要做一些實時的觸發,必須使用事(shi)件驅(qu)動的流(liu)計算,經(jing)(jing)過(guo)一年多(duo)的努力(li),TDengine 3.0 終于升級了這一流(liu)計算功(gong)能(neng)。

TDengine 3.0 所(suo)支持(chi)的(de)(de)流(liu)計算(suan)功能是非常典型的(de)(de),如上(shang)面(mian)的(de)(de)架構圖所(suo)示(shi),數據源要先進(jin)入(ru) Input Queue,再(zai)進(jin)入(ru)流(liu)計算(suan)的(de)(de) Task,再(zai)輸出(chu)到另(ling)外一個列。而且流(liu)計算(suan)可(ke)以嵌套,一層一層形(xing)成一個數據的(de)(de) pipeline。從(cong)方便用戶使用的(de)(de)角度(du)出(chu)發,TDengine 的(de)(de)流(liu)計算(suan)語法就是 SQL,里面(mian)做了 windows 等(deng)擴展(zhan),可(ke)以在數據寫入(ru)時觸發,也可(ke)以在窗口結束觸發。
此外, TDengine 3.0 對 UDF 的支持也進行了優化。3.0 對 UDF 進行了重新實現,加上時(shi)間驅動的流計算(suan),我覺得(de)至(zhi)少在時(shi)序數據的場(chang)景下(xia),TDengine 已經能夠完(wan)全代替(ti) Spark 和 Flink。

但(dan)在此(ci)我需要再(zai)重(zhong)申一下,我們(men)優化 TDengine 的緩(huan)存、消(xiao)息隊(dui)列、流計算(suan)等功能,并不是(shi)想代替 Flink、Spark、Kafka 這(zhe)類通用型的消(xiao)息隊(dui)列軟件(jian)、流計算(suan)軟件(jian),只是(shi)想簡(jian)化這(zhe)款(kuan)基于時(shi)序(xu)數據(ju)場景做的數據(ju)庫軟件(jian),更(geng)加(jia)便于大(da)家使用,通過降低系統復雜(za)度來真正(zheng)降低運維和存儲成本,這(zhe)也是(shi)我們(men)搭建極簡(jian)時(shi)序(xu)數據(ju)處(chu)理平(ping)臺的原(yuan)因。
便捷的數據分析

TDengine 3.0 還有一個較大的改變就是重新設計了計算引擎,現在(zai)像 Planner、優化(hua)器、執(zhi)行器等都具備了。對于數據來說,查詢是(shi)非(fei)常重要的,數據存儲好之后,用戶最重要的就是(shi)要從中挖(wa)掘數據價值,TDengine 對 SQL 的支持(chi)已經做(zuo)的很好了。
但(dan)是 SQL 這個概念也(ye)很復(fu)雜(za),我們不可(ke)能像 Oracle 一樣支持(chi)那么(me)多詳細的(de)(de)復(fu)雜(za)查(cha)詢,3.0 的(de)(de)查(cha)詢對標的(de)(de)是 Hive,Hive 能做(zuo)的(de)(de)所有(you)(you)的(de)(de)分(fen)析 TDengine 已(yi)經都能做(zuo)了(le)。此外(wai),TDengine 也(ye)有(you)(you)很多針對時(shi)序數據的(de)(de)特有(you)(you)函數,比(bi)如說移動平(ping)均、時(shi)間加(jia)權(quan)平(ping)均等等。
重構(gou)查詢引(yin)擎(qing)的 TDengine 3.0 已經成為了一個(ge)很好的查詢工具,再輔(fu)以下面的這些手(shou)段(duan),足以讓查詢變(bian)得更有效:
- 超級表適合做多維度分析
- 計算與存儲分離
- 數據分片、分區
- 流處理
- 歷史數據和實時數據統一分析
- 來自控制臺的臨時查詢
- Python Pandas,數據框支持
- Grafana,用于可視化的谷歌數據工作室
TDengine 3.0 的最后一個更新功能叫作 taosX,它充分利用了 TDengine 的數據訂閱功能來解決增量備份、異地容災,即把一(yi)個(ge)(ge)集(ji)群的數據復制到(dao)另(ling)外一(yi)個(ge)(ge)地方去,以實(shi)現邊(bian)(bian)云協(xie)同(tong)。眾所(suo)周(zhou)知,邊(bian)(bian)云協(xie)同(tong)在(zai)物聯網里面很重要,如果說工(gong)廠的數據想要同(tong)步到(dao)集(ji)團,就(jiu)(jiu)需(xu)要一(yi)個(ge)(ge)邊(bian)(bian)云的盒子(zi)一(yi)層(ceng)接一(yi)層(ceng)做同(tong)步,而這個(ge)(ge)需(xu)求,在(zai) TDengine 中就(jiu)(jiu)靠(kao) taosX 解決(jue)了。
此外除了技術上的種種進步外,今天我還要給大家同步一個好消息。為了方便工業場景下大量的 Windows 客戶,TDengine 3.0 的 Windows 版本也正式發布了,包括客戶端和服務器。同(tong)時,大概在 10 月 1 日,TDengine 的 Mac 版本也將正式(shi)對(dui)外發布,大家敬請期待。

目前 TDengine 3.0 的(de)(de)(de)(de)(de)代(dai)(dai)碼已經在 GitHub() 上公開(kai)(kai),大家可(ke)以完全參照我(wo)們的(de)(de)(de)(de)(de) readme 文(wen)件來編譯(yi),也可(ke)以到 TDengine 的(de)(de)(de)(de)(de)官(guan)網去下載。如果(guo)你(ni)(ni)是(shi)(shi)一個開(kai)(kai)發(fa)者,覺(jue)得(de) TDengine 這(zhe)個項目有(you)意思,可(ke)以選擇加入我(wo)們的(de)(de)(de)(de)(de)開(kai)(kai)發(fa)者社區,學(xue)習(xi)源代(dai)(dai)碼,甚至是(shi)(shi)貢(gong)獻代(dai)(dai)碼。如果(guo)你(ni)(ni)是(shi)(shi)一個物(wu)聯網或者工(gong)業互聯網應(ying)用的(de)(de)(de)(de)(de)開(kai)(kai)發(fa)者,那歡迎(ying)你(ni)(ni)把 TDengine 應(ying)用起(qi)來,你(ni)(ni)可(ke)以加入我(wo)們的(de)(de)(de)(de)(de)用戶(hu)群(qun),我(wo)們很樂(le)意回答你(ni)(ni)的(de)(de)(de)(de)(de)問(wen)題。如果(guo)你(ni)(ni)是(shi)(shi)個 DBA,那歡迎(ying)你(ni)(ni)馬(ma)上下載,去體驗我(wo)剛才講的(de)(de)(de)(de)(de)各(ge)種功能。
中國的(de)開源軟件特別需(xu)要大家的(de)支持和使用,我(wo)經(jing)常跟銷售團隊起爭論,比如在決(jue)定(ding)哪(na)些功(gong)能(neng)必須放(fang)在企(qi)業版(ban)時,我(wo)就表示所有的(de)核心(xin)功(gong)能(neng)都(dou)必須同步在開源版(ban)本上,而絕不能(neng)只放(fang)在企(qi)業版(ban)里(li)。為(wei)什么?因為(wei)想要做好開源就一定(ding)要給用戶帶(dai)來價(jia)值(zhi),我(wo)希望有越(yue)來越(yue)多的(de)人能(neng)夠(gou)成為(wei) TDengine 的(de)布(bu)道(dao)者。
結語

我特別(bie)喜歡丘(qiu)吉(ji)爾的(de)這(zhe)(zhe)段名(ming)言,翻譯成中(zhong)文就是(shi)(shi)“成功(gong)不是(shi)(shi)終點,失(shi)敗不是(shi)(shi)終結,唯有(you)你(ni)繼(ji)續(xu)前行的(de)勇氣最為關鍵”。從(cong)創建 TDengine 到現在(zai)(zai),我們已(yi)經走過了 5 個年(nian)(nian)頭,開源也已(yi)經走過了 3 年(nian)(nian),在(zai)(zai)這(zhe)(zhe)個過程中(zhong)取得(de)了一(yi)些小小的(de)成功(gong),但是(shi)(shi)我們前面(mian)的(de)路還(huan)很漫長,我已(yi)經做(zuo)好了再戰(zhan) 5 年(nian)(nian)、10 年(nian)(nian)的(de)準(zhun)備(bei)。希望我在(zai)(zai)七八(ba)十(shi)歲的(de)時(shi)候(hou)還(huan)能(neng)繼(ji)續(xu)寫(xie)代碼,和大家一(yi)起討(tao)論問題,度(du)過真正有(you)價值的(de)一(yi)生。


























