請警戒 ES 的三大坑

這是悟空的第 104 篇原創文章
html

做者 | 悟空聊架構前端

來源 | 悟空聊架構(ID:PassJava666)java

轉載請聯繫受權(微信ID:PassJava)

ES 搜索引擎系列文章彙總:node

1、別隻會搜日誌了,求你懂點原理吧mysql

2、ES 終於能夠搜到」悟空哥「了!
web

3、1W字|40 圖|硬核 ES 實戰算法

本文主要內容以下:sql

搜索引擎如今是用得愈來愈多了,好比咱們日誌系統中用到的 ELK 就用到了搜索引擎 Elasticsearch(簡稱 ES)。數據庫

那對於搜索這種技術來講,最看重的是搜索的結果的準確性和搜索的響應時間。ES 的準確性能夠經過 倒排索引算法來保證,那響應時間就須要磁盤或緩存來支持了,那麼磁盤和緩存會帶來哪些坑呢?( 其實不管是分佈式的,仍是單機模式下的搜索引擎都會遇到這個問題。)小程序

1、ES 慢查詢之坑

Elasticsearch 是現現在用的最普遍的搜索引擎。它是一個分佈式的開源搜索和分析引擎,適用於全部類型的數據,包括文本、數字、地理空間、結構化和非結構化數據。

1.1 工做原理:

ES 的工做原理:往 ES 裏寫數據時,實際是寫到磁盤文件,查詢時,操做系統會將磁盤文件裏的數據自動緩存 filesystem cache 裏面。若是給 filesystem cache 更多的內存,儘可能讓內存能夠容納全部的 idx segment file 索引數據文件,則搜索的時候走內存,性能較好。

ES 工做原理

坑: 首先若是訪問磁盤那必定很慢,而走緩存會快不少。但若是不少沒用的字段數據都丟到緩存裏面,則會浪費緩存的空間,因此不少數據仍是存在磁盤裏面的,那麼大部分查詢走的數據庫,則會帶來性能問題。

1.2 案例

ES 節點 3 臺機器,每臺機器 32 G 內存,總內存 96 G,給 ES JVM 堆內存是 16 G,那麼剩下來給 cache 的是 16 G,總共 ES 集羣的的 cache 佔用內存 48 G ,若是全部的數據佔據磁盤空間 600 G,那麼每臺機器的數據量是 200 G,而查詢時,有 150 G 左右的的數據是走磁盤查詢的,那麼走 cache 的機率是 48 G/ 600 G = 8%,也就是說大量查詢是走磁盤的。

1.3 避坑指南:

1.3.1 存儲關鍵信息

搜索引擎避坑指南
  • 將數據中索引字段存到 cache,好比 一行數據有 name、gender、age、city、job 字段,而檢索這條數據只須要 name 和 gender 就能夠查詢出數據,那麼 cache 就只須要存 id、name 和 gender 字段。別把全部字段都丟到 cache 裏面,純屬浪費空間,資源是有限的。

  • 那剩下的字段怎麼檢索出來?能夠把其餘字段存到 mysql/hbase 裏面。

  • hbase 特色:適用於海量數據的在線存儲。缺點是不能進行復雜的搜索。根據 name 和 gender 字段從 ES 中拿到 100 條數據 ( 包含 doc id ) ,而後根據 doc id 再去 hbase 中查詢每一個 doc id 對應的完整數據,將結果組裝後返回給前端 ( 須要考慮分頁的狀況 ) 。

1.3.2 數據預熱

  • 將訪問量高的數據或者即將訪問量高的數據放到 filesystem cache 裏面。
  • 每隔一段時間就從數據庫訪問下數據,而後同步到 filesystem cache 裏面。

1.3.3 冷熱分離

  • 不常訪問的數據和常常訪問的數據進行隔離。好比 3 臺機器存放冷數據的索引,另外 3 臺存放熱數據的索引。

1.3.4 避免使用關聯查詢

  • ES 中的關聯查詢是比較慢的,性能不佳,儘可能避免使用。

2、ES 架構之坑

一般狀況下,咱們會使用 ES 的集羣模式,在集羣規模不大的狀況下,性能還算能夠,但若是集羣規模變得很大,則會遇到集羣瓶頸,也就是說集羣擴大,性能提高甚微,甚至不增反降。

ES 的集羣也是採用中心化的分佈式架構,整個集羣只有一個是 Master 節點。而它的職責很是重要:負責整個集羣的元數據管理,元數據包含全局的配置信息、索引信息、節點信息,若是元數據發生改變,則須要 master 節點將變動信息發佈到集羣的其餘節點。

另外由於 master 節點的任務處理是單線程的,因此每次處理任務時,須要等待所有節點接收到變動信息,並處理完變動的任務後,纔算完成了變動任務。

那麼這樣的架構會帶來什麼問題:

  • 響應時間問題。若是元數據發生了改變,但某節點 假死,好比 JVM 的內存爆了,可是進程還活着,那麼響應 master 節點的時間會很是長,進而影響單個同步信息任務的完成時間。
  • 任務恢復問題。有大量恢復任務的時候,任務須要排隊,恢復時間變長。
  • 任務回調問題。任務執行完成後,須要回調大量 listener 處理元數據變動。若是分片的數據很大,則處理時間會到 10 秒級,嚴重影響了集羣的恢復能力。

解決方案:採用 ES 的 tribe node 特性實現 ES 多集羣。文中後面會介紹下 tribe node 的原理。

3、業務場景的坑

ES 的被普遍應用到多個場景,好比查詢日誌、查詢商品資料、數據聚合等。而這些場景的需求又有很是大的差別,這也是一個坑。

  • 場景一:前端首頁搜索功能。好比搜索商品,數據實時寫入的頻率不高,可是讀的頻率很高。
  • 場景二:日誌檢索的功能。日誌系統中,咱們通常都是 ELK 這種架構模式,對實時寫入要求很高,而查詢的次數其實很少,畢竟查詢日誌多工做仍是開發和運維人員來作。
Kibana 界面
  • 場景三:監控、分析的功能。ES 也會被運用到須要監控數據和分析數據的場景中,而這種場景又是對 ES 的內存要求比較高,由於這些分析功能是在內存中完成的,若內存出現太大的壓力,則會形成系統的垃圾回收,可能出現短暫的服務抖動。

解決方案:按業務場景劃分 ES 集羣,一樣採用 ES tribe node 功能。

4、ES Tribe Node 方案

ES tribe node  功能原理圖以下所示:

  • 有兩個 ES 集羣,每一個集羣都有多個 ES 節點。
  • Logstash 負責日誌蒐集。
  • Kibana 負責客戶端查詢,將查詢命令傳送到 ES Tribe Node。
  • ES Tribe Node 還承擔了集羣管理的職責。
後續咱們再來聊聊 ES Tribe Node 的底層原理和用法~

參考資料: 

https://www.infoq.cn/article/SbfS6uOcF_gW6FEpQlLK https://www.elastic.co/guide/en/elasticsearch/reference/2.0/modules-tribe.html advance-java

ES 搜索引擎系列文章彙總:

1、別隻會搜日誌了,求你懂點原理吧

2、ES 終於能夠搜到」悟空哥「了!

3、1W字|40 圖|硬核 ES 實戰

- END -

寫了兩本 PDF, 回覆  分佈式  或  PDF  載。
個人 JVM 專欄已上架,回覆  JVM  領取

我是悟空,努力變強,變身超級賽亞人!

本文分享自微信公衆號 - 悟空聊架構(PassJava666)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。