天天看點

【玩轉ElasticSearch】降維打擊!使用ElasticSearch作為時序資料庫

本篇分享最近把elasticsearch當作時序資料庫來用的心得。

• 需求

需求是這樣的:提供一個背景,選使用者畫像标簽(多選),點确認後彈出“選出了xxx個使用者”,再繼續點就把使用者dump出來、推送消息。現在要做這個背景的資料倉庫層。

詳細分析一下需求:

1. 我們的使用者畫像走流式計算,每秒大量更新,是以對插入/更新性能要求很高。

2. 查詢條件翻譯成sql就是類似 select count(*) from `table` where (`tags` like '%tag1%') and (`tags` like '%tag2%') and (`tags` like '%tag3%') and ...,正常資料庫算起來比較慢。

需要一個資料倉庫,支援大量插入/更新、大量導出、快速多字元串比對查詢。

【玩轉ElasticSearch】降維打擊!使用ElasticSearch作為時序資料庫

很不幸的是,單機版influxdb在壓測環節爆了,頂不住插入/更新的量。而分布式influxdb又閉源了。接下來嘗試了一下elasticsearch,于是就有了這篇文章了。

• es能幹這個事麼?

還真能。

1. 插入/更新性能高

es通過bulk接口,可以做到批處理,擁有相當高的插入/更新性能。

2. 查詢效率高

3. 導出效率高

用es的scroll接口可以做到這麼一件事:1)進行一個查詢,指定翻頁大小、本次查詢的索引儲存時間,擷取一個scroll_id;2)通過scroll_id不斷地翻頁。可以實作大批量導出一個查詢的所有資料,不需要重複計算。

4. 高可用與橫向擴充能力

就不贅述了。

• 實作與優化

1. 用了3個node組成的叢集,全ssd。3個剛好是滿足高可用的最小master node數量。每個node的記憶體開到31g。

2. es前面頂一層logstash,logstash開一個http-input和elasticsearch-output,用http keep-alive來接流量。關鍵配置有:

1)input.http.threads預設是4,要開大;

2)output.elasticsearch.action => "update",output.elasticsearch.doc_as_upsert => true,這樣可實作upsert操作;

3)pipeline.workers跟pipeline.output.workers開到跟核數一緻;

4)pipeline.batch.size跟output.elasticsearch.flush_size适度開大。

3. 整個流程是資料怼logstash、logstash怼es,是以會有es的資料延後幾秒才更新的情況,這樣可能會引起一些問題,需要務必留意。

4. es5.0取消了ttl,是以資料的過期要另外處理。

5. es的scroll查詢中,通過配置_source來提取部分字段,可以大幅降低網絡i/o。

• 一些驚喜

我們往es裡存的标簽是沒去重的原始資料,就是說一個使用者的标簽可能長這樣:

a b a a a c d a

而es本質上是個搜尋引擎,使用預設的bm25算法搜尋使用者,排在前面的就自然是重度使用者。

非常不錯。

• 總結

elasticsearch除了用來幹搜尋、運維監控之外,還能用來當時序資料庫。在這個case裡,算是對influxdb等時序資料庫産品做降維打擊了,真乃居家旅行、殺人越貨的神器。