開源時序數據庫解析:時間序列數據的存儲和計算

HBase NoSQL ElasticSearch PowerPoint 雲棲社區 2017-06-23

KairosDB

KairosDB最初是從OpenTSDB 1.x版本fork出來的一個分支,目的是在OpenTSDB的代碼基礎上進行二次開發來滿足新的功能需求。其改造之一就是支持可插拔式的存儲引擎,例如支持H2可以方便本地開發和測試,而不是像OpenTSDB一樣與HBase強耦合。在其最初的幾個版本中,HBase也是作為其主要的存儲引擎。但是在之後的存儲優化中,慢慢使用Cassandra替換了HBase,它也是第一個基於Cassandra開發的時序數據庫。在最新的幾個版本中,已不再支持HBase,因為其存儲優化使用了Cassandra所特有而HBase沒有的一些特性。

在整體架構上,和OpenTSDB比較類似,都是採用了一個比較成熟的數據庫來作為底層存儲引擎。自己的主要邏輯僅僅是在存儲引擎層之上很薄的一個邏輯層,這層邏輯層的部署架構是一個無狀態的組件,可以很容易的水平擴展。

在功能差異性上,它在OpenTSDB 1.x上做二次開發,也是為了對OpenTSDB的一些功能做優化,或做出一些OpenTSDB所沒有的功能。我大概羅列下我看到的主要的功能差異:

1. 可插拔式的存儲引擎:OpenTSDB在早期與HBase強耦合,為了追求極致的性能,甚至自研了一個異步的HBase Client(現在作為獨立的一個開源項目輸出:AsyncHBase)。這樣也導致其整個代碼都是採用異步驅動的模式編寫,不光增加了代碼的複雜度和降低可閱讀性,也加大了支持多種存儲引擎的難度。KairosDB嚴格定義了存儲層的API Interface,整體邏輯與存儲層耦合度較低,能比較容易的擴展多種存儲引擎。當然現在最新版的OpenTSDB也能夠額外支持Cassandra和BigTable,但是從整體的架構上,還不能說是一個支持可插拔式存儲引擎的架構。

2. 支持多種數據類型及自定義類型的值:OpenTSDB只支持numeric的值,而KairosDB支持numeric、string類型的值,也支持自定義數值類型。在某些場景下,metric value不是一個簡單的數值,例如你要統計這個時間點的TopN,對應的metric value可能是一組string值。可擴展的類型,讓未來的需求擴展會變得容易。從第一第二點差異可以看出,KairosDB基於OpenTSDB的第一大改造就是將OpenTSDB的功能模型和代碼架構變得更加靈活。

3. 支持Auto-rollup:目前大部分TSDB都在朝著支持pre-aggregation和auto-rollup的方向發展,OpenTSDB是少數的不支持該feature的TSDB,在最新發布的OpenTSDB版本中,甚至都不支持多精度數據的存儲。不過現在KairosDB支持的auto-rollup功能,採取的還是一個比較原始的實現方式,在下面的章節會詳細講解。

4. 不同的存儲模型:存儲是TSDB核心中的核心,OpenTSDB在存儲模型上使用了UID的壓縮優化,來優化查詢和存儲。KairosDB採取了一個不同的思路,利用了Cassandra寬表的特性,這也是它從HBase轉向Cassandra的一個最重要的原因,在下面的章節會詳細講解。

存儲模型

OpenTSDB的存儲模型細節,可以參考這篇文章。其主要設計特點是採用了UID編碼,大大節省了存儲空間,並且利用UID編碼的固定字節數的特性,利用HBase的Filter做了很多查詢的優化。但是採用UID編碼後也帶來了很多的缺陷,一是需要維護metric/tagKey/tagValue到UID的映射表,所有data point的寫入和讀取都需要經過映射表的轉換,映射表通常會緩存在TSD或者client,增加了額外的內存消耗;二是由於採用了UID編碼,導致metric/tagKey/tagValue的基數是有上限的,取決於UID使用的字節數,並且在UID的分配上會有衝突,會影響寫入。

本質上,OpenTSDB存儲模型採用的UID編碼優化,主要解決的就兩個問題:

1. 存儲空間優化:UID編碼解決重複的row key存儲造成的冗餘的存儲空間問題。

2. 查詢優化:利用UID編碼後TagKey和TagValue固定字節長度的特性,利用HBase的FuzzyRowFilter做特定場景的查詢優化。

KairosDB在解決這兩個問題上,採取了另外一種不同的方式,使其不需要使用UID編碼,也不存在使用UID編碼後遺留的問題。先看下KairosDB的存儲模型是怎樣的,它主要由以下三張表構成:

1. DataPoints: 存儲所有原始數據點,每個數據點也是由metric、tags、timestamp和value構成。該表中一行數據的時間跨度是三週,也就是說三週內的所有數據點都存儲在同一行,而OpenTSDB內的行的時間跨度只有一個小時。RowKey的組成與OpenTSDB類似,結構為<metric><timestamp><tagk1><tagv1><tagk2>tagv2>...<tagkn><tagvn>,不同的是metric, tag key和tag value都存儲原始值,而不是UID。

2. RowKeyIndex: 該表存儲所有metric對應DataPoints表內所有row key的映射,也就是說同一個metric上寫入的所有的row key,都會存儲在同一行內,並且按時間排序。該表主要被用於查詢,在根據tag key或者tag value做過濾時,會先從這張表過濾出要查詢的時間段內所有符合條件的row key,後在DataPoints表內查詢數據。

3. StringIndex: 該表就三行數據,每一行分別存儲所有的metric、tag key和tag value。

KairosDB採取的存儲模型,是利用了Cassandra寬表的特性。HBase的底層文件存儲格式中,每一列會對應一個KeyValue,Key為該行的RowKey,所以HBase中一行中的每一列,都會重複的存儲相同的RowKey,這也是為何採用了UID編碼後能大大節省存儲空間的主要原因,也是為何有了UID編碼後還能採用compaction策略(將一行中所有列合併為一列)來進一步壓縮存儲空間的原因。而Cassandra的底層文件存儲格式與HBase不同,它一行數據不會為每一列都重複的存儲RowKey,所以它不需要使用UID編碼。Cassandra內降低存儲空間的一個優化方案就是縮減行數,這也是為何它一行存儲三週數據而不是一個小時數據的原因。要進一步瞭解兩種設計方案的原因,可以看下HBase文件格式以及Cassandra文件格式。

利用Cassandra的寬表特性,即使不採用UID編碼,存儲空間上相比採用UID編碼的OpenTSDB,也不會差太多。可以看下官方的解釋:

For one we do not use id’s for strings. The string data (metric names and tags) are written to row keys and the appropriate indexes. Because Cassandra has much wider rows there are far fewer keys written to the database. The space saved by using id’s is minor and by not using id’s we avoid having to use any kind of locks across the cluster.As mentioned the Cassandra has wider rows. The default row size in OpenTSDB HBase is 1 hour. Cassandra is set to 3 weeks.

在查詢優化上,採取的也是和OpenTSDB不一樣的優化方式。先看下KairosDB內查詢的整個流程:

1. 根據查詢條件,找出所有DataPoints表裡的row key

  • 如果有自定義的plugin,則從plugin中獲取要查詢的所有row key。(通過Plugin可以擴展使用外部索引系統來對row key進行索引,例如使用ElasticSearch)

  • 如果沒有自定義的plugin,則在RowKeyIndex表裡根據metric和時間範圍,找出所有的row key。(根據列名的範圍來縮小查詢範圍,列名的範圍是(metric+startTime, metric+endTime))

  1. 根據row key,從DataPoints表裡找出所有的數據

相比OpenTSDB直接在數據表上進行掃描來過濾row key的方式,KairosDB利用索引表無疑會大大減少掃描的數據量。在metric下tagKey和tagValue組合有限的情況下,會大大的提高查詢效率。並且KairosDB還提供了QueryPlugin的方式,能夠擴展利用外部組件來對row key進行索引,例如可以利用ElasticSearch,或者其他的索引系統,畢竟通過索引的方式,才是最優的查詢方案,這也是Heroic相比KairosDB最大的一個改進的地方。

Auto-rollup

KairosDB的官方文檔中有關於auto-rollup如何配置的章節,但是在討論組內,其關於auto-rollup的說明如下:

First off Kairos does not do any aggregation on ingest. Ingest is direct to the storage on purpose - performance.

總結來說,目前KairosDB提供的auto-rollup方案,還是比較簡單的實現。就是一個可配置的單機組件,能夠定時啟動,把已經寫入的數據讀出後進行aggregation後再次寫入,確實非常的原始,可用性和性能都比較低。

但是有總比沒有好,支持auto-rollup一定是所有TSDB的趨勢,也是能拉開功能差異和提高核心競爭力的關鍵功能。

BlueFlood

上面主要分析了KairosDB,第一個基於Cassandra構建的TSDB,那乾脆繼續分析下其他基於Cassandra構建的TSDB。

BlueFlood也是一個基於Cassandra構建的TSDB,從這個PPT介紹上可以看到整體架構上核心組成部分主要有三個:

  • Ingest module: 處理數據寫入。

  • Rollup module: 做自動的預聚合和降精度。

  • Query module: 處理數據查詢。

相比KairosDB,其在數據模型上與其他的TSDB有略微差異,主要在:

  • 引入了租戶的維度:這是一個創新,如果你是做一個服務化的TSDB,那租戶這個維度是必需的。

  • 不支持Tag:這一點上,是比較讓我差異的地方。在大多數TSDB都基本上把Tag作為模型的不可缺少部分的情況下,BlueFlood在模型上居然不支持Tag。不過這有可能是其沒有想好如何優化Tag維度查詢的一種取捨,既然沒想好怎麼優化,那乾脆就先不支持,反正未來再去擴展Tag是可以完全兼容的。BlueFlood當前已經利用ElasticSearch去構建metric的索引,我相信它未來的方案,應該也是基於ElasticSearch去構建Tag的索引,在這個方案完全支持好後,應該才會去引入Tag。

模型上的不足,BlueFlood不需要去考慮Tag查詢如何優化,把精力都投入到了其他功能的優化上,例如auto-rollup。它在auto-rollup的功能支持上,甩了KairosDB和OpenTSDB幾條街。來看看它的Auto-rollup功能的特點:

  • 僅支持固定的Interval:5min,20min,60min,4hour,1day。

  • 提供分佈式的Rollup Service:rollup任務可以分佈式的調度,rollup的數據是通過離線的批量掃描獲取。

從它14年的介紹PPT上,還可以看到它在未來規劃的幾個功能點:

  • ElasticSearch Indexer and discovery: 目前這個已經實現,但是僅支持metric的索引,未來引入Tag後,可能也會用於Tag的索引。

  • Cloud files exporter for rollups: 這種方式對離線計算更加優化,rollup的大批量歷史數據讀取就不會影響在線的業務。

  • Apache Kafka exporter for rollups: 這種方式相比離線計算更進一步,rollup可以用流計算來做,實時性更加高。

總結來說,如果你不需要Tag的支持,並且對Rollup有強需求,那BlueFlood相比KairosDB會是一個更好的選擇,反之還是選擇KairosDB。

Heroic

第三個要分析的基於Cassandra的TSDB是Heroic,它在DB-Engines上的排名是第19,雖然比BlueFlood和KairosDB都落後,但是我認為它的設計實現卻是最好的一個。關於它的起源,可以看下這篇文章或者這個PPT,都是寶貴的經驗教訓。

Spotify在決定研發Heroic之前,在OpenTSDB、InfluxDB、KairosDB等TSDB中選用KairosDB來替換他們老的監控系統的底層。但是很快就遇到了KairosDB在查詢方面的問題,最主要還是KairosDB對metric和tag沒有索引,在metric和tag基數達到一定數量級後,查詢會變的很慢。所以Spotify研發Heroic的最大動機就是解決KairosDB的查詢問題,採用的解決方案是使用ElasticSearch來作為索引優化查詢引擎,而數據的寫入和數據表的Schema則完全與KairosDB一致。

簡單總結下它的特點:

1. 完整的數據模型,完全遵循metric2.0的規範。

2. 數據存儲模型與KairosDB一致,使用ElasticSearch優化查詢引擎。(這是除了InfluxDB外,其他TSDB如KairosDB、OpenTSDB、BlueFlood等現存最大的問題,是其核心競爭力之一)

3. 不支持auto-rollup,這是它的缺陷之一。

如果你需要TSDB支持完整的數據模型,且希望得到高效的索引查詢,那Heroic會是你的選擇。

原文來自:https://yq.aliyun.com/articles/106382

相關推薦

推薦中...