時間序列數據庫——索引用ES、聚合分析時加載數據用什麼?docvalues的列存儲貌似更優優點一些。那分佈式計算呢?ES作

分佈式計算

分佈式聚合如何作得快

Elasticsearch/Lucene從最底層就支持數據分片,查詢的時候能夠自動把不一樣分片的查詢結果合併起來。Elasticsearch的document都有一個uid,默認策略是按照uid 的 hash把文檔進行分片。算法

一個Elasticsearch Index至關於一個MySQL裏的表,不一樣Index的數據是物理上隔離開來的。Elasticsearch的Index會分紅多個Shard存儲,一 部分Shard是Replica備份。一個Shard是一份本地的存儲(一個本地磁盤上的目錄),也就是一個Lucene的Index。不一樣的Shard 可能會被分配到不一樣的主機節點上。一個Lucene Index會存儲不少的doc,爲了好管理,Lucene把Index再拆成了Segment存儲(子目錄)。Segment內的doc數量上限是1的 31次方,這樣doc id就只須要一個int就能夠存儲。Segment對應了一些列文件存儲索引(倒排表等)和主存儲(DocValues等),這些文件內部又分爲小的 Block進行壓縮。數據庫

時間序列數據通常按照日期分紅多個Elasticsearch Index來存儲,好比logstash-2014.08.02。查詢的時候能夠指定多個Elasticsearch Index做爲查找的範圍,也能夠用logstash-*作模糊匹配。網絡

美妙之處在於,雖然數據被拆得七零八落的,在查詢聚合的時候甚至須要分爲兩個階段完成。可是對於最終用戶來講,使用起來就好像是一個數據庫表同樣。全部的合併查詢的細節都是隱藏起來的。架構

對於聚合查詢,其處理是分兩階段完成的:數據庫設計

  • Shard本地的Lucene Index並行計算出局部的聚合結果;
  • 收到全部的Shard的局部聚合結果,聚合出最終的聚合結果。

這種兩階段聚合的架構使得每一個shard不用把原數據返回,而只用返回數據量小得多的聚合結果。相比Opentsdb這樣的數據庫設計更合理。 Opentsdb其聚合只在最終節點處完成,全部的分片數據要匯聚到一個地方進行計算,這樣帶來大量的網絡帶寬消耗。因此Influxdb等更新的時間序列數據庫選擇把分佈式計算模塊和存儲引擎進行同機部署,以減小網絡帶寬的影響。elasticsearch

除此以外Elasticsearch還有另一個減小聚合過程當中網絡傳輸量的優化,那就是Hyperloglog算 法。在計算unique visitor(uv)這樣的場景下,常常須要按用戶id去重以後統計人數。最簡單的實現是用一個hashset保存這些用戶id。可是用set保存全部 的用戶id作去重須要消耗大量的內存,同時分佈式聚合的時候也要消耗大量的網絡帶寬。Hyperloglog算法以必定的偏差作爲代價,能夠用很小的數據 量保存這個set,從而減小網絡傳輸消耗。分佈式

爲何時間序列須要更復雜的聚合?

關係型數據庫支持一些很複雜的聚合查詢邏輯,好比:大數據

  • Join兩張表;
  • Group by以後用Having再對聚合結果進行過濾;
  • 用子查詢對聚合結果進行二次聚合。

在使用時間序列數據庫的時候,咱們常常會懷念這些SQL的查詢能力。在時間序列裏有一個特別常見的需求就是降頻和降維。舉例以下:優化

12:05:05 湖南 81
12:05:07 江西 30
12:05:11 湖南 80
12:05:12 江西 32
12:05:16 湖南 80
12:05:16 江西 30

按1分鐘頻率進行max的降頻操做得出的結果是:ui

12:05 湖南 81
12:05 江西 32

這種按max進行降頻的最多見的場景是採樣點的歸一化。不一樣的採集器採樣的時間點是不一樣的,爲了不漏點也會加大采樣率。這樣就可能致使一分鐘內採樣屢次,並且採樣點的時間都不對齊。在查詢的時候按max進行降頻能夠得出一個統一時間點的數據。

按sum進行降維的結果是:

12:05 113

常常咱們須要捨棄掉某些維度進行一個加和的統計。這個統計須要在時間點對齊以後再進行計算。這就致使一個查詢須要作兩次,上面的例子裏:

  • 先按1分鐘,用max作降頻;
  • 再去掉省份維度,用sum作降維。

若是僅僅能作一次聚合,要麼用sum作聚合,要麼用max作聚合。沒法知足業務邏輯的需求。爲了不在一個查詢裏作兩次聚合,大部分的時間序列數據庫都要求數據在入庫的時候已是整點整分的。這就要求數據不能直接從採集點直接入庫,而要通過一個實時計算管道進行處理。若是可以在查詢的時候同時完成降頻和降維,那就能夠帶來一些使用上的便利。

這個功能看似簡單,其實很是難以實現。不少所謂的支持大數據的數據庫都只支持簡單的一次聚合操做。Elasticsearch 將要發佈的 2.0 版本的最重量級的新特性是Pipeline Aggregation,它支持數據在聚合以後再作聚合。相似SQL的子查詢和Having等功能都將被支持。

總結

時間序列隨着Internet of Things等潮流的興起正變得愈來愈常見。但願本文能夠幫助你瞭解到那些號稱本身很是海量,查詢很是快的時間序列數據庫背後的祕密。沒有完美的數據 庫,Elasticsearch也不例外。若是你的用例根本不包括聚合的需求,也許Opentsdb甚至MySQL就是你最好的選擇。可是若是你須要聚合海量的時間序列數據,必定要嘗試一下Elasticsearch!

相關文章
相關標籤/搜索