不同數(shù)據(jù)庫處理高基數(shù)數(shù)據(jù)的方式,你會嗎?
了解不同數(shù)據(jù)庫如何處理高基數(shù)數(shù)據(jù),并了解選擇正確的索引方案為何如此重要。
譯自How Different Databases Handle High-Cardinality Data,作者 Team Timescale。
時間序列數(shù)據(jù)、物聯(lián)網(wǎng)傳感器讀數(shù)、用戶行為日志——這些只是現(xiàn)代系統(tǒng)必須處理的數(shù)據(jù)流的幾個例子。它們的共同點是都傾向于高基數(shù),這給數(shù)據(jù)存儲和分析帶來了獨特的挑戰(zhàn)。隨著組織越來越依賴數(shù)據(jù)驅(qū)動的決策,了解不同數(shù)據(jù)庫如何處理高基數(shù)數(shù)據(jù)對于構(gòu)建高效且可擴展的系統(tǒng)至關(guān)重要。
本文將探討高基數(shù)數(shù)據(jù)帶來的挑戰(zhàn),檢查旨在處理高基數(shù)數(shù)據(jù)的各種數(shù)據(jù)庫工具,并比較各種方法,以幫助您做出關(guān)于數(shù)據(jù)架構(gòu)的明智決策。
高基數(shù)的挑戰(zhàn)
高基數(shù)指的是數(shù)據(jù)集中唯一元素的數(shù)量,當(dāng)我們查看現(xiàn)實世界的例子時,這是一個特別具體的概念。想象一下一個跟蹤熱門網(wǎng)站上用戶交互的系統(tǒng)——每個用戶可能都有一個唯一的標(biāo)識符,每個會話都會生成一個唯一的ID,每個交互都會創(chuàng)建一個唯一的事件ID。在大規(guī)模應(yīng)用中,這些唯一值可以迅速達(dá)到數(shù)百萬甚至數(shù)十億。
這種大量唯一值會給數(shù)據(jù)庫系統(tǒng)帶來重大挑戰(zhàn)。當(dāng)在具有高基數(shù)列的表之間執(zhí)行連接時,潛在的組合會呈指數(shù)級增長。例如,將用戶交互數(shù)據(jù)與會話數(shù)據(jù)連接可能需要將數(shù)百萬個唯一的用戶ID與數(shù)百萬個唯一的會話ID進(jìn)行匹配。由于數(shù)據(jù)庫必須維護(hù)和處理這些海量獨特的組合,因此生成的運算會迅速壓垮系統(tǒng)資源。
在需要完全表掃描的操作中,性能下降尤其嚴(yán)重。當(dāng)數(shù)據(jù)庫需要跨高基數(shù)列分析或聚合數(shù)據(jù)時,它必須在內(nèi)存中為每個唯一值維護(hù)不同的計數(shù)器或聚合。這會迅速耗盡可用的內(nèi)存資源,導(dǎo)致查詢執(zhí)行時間變慢,或者在極端情況下導(dǎo)致系統(tǒng)故障。
閱讀本文以了解更多關(guān)于高基數(shù)的信息。
數(shù)據(jù)庫解決方案:時間序列數(shù)據(jù)庫InfluxDB和TimescaleDB如何處理高基數(shù)
鑒于高基數(shù)數(shù)據(jù)集在時間序列中有多么常見,讓我們來看看兩個時間序列數(shù)據(jù)庫InfluxDB和TimescaleDB是如何處理這個問題的。
InfluxDB是一個NoSQL數(shù)據(jù)庫,其創(chuàng)建者選擇從頭開始重建所有內(nèi)容。相比之下,TimescaleDB是一個SQL數(shù)據(jù)庫,其創(chuàng)建者(即本文作者)選擇擁抱并構(gòu)建在PostgreSQL和已驗證的數(shù)據(jù)結(jié)構(gòu)之上,然后進(jìn)一步擴展它以用于時間序列、事件和實時分析問題。(順便說一句,使用正確的擴展,它還可以推動您的AI應(yīng)用程序開發(fā)。)
首先,以下是這兩個數(shù)據(jù)庫在數(shù)據(jù)集基數(shù)增加時插入性能的比較。
對于以下比較,我們使用了以下設(shè)置:
- TimescaleDB版本1.2.2,InfluxDB版本1.7.6
- 1臺遠(yuǎn)程客戶端機器和1臺數(shù)據(jù)庫服務(wù)器,兩者都在同一個云數(shù)據(jù)中心
- AWS EC2實例:i3.xlarge(4個vCPU,30 GB內(nèi)存)
- 4個1 TB磁盤,采用raid0配置(EXT4文件系統(tǒng))
- 兩個數(shù)據(jù)庫都獲得了所有可用內(nèi)存
- 數(shù)據(jù)集:100-1,000,000個模擬設(shè)備每10秒生成1-10個CPU指標(biāo),約1億個讀取間隔,約10億個指標(biāo)(100個設(shè)備一個月間隔;4000個設(shè)備三天;100,000個設(shè)備三個小時;1,000,000個設(shè)備三分鐘),使用時間序列基準(zhǔn)套件 (TSBS) 生成- 用于TimescaleDB (1)和InfluxDB (2)的模式
- 插入時兩個數(shù)據(jù)庫都使用了10K批大小
- 對于TimescaleDB,我們根據(jù)數(shù)據(jù)量設(shè)置塊大小,目標(biāo)是10-15個塊(更多信息)
- 對于InfluxDB,我們啟用了TSI(時間序列索引)
(1)TimescaleDB schema:Tablecpu(time timestamp, tags_id integer, usage_user double, usage_system double, usage_idle double, usage_nice double, usage_iowait double, usage_irq double, usage_softirq double, usage_steal double, usage_guest double, usage_guest_nice double, additional_tags jsonb); indexes (tags_id, time) and (time, tags_id); Tabletags(id integer, hostname text, region text, datacenter text, rack text, os text, arch text, team text, service text, service_version text, service_environment text); unique index on all columns
(2)InfluxDB schema:Field keys (usage_guest integer, usage_guest_nice integer, usage_idle integer, usage_iowait integer, usage_irq integer, usage_nice integer, usage_softirq integer, usage_steal integer, usage_system integer, usage_user integer), Tag keys (arch, datacenter, hostname, os, rack, region, service, service_environment, service_version, team)
圖片
注意:這里可以找到這兩個數(shù)據(jù)庫更詳細(xì)的總體比較。
正如你所看到的,在低基數(shù)情況下,兩個數(shù)據(jù)庫是可比的(盡管 TimescaleDB 的性能高出 30%)。但隨著基數(shù)的增加,差異變得相當(dāng)顯著,因為 TimescaleDB 的插入性能下降速度遠(yuǎn)遠(yuǎn)慢于 InfluxDB,而 InfluxDB 的性能則急劇下降。在高基數(shù)情況下,TimescaleDB 的性能比 InfluxDB 高出 11 倍以上。
這些結(jié)果對一些人來說可能并不令人驚訝,因為高基數(shù)是 InfluxDB 的一個眾所周知的弱點(來源:GitHub、論壇)。
但為什么會這樣呢?讓我們更仔細(xì)地看看這兩種數(shù)據(jù)庫的開發(fā)情況。
B-Trees 與TSI:處理高基數(shù)的兩種不同方法
我們可以將高基數(shù)性能的差異追溯到InfluxDB與TimescaleDB在工程決策上的根本不同。
InfluxDB 和 TSI
由于高基數(shù)一直是InfluxDB的一個眾所周知的挑戰(zhàn),他們的團(tuán)隊一直在研究一種稱為“時間序列索引”(TSI)的東西來解決這個問題。
與他們在其他領(lǐng)域的做法一致,InfluxDB TSI 是一個基于本地日志結(jié)構(gòu)合并樹的系統(tǒng),由各種數(shù)據(jù)結(jié)構(gòu)組成,包括哈希映射和位集。這包括一個內(nèi)存中的日志(“LogFile”),當(dāng)其超過閾值(5 MB)時會定期刷新到磁盤,并且被壓縮到一個磁盤上的內(nèi)存映射索引(“IndexFile”);一個文件(“SeriesFile”),包含了整個數(shù)據(jù)庫中所有序列鍵的集合。(在他們的文檔中有描述。)
TSI 的性能取決于所有這些數(shù)據(jù)結(jié)構(gòu)的相互作用。然而,由于 TSI 是定制構(gòu)建的,理解其在各種高基數(shù)工作負(fù)載下的表現(xiàn)變得難以理解。
TSI 的設(shè)計決策也導(dǎo)致了一些具有性能影響的限制:
- 根據(jù)InfluxDB的文檔,該總基數(shù)限制大約為3,000萬(盡管根據(jù)上面的圖表,InfluxDB在達(dá)到該限制之前就已經(jīng)開始表現(xiàn)不佳),或者遠(yuǎn)低于物聯(lián)網(wǎng)(包括我們上面的示例)等時間序列用例中通常所需的數(shù)量。
- InfluxDB索引標(biāo)簽但不索引字段,這意味著某些查詢無法比全表掃描表現(xiàn)得更好。因此,以我們之前提到的物聯(lián)網(wǎng)數(shù)據(jù)集為例,如果想要搜索所有沒有空閑內(nèi)存的行(例如,類似于SELECT * FROM sensor_data WHERE mem_free = 0的查詢),就無法比全表線性掃描(即O(n)時間)做得更好來識別相關(guān)數(shù)據(jù)點。
- 索引中包含的列集是完全固定且不可變的。更改數(shù)據(jù)中哪些列被索引(標(biāo)記)以及哪些沒有,需要完全重寫數(shù)據(jù)。
- 由于依賴哈希映射,InfluxDB 只能索引離散值而不能索引連續(xù)值。例如,要搜索所有溫度高于 90 度的行(例如,類似于 SELECT * FROM sensor_data WHERE temperature > 90 的查詢),則需要再次完全掃描整個數(shù)據(jù)集。
- InfluxDB 的基數(shù)受到所有時間范圍內(nèi)基數(shù)的影響,即使某些字段/值不再存在于數(shù)據(jù)集中也是如此。這是因為 SeriesFile 存儲了整個數(shù)據(jù)集的所有系列鍵。
TimescaleDB 和 B-trees
相比之下,TimescaleDB是一個關(guān)系型數(shù)據(jù)庫,它依賴于久經(jīng)考驗的用于索引數(shù)據(jù)的結(jié)構(gòu):B-tree。這一決定使其能夠擴展到高基數(shù)。
首先,TimescaleDB按時間對您的數(shù)據(jù)進(jìn)行分區(qū),一個B-tree將時間段映射到相應(yīng)的分區(qū)(“chunk”)。所有這些分區(qū)都在后臺進(jìn)行,對用戶隱藏,用戶能夠訪問一個虛擬表(“hypertable”),該表跨越所有分區(qū)中的所有數(shù)據(jù)。
接下來,TimescaleDB允許在您的數(shù)據(jù)集上創(chuàng)建多個索引(例如,對于equipment_id、sensor_id、firmware_version、site_id)。默認(rèn)情況下,這些索引以B-tree的形式在每個chunk上創(chuàng)建。
也可以使用任何內(nèi)置的PostgreSQL索引類型創(chuàng)建索引:Hash、GiST、SP-GiST、GIN和BRIN。您可以閱讀這篇文章以了解有關(guān)索引的更多信息以及如何使用它們來優(yōu)化PostgreSQL數(shù)據(jù)庫性能。
這種方法對高基數(shù)數(shù)據(jù)集有一些好處:
- 更簡單的方法可以更清晰地了解數(shù)據(jù)庫的性能。只要我們要查詢的數(shù)據(jù)集的索引和數(shù)據(jù)適合內(nèi)存(這是可以調(diào)整的),基數(shù)就成為一個非問題。
- 此外,由于輔助索引的范圍在chunk級別,因此索引本身的大小僅與該時間范圍的數(shù)據(jù)集的基數(shù)一樣大。
- 您可以控制要索引的列,包括能夠在多列上創(chuàng)建復(fù)合索引。您也可以隨時添加或刪除索引,例如,如果您的查詢工作負(fù)載發(fā)生變化。與InfluxDB不同,在TimescaleDB中更改索引結(jié)構(gòu)不需要重寫數(shù)據(jù)的整個歷史記錄。
- 您可以對離散字段和連續(xù)字段創(chuàng)建索引,特別是由于B-tree非常適合使用以下任何運算符進(jìn)行比較:<、<=、=、>=、>、BETWEEN、IN、IS NULL、IS NOT NULL。我們上面示例查詢(SELECT * FROM sensor_data WHERE mem_free = 0和SELECT * FROM sensor_data WHERE temperature > 90)將在對數(shù)時間或O(log n)時間內(nèi)運行。
- 其他受支持的索引類型在其他場景中可能派上用場,例如,用于“最近鄰”搜索的GIST索引。
結(jié)論
現(xiàn)代數(shù)據(jù)庫系統(tǒng)中高基數(shù)數(shù)據(jù)帶來的挑戰(zhàn)需要復(fù)雜的索引解決方案來克服連接操作和全表掃描的固有障礙。InfluxDB和Timescale都具有獨特的策略來有效地管理高基數(shù)數(shù)據(jù)。
Timescale的方法利用了B-tree數(shù)據(jù)結(jié)構(gòu)的強大功能,為處理高基數(shù)數(shù)據(jù)集提供了強大的基礎(chǔ)。這種結(jié)構(gòu)不僅能夠?qū)崿F(xiàn)卓越的查詢性能,而且還提供了滿足各種索引需求所需的靈活性。B-tree架構(gòu)允許高效的范圍查詢和點查找,使其特別適合時間序列應(yīng)用程序,在這些應(yīng)用程序中,歷史分析和實時數(shù)據(jù)訪問都至關(guān)重要。