時(shí)序數(shù)據(jù)庫(kù)TDengine寫(xiě)入查詢(xún)的問(wèn)題分析
寫(xiě)入問(wèn)題
必須為每個(gè)Tag組合起一個(gè)表名
付出的代價(jià):
- 用戶(hù)必須要保證每個(gè)Tag組合起的表名唯一,并且一旦Tag組合數(shù)過(guò)多用戶(hù)很難記住每個(gè)Tag組合對(duì)應(yīng)的表名,在查詢(xún)時(shí)基本都是靠超級(jí)表STable來(lái)查詢(xún)。所以對(duì)用戶(hù)來(lái)說(shuō)這個(gè)表名幾乎沒(méi)用到卻讓用戶(hù)來(lái)花代價(jià)來(lái)起名
這樣設(shè)計(jì)的最終目的是為了將相同Tag組合的數(shù)據(jù)放到一起,但是系統(tǒng)設(shè)計(jì)時(shí)完全可以自己內(nèi)部針對(duì)這個(gè)Tag組合記錄一個(gè)唯一id或者唯一字符串來(lái)作為內(nèi)部隱藏的表名,來(lái)替換讓用戶(hù)自己起表名的操作,對(duì)用戶(hù)只需要呈現(xiàn)一個(gè)超級(jí)表STable即可,減輕用戶(hù)負(fù)擔(dān)。
其實(shí)可以看到上述其實(shí)是將系統(tǒng)內(nèi)部判斷唯一的負(fù)擔(dān)轉(zhuǎn)交給用戶(hù),麻煩了用戶(hù)。假如系統(tǒng)內(nèi)部自動(dòng)判斷Tag組合是否唯一,則在數(shù)據(jù)寫(xiě)入過(guò)程中一直需要判斷當(dāng)前Tag組合是否存在以及查找對(duì)應(yīng)的底層唯一id或者唯一字符串,而讓用戶(hù)起表名則省去了上述代價(jià),因?yàn)橛脩?hù)起的表名就是一個(gè)唯一的字符串,所以寫(xiě)入性能自然好一些
Tag支撐與管理
- 最多支持6個(gè)Tag,如果想要支持更多就要重新源碼編譯
- 超級(jí)表STable對(duì)Tag組合的索引是全內(nèi)存的,終將會(huì)遇到瓶頸的,InfluxDB已經(jīng)走過(guò)這條路了,從之前的全內(nèi)存到后面的tsi
- 超級(jí)表STable對(duì)Tag組合的索引僅僅是對(duì)第一個(gè)Tag作為key來(lái)構(gòu)建一個(gè)skiplist,也就是說(shuō)當(dāng)你的查詢(xún)用到第一個(gè)tag時(shí)可以利用下上述索引,當(dāng)你的查詢(xún)沒(méi)用到第一個(gè)tag時(shí),那就是暴力全掃,所以這種在Tag組合數(shù)過(guò)多的時(shí)候過(guò)濾查詢(xún)能力還是很有限的。而像其他時(shí)序數(shù)據(jù)庫(kù)InfluxDB、Druid都在寫(xiě)入過(guò)程中針對(duì)Tag組合構(gòu)建了倒排索引來(lái)應(yīng)對(duì)任意維度的過(guò)濾,寫(xiě)入性能比TDengine自然就會(huì)差一些
- 對(duì)于不再使用的Tag組合的過(guò)期目前也是個(gè)麻煩的事情
不支持亂序?qū)懭?/h3>
每張表會(huì)記錄該表目前寫(xiě)入的最大時(shí)間,一旦后續(xù)的寫(xiě)入時(shí)間小于該時(shí)間則不允許寫(xiě)入。假如你不小心向某張表寫(xiě)入2021-07-24 00:00:00時(shí)間的數(shù)據(jù),那么該時(shí)間之前的數(shù)據(jù)都無(wú)法寫(xiě)入了
這樣做帶來(lái)的好處,簡(jiǎn)化了寫(xiě)入過(guò)程,寫(xiě)入過(guò)程永遠(yuǎn)是append操作。舉個(gè)簡(jiǎn)單例子,比如用數(shù)組來(lái)存放內(nèi)存數(shù)據(jù),數(shù)組中的數(shù)據(jù)是按時(shí)間排序的,如果后來(lái)的數(shù)據(jù)的時(shí)間不是遞增,那么就需要將數(shù)據(jù)插入到數(shù)組中間的某個(gè)位置,并且需要將該位置之后的數(shù)據(jù)全部后移。假如后來(lái)的數(shù)據(jù)的時(shí)間都是遞增的,那么直接往數(shù)組的最后面放即可,所以不支持亂序?qū)懭爰匆誀奚脩?hù)使用為代價(jià)來(lái)簡(jiǎn)化寫(xiě)入過(guò)程提高寫(xiě)入性能
不支持亂序?qū)懭脒€省去的一個(gè)麻煩就是:LSM中常見(jiàn)的compact。如果允許亂序?qū)懭?,那么就?huì)存在2個(gè)文件中時(shí)間范圍是有重疊的,那么就需要像RocksDB那樣來(lái)進(jìn)行compact來(lái)消滅重疊,進(jìn)而減少查詢(xún)時(shí)要查詢(xún)的文件個(gè)數(shù),所以你就會(huì)發(fā)現(xiàn)HBase、RocksDB、InfluxDB等等辛辛苦苦設(shè)計(jì)的compact在TDengine中基本不存在
總結(jié)一下就是:不支持亂序?qū)懭胧且誀奚脩?hù)的使用為代價(jià)來(lái)提高寫(xiě)入性能以及簡(jiǎn)化設(shè)計(jì)
查詢(xún)問(wèn)題
求topN的group
order by只能對(duì)時(shí)間、以及tag進(jìn)行排序。top或者bottom只能對(duì)某個(gè)field求topN
時(shí)序領(lǐng)域非常常見(jiàn)的topN的group,比如求CPU利用率最大的3臺(tái)機(jī)器,目前也無(wú)法滿(mǎn)足
downsampling和aggregation
downsampling:將同一根時(shí)間線上1s粒度的數(shù)據(jù)聚合成10s粒度的數(shù)據(jù)
aggregation:將同一時(shí)刻多根時(shí)間線聚合成1根時(shí)間線
比如每個(gè)appId有多臺(tái)機(jī)器,每臺(tái)機(jī)器每秒都會(huì)記錄該機(jī)器的連接數(shù),目前想畫(huà)出每個(gè)appId的總連接數(shù)的曲線
假如使用標(biāo)準(zhǔn)SQL則可能表示如下:
select sum(avg_host_conn),appid,new_time from ( select avg(connection) as avg_host_conn, appid,host,time/10 as new_time from t1 group by appid,host,time/10 ) as t2 group by appid, new_time
內(nèi)部的子查詢(xún)會(huì)先將每個(gè)appid的host 10s內(nèi)的connection求平均值,即downsampling,外部的查詢(xún)將每個(gè)appid下的host的上述平均值求和,即aggregation
由于這類(lèi)需求在時(shí)序查詢(xún)中太常見(jiàn)了,使用上述SQL書(shū)寫(xiě)非常麻煩,有些系統(tǒng)就通過(guò)函數(shù)嵌套的方式來(lái)簡(jiǎn)化這類(lèi)查詢(xún)的書(shū)寫(xiě)
目前TDengine的聚合函數(shù)要么只能是downsampling要么只能是aggregation,也不支持子查詢(xún),那么是無(wú)法滿(mǎn)足上述需求的
查詢(xún)聚合架構(gòu)
查詢(xún)分2階段:第一階段請(qǐng)求管理節(jié)點(diǎn),獲取符合tag過(guò)濾的所有表的meta信息(包含每個(gè)表在哪個(gè)數(shù)據(jù)節(jié)點(diǎn)上),假如滿(mǎn)足條件的表有上百萬(wàn)個(gè),這這個(gè)階段的查詢(xún)基本也吃不消,第二階段向數(shù)據(jù)節(jié)點(diǎn)查詢(xún)聚合每個(gè)表的數(shù)據(jù),返回給客戶(hù)端,客戶(hù)端再做最終的聚合。
這種查詢(xún)方案終究還是會(huì)面臨客戶(hù)端聚合瓶頸的,還是要上多機(jī)協(xié)調(diào)的分布式查詢(xún)方案比如類(lèi)似Presto、Impala等等
以上就是時(shí)序數(shù)據(jù)庫(kù)TDengine寫(xiě)入問(wèn)題分析的詳細(xì)內(nèi)容,更多關(guān)于時(shí)序數(shù)據(jù)庫(kù)TDengine寫(xiě)入的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
如何在Navicat新建連接、新建數(shù)據(jù)庫(kù)以及導(dǎo)入數(shù)據(jù)庫(kù)
Navicat是圖形化操作MySQL的強(qiáng)大工具,但是當(dāng)數(shù)據(jù)庫(kù)的服務(wù)器沒(méi)有開(kāi)放3306端口給辦公網(wǎng)絡(luò)時(shí),在辦公網(wǎng)使用navicat連接數(shù)據(jù)庫(kù)是連不上的,下面這篇文章主要給大家介紹了關(guān)于如何在Navicat新建連接、新建數(shù)據(jù)庫(kù)以及導(dǎo)入數(shù)據(jù)庫(kù)的相關(guān)資料,需要的朋友可以參考下2023-05-05
詳解通過(guò)SQL進(jìn)行分布式死鎖的檢測(cè)與消除
本文主要介紹在 GaussDB(DWS) 中,如何通過(guò) SQL 語(yǔ)句,對(duì)分布式死鎖進(jìn)行檢測(cè)和恢復(fù)。2021-05-05
使用Sqlyog遠(yuǎn)程連接數(shù)據(jù)庫(kù)報(bào)錯(cuò)解決方案
大家好,本篇文章主要講的是使用Sqlyog遠(yuǎn)程連接數(shù)據(jù)庫(kù)報(bào)錯(cuò)解決方案,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話(huà)記得收藏一下,方便下次瀏覽2021-12-12
Navicat恢復(fù)數(shù)據(jù)庫(kù)連接及查詢(xún)sql的完美解決辦法
因?yàn)楣窘o電腦加域,導(dǎo)致使用新的用戶(hù)賬戶(hù),原先的很多配置都失效了,這篇文章主要介紹了Navicat恢復(fù)數(shù)據(jù)庫(kù)連接及查詢(xún)sql的解決辦法,需要的朋友可以參考下2023-08-08
數(shù)據(jù)設(shè)計(jì)之權(quán)限的實(shí)現(xiàn)
這篇文章主要介紹了數(shù)據(jù)設(shè)計(jì)之權(quán)限的實(shí)現(xiàn),文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下2022-08-08
在SQL SERVER中查詢(xún)數(shù)據(jù)庫(kù)中第幾條至第幾條之間的數(shù)據(jù)SQL語(yǔ)句寫(xiě)法
這篇文章主要介紹了在SQL SERVER中查詢(xún)數(shù)據(jù)庫(kù)中第幾條至第幾條之間的數(shù)據(jù)SQL語(yǔ)句寫(xiě)法,需要的朋友可以參考下2015-11-11
數(shù)據(jù)庫(kù)觸發(fā)器(Trigger)的一點(diǎn)使用心得
最近了解了一下數(shù)據(jù)庫(kù)觸發(fā)器,并做一點(diǎn)實(shí)際的應(yīng)用,在翻看其概念的時(shí)候,還是本著從理解的角度來(lái)學(xué)習(xí)的,但是,到了實(shí)際的應(yīng)用場(chǎng)景中,還是有一些特別注意的地方的,下面是自己在應(yīng)用中的幾點(diǎn)體會(huì)2009-07-07
在PostgreSQL的基礎(chǔ)上創(chuàng)建一個(gè)MongoDB的副本的教程
這篇文章主要介紹了在PostgreSQL的基礎(chǔ)上創(chuàng)建一個(gè)MongoDB的副本的教程,使在使用NoSQL的同時(shí)又能用到PostgreSQL中的東西,需要的朋友可以參考下2015-04-04

