數(shù)據(jù)被存儲在列中,并按時間進(jìn)行分區(qū)
QuestDB與ClickHouse、InfluxDB和TimescaleDB相比如何?
我們看到時間序列基準(zhǔn)測試套件(TSBS https://github.com/timescale/tsbs)經(jīng)常出現(xiàn)在關(guān)于數(shù)據(jù)庫性能的討論,因此我們決定提供對QuestDB和其他系統(tǒng)進(jìn)行基準(zhǔn)測試的能力。TSBS是一個Go程序集,用于生成數(shù)據(jù)集,然后對讀寫性能進(jìn)行基準(zhǔn)測試。該套件是可擴(kuò)展的,因此可以包括不同的用例和查詢類型,并在不同系統(tǒng)之間進(jìn)行比較。
以下是我們在AWS EC2 m5.8xlarge實例上使用多達(dá)14個worker的純cpu用例的基準(zhǔn)測試結(jié)果,該實例有16個內(nèi)核。
TSBS結(jié)果比較了QuestDB、InfluxDB、ClickHouse和TimescaleDB的最大獲取吞吐量
我們使用4個worker達(dá)到最大的攝取性能,而其他系統(tǒng)需要更多的CPU資源來達(dá)到最大的吞吐量。QuestDB用4個線程達(dá)到了95.9萬行/秒。我們發(fā)現(xiàn)InfluxDB需要14個線程才能達(dá)到最大的攝取率(334k行/秒),而TimescaleDB用4個線程達(dá)到145k行/秒。ClickHouse以兩倍于QuestDB的線程達(dá)到914k行/秒。
當(dāng)在4個線程上運行時,QuestDB比ClickHouse快1.7倍,比InfluxDB快6.5倍,比TimescaleDB快6.6倍。
使用4個線程的TSBS基準(zhǔn)測試結(jié)果:QuestDB、InfluxDB、ClickHouse和TimescaleDB每秒獲取的行數(shù)
當(dāng)我們使用AMD Ryzen5處理器再次運行該套件時,我們發(fā)現(xiàn),我們能夠使用5個線程達(dá)到每秒143萬行的最大吞吐量。與我們在AWS上的參考基準(zhǔn)m5.8xlarge實例所使用的英特爾至強Platinum相比:
比較QuestDB TSBS在AWS EC2與AMD Ryzen5上的負(fù)載結(jié)果
你應(yīng)該如何存儲亂序的時間序列數(shù)據(jù)?
事實證明,在攝取過程中對 “亂序”(O3)的數(shù)據(jù)進(jìn)行重新排序特別具有挑戰(zhàn)性。這是一個新的方法,我們想在這篇文章中詳細(xì)介紹一下。我們對如何處理失序攝取的想法是增加一個三階段的方法。
保持追加模式,直到記錄不按順序到達(dá)為止
在內(nèi)存中對暫存區(qū)的未提交的記錄進(jìn)行排序
在提交時對分類的無序數(shù)據(jù)和持久化的數(shù)據(jù)進(jìn)行核對和合并
前兩個步驟很直接,也很容易實現(xiàn),依然只是處理追加的數(shù)據(jù),這一點沒變。只有在暫存區(qū)有數(shù)據(jù)的時候,昂貴的失序提交才會啟動。這種設(shè)計的好處是,輸出是向量,這意味著我們基于向量的閱讀器仍然是兼容的。
這種預(yù)提交的排序和合并方式給數(shù)據(jù)獲取增加了一個額外的處理階段,同時也帶來了性能上的損失。不過,我們還是決定探索這種方法,看看我們能在多大程度上通過優(yōu)化失序提交來減少性能損耗。
我們?nèi)绾畏诸?、合并和提交無序的時間序列數(shù)據(jù)
處理一個暫存區(qū)給了我們一個獨特的機(jī)會來全面分析數(shù)據(jù),在這里我們可以完全避免物理合并,并通過快速和直接的memcpy或類似的數(shù)據(jù)移動方法來替代。由于我們的基于列的存儲,這種方法可以被并行化。我們可以采用SIMD和非時序數(shù)據(jù)訪問,這對我們來說是很重要的。
我們通過優(yōu)化版本的radix排序?qū)碜詴捍鎱^(qū)的時間戳列進(jìn)行排序,所產(chǎn)生的索引被用于并行對暫存區(qū)的其余列進(jìn)行排序。
并行得將列進(jìn)行排序
現(xiàn)在排序的暫存區(qū)是相對于現(xiàn)有分區(qū)數(shù)據(jù)進(jìn)行映射的。從一開始可能并不明顯,但我們正試圖為以下三種類型的每一種建立所需的操作和維度。
?失序(O3)排序和合并方案
當(dāng)以這種方式合并數(shù)據(jù)集時,前綴和后綴組可以是持續(xù)的數(shù)據(jù)、失序的數(shù)據(jù),或者沒有數(shù)據(jù)。合并組(Merge Group)是最繁忙的,因為它可以被持久化的數(shù)據(jù)、失序的數(shù)據(jù)、失序的數(shù)據(jù)和持久化的數(shù)據(jù)占據(jù),或者沒有數(shù)據(jù)。
當(dāng)明確了如何分組和處理暫存區(qū)的數(shù)據(jù)時,一個工人池就會執(zhí)行所需的操作,在少量的情況下調(diào)用memcpy,其他都轉(zhuǎn)向SIMD優(yōu)化的代碼。通過前綴、合并和后綴拆分,提交的最大活度(增加CPU容量的易感性)可以通過partition_affected x number_of_columns x 3得到。
時間序列數(shù)據(jù)應(yīng)該多久進(jìn)行一次排序和合并?
能夠快速復(fù)制數(shù)據(jù)是一個不錯的選擇,但我們認(rèn)為在大多數(shù)時間序列獲取場景中可以避免大量的數(shù)據(jù)復(fù)制。假設(shè)大多數(shù)實時失序的情況是由傳遞機(jī)制和硬件抖動造成的,我們可以推斷出時間戳分布將在一定區(qū)間范圍。
例如,如果任何新的時間戳值有很大概率落在先前收到的值的10秒內(nèi),那么邊界就是10秒,我們稱這個為滯后邊界。
當(dāng)時間戳值遵循這種模式時,推遲提交可以使失序提交成為正常的追加操作。失序系統(tǒng)可以處理任何種類的延遲,但如果延遲的數(shù)據(jù)在指定的滯后邊界內(nèi)到達(dá),它將被優(yōu)先快速處理。
如何比較時間序列數(shù)據(jù)庫的性能
我們已經(jīng)在TimescaleDB的TSBS GitHub倉庫中開啟了一個合并請求(Questdb基準(zhǔn)支持 https://github.com/timescale/tsbs/issues/157),增加了針對QuestDB運行基準(zhǔn)測試的能力。同時,用戶可以克隆我們的基準(zhǔn)測試fork(https://github.com/questdb/tsbs),并運行該套件以查看自己的結(jié)果。
tsbs_generate_data –use-case=”cpu-only” –seed=123 –scale=4000 `。
–timestamp-start=”2016-01-01T00:00:00Z” –timestamp-end=”2016-01-02T00:00:00Z” \
–log-interval=”10s” –format=”influx” > /tmp/bigcpu
tsbs_load_questdb –file /tmp/bigcpu –workers 4
構(gòu)建具有授權(quán)許可的開源數(shù)據(jù)庫
在進(jìn)一步推動數(shù)據(jù)庫性能的同時,使開發(fā)人員能夠輕松地開始使用我們的產(chǎn)品,這一點每天都激勵著我們。這就是為什么我們專注于建立一個堅實的開發(fā)者社區(qū),他們可以通過我們的開源分銷模式參與并改進(jìn)產(chǎn)品。
除了使QuestDB易于使用之外,我們還希望使其易于審計、審查,提交代碼或其他的項目貢獻(xiàn)。QuestDB的所有源代碼都在GitHub(https://github.com/questdb/questdb)上以Apache 2.0許可證提供,我們歡迎對此產(chǎn)品的各種貢獻(xiàn),包括在GitHub上創(chuàng)建issue或者提交代碼。
? 2021年QuestDB。由Slab提供