天天看點

SparkES 多元分析引擎設計

elasticsearch 毫秒級的查詢響應時間還是很驚豔的。其優點有:

優秀的全文檢索能力

高效的列式存儲與查詢能力

資料分布式存儲(shard 分片)

其列式存儲可以有效的支援高效的聚合類查詢,譬如groupby等操作,分布式存儲則提升了處理的資料規模。

相應的也存在一些缺點:

缺乏優秀的sql支援

缺乏水準擴充的reduce(merge)能力,現階段的實作局限在單機

json格式的查詢語言,缺乏程式設計能力,難以實作非常複雜的資料加工,自定義函數(類似hive的udf等)

spark 作為一個計算引擎,可以克服es存在的這些缺點:

良好的sql支援

強大的計算引擎,可以進行分布式reduce

支援自定義程式設計(采用原生api或者編寫udf等函數對sql做增強)

是以在建構即席多元查詢系統時,spark 可以和es取得良好的互補效果。通過es的列式存儲特性,我們可以非常快的過濾出資料,并且支援全文檢索,之後這些過濾後的資料從各個shard 進入spark,spark分布式的進行reduce/merge操作,并且做一些更高層的工作,最後輸出給使用者。

通常而言,結構化的資料結構可以有效提升資料的查詢速度,但是會對資料的建構産生一定的吞吐影響。es強大的query能力取決于資料結構化的存儲(索引檔案),為了解決這個問題,我們可以通過spark streaming有效的對接各個資料源(kafka/檔案系統)等,将資料規範化後批量導入到es的各個shard。spark streaming 基于以下兩點可以實作為es快速導入資料。

spark rdd 的partition 能夠良好的契合es的shard的概念。能夠實作一一對應。避免經過es的二次分發

spark streaming 批處理的模式 和 lucene(es的底層存儲引擎)的segment對應的非常好。一次批處理意味着新生成一個檔案,我們可以有效的控制生成檔案的大小,頻度等。

下面是架構設計圖:

SparkES 多元分析引擎設計

spark-es-4.png

整個系統大概分成四個部分。分别是:

api層

spark 計算引擎層

es 存儲層

es 索引建構層

api 層主要是做多查詢協定的支援,比如可以支援sql,json等形态的查詢語句。并且可是做一些啟發式查詢優化。進而決定将查詢請求是直接轉發給後端的es來完成,還是走spark 計算引擎。也就是上圖提到的 query optimize,根據條件決定是否需要短路掉 spark compute。

前面我們提到了es的三個缺陷,而spark 可以有效的解決這個問題。對于一個普通的sql語句,我們可以把 where 條件的語句,部分group 等相關的語句下沉到es引擎進行執行,之後可能彙總了較多的資料,然後放到spark中進行合并和加工,最後轉發給使用者。相對應的,spark 的初始的rdd 類似和kafka的對接,每個kafka 的partition對應rdd的一個partiton,每個es的shard 也對應rdd的一個partition。

es的shard 數量在索引建構時就需要确定,确定後無法進行更改。這樣單個索引裡的shard 會越來越大進而影響單shard的查詢速度。但因為上層有了 spark compute層,是以我們可以通過添加index的方式來擴大shard的數目,然後查詢時查詢所有分片資料,由spark完成資料的合并工作。

資料的結構化必然帶來了建構的困難。是以有了spark streaming層作為資料的建構層。這裡你有兩種選擇:

通過es原生的bulk api 完成索引的建構

然spark 直接對接到 es的每個shard,直接針對該shard 進行索引,可有效替身索引的吞吐量。

繼續閱讀