Elasticsearch必知必會

前置知識:

Elasticsearch基本概念與核心原理
Elasticsearch數據建模

1. Elasticsearch的分佈式架構原理是什麼?

Elasticsearch是分佈式的, 在多臺機器上啓動ES進程實例, 組成一個ES集羣. ES集羣中的節點會選舉出一個master節點來管理集羣, 比如負責索引的創建與刪除, 負責主分片與副本分片的身份切換等等. ES集羣的master節點選舉算法如下:

  • 查找當前活躍的Master節點.
  • 如果存在活躍的Master節點, 選擇其中nodeId最小的那個作爲Master節點. (腦裂問題可能導致多個Master節點)
  • 如果不存在活躍的Master節點, 則獲取集羣中活躍的Master Eligible Nodes, 進行投票選舉.
  • 如果集羣中活躍的候選節點數超過一半(正常情況下候選節點數的一半), 則選擇clusterStateVersion(集羣狀態版本)最新的那個作爲Master節點. 如果clusterStateVersion相同, 則選擇nodeId最小的那個作爲Master節點.
  • 如果如果集羣中活躍的候選節點數沒有超過一半, 則無法選舉.

ES存儲數據的基本單位是索引, 每個索引都會被拆分爲多個分片, 每個分片分佈在不同節點上. 同時爲了保證可用性, 每個分片都會設置副本, 主分片提供讀寫服務, 副本分片提供讀服務. 當主分片所在的節點宕機後, master節點會從副本分片中選出一個作爲主分片, 然後當宕機的節點修復後, master節點會將缺失的副本分片分配過去, 同步數據後, 集羣恢復正常.

2. Elasticsearch寫入數據的工作原理, 查詢數據的工作原理, 搜索數據的工作原理分別是什麼?

Elasticsearch寫入數據的工作原理

  • 客戶端發送請求到任意一個協調節點(Coordinating Node), 然後協調節點將請求轉發給master節點.
  • master節點對document進行路由, 將document寫入主分片.
  • document寫入主分片後, 將數據同步到副本分片.
  • 主分片和副本分片都寫入成功後, 返回響應結果給客戶端.

(1) document寫入主分片的詳細過程

  • Document寫入Index Buffer(ES進程緩衝), 同時將寫命令記錄到Transaction Log.
  • 每隔1秒或Index Buffer空間被佔滿後, Index Buffer中的數據被寫入新的Segment中, 並進入OS Cache, 這個過程叫Refresh. (此時倒排索引已創建, 存在OS Cache中, 數據可被搜索)
  • 重複前面兩個步驟.
  • 每隔30分鐘或Transaction Log佔滿後, 先進行Refresh操作, 然後將OS Cache中的Segment刷入磁盤, 這個過程叫Flush.
  • 刪除舊Transaction Log, 創建一個新的Transaction Log.
  • ES定期合併磁盤中的Segment File, 同時清除那些被標記爲delete的文檔.

(2) ES被稱爲近實時(Near Realtime)的原因

從上文"document寫入主分片的詳細過程"中可以知道, Refresh操作每秒執行一次, 只有執行Refresh操作之後, 倒排索引纔會被創建, 數據才能被搜索, 這就是ES被稱爲近實時的原因.

(3) ES存在數據丟失的問題

從上文"document寫入主分片的詳細過程"中可以知道, document寫入Index Buffer的同時會將寫命令記錄到Transaction Log, 目的是如果數據落盤之前機器宕機了, 可以從Transaction Log中恢復數據. 但在舊版本中Transaction Log不是默認落盤的, 它會先寫入OS Cache中, 每隔5s纔會被刷入磁盤, 所以如果在Transaction Log落盤前機器宕機了, 數據就完全丟失了.

在新版本7.x中, Transaction Log是默認落盤的, 也就不會有數據丟失的問題. (index.translog.durability, index.translog.sync_interval)

Elasticsearch查詢數據的工作原理(Get查詢)

  • 客戶端發送請求到任意一個協調節點(Coordinating Node).
  • 協調節點根據id進行路由, 找到對應的分片.
  • 根據round-robin隨機輪詢算法, 在主分片和其他副本分片中隨機選擇一個, 進行查詢.
  • 將對應的document返回給協調節點.
  • 協調節點返回document給客戶端.

Elasticsearch搜索數據的工作原理

  • 客戶端發送請求到任意一個協調節點(Coordinating Node).
  • 協調節點將搜索請求轉發給所有分片(主分片和副本分片採用隨機輪詢算法選一個)
  • 每個分片將自己的搜素結果(這裏只有id)返回給協調節點
  • 協調節點對搜索結果進行合併, 排序, 分頁等操作, 得出最終結果.
  • 協調節點根據最終結果的id去各個分片上拉取document, 返回給客戶端.

3. Elasticsearch在數據量很大的情況下(數十億級別)如何提高搜索性能?

(1) 善於利用OS Cache

如果Elasticsearch的每次搜索都要落盤, 那搜索性能肯定很差, 將達到秒級. 但如果ES集羣中的數據量等於OS Cache的容量, 那每次搜索都會直接走OS Cache, 這樣性能就會很高, 達到毫秒級.

ES集羣中的數據量最好不要超過OS Cache的容量, 最低要求也不能超過OS Cache的兩倍. 比如我們ES集羣有3臺機器, 每臺機器64G內存, 爲每個節點的ES JVM Heap分配32G內存, 最終集羣的OS Cache爲 32G * 3 = 96G內存. 我們ES集羣中的數據量最優情況是不超過96G, 最低要求的情況是不超過192G.

(2) 數據建模

從上文"善於利用OS Cache"中我們知道, 我們要保證ES集羣中的數據量不超過OS Cache的容量, 那麼我們在數據建模的時候就要注意兩點:

  • 不要將MySQL表中的所有字段都寫入ES, 只寫入一部分會被搜索的字段.
  • 對於MySQL中具有關聯關係的表, 我們直接將關聯字段寫入ES中或在應用端處理關聯關係, 禁止在ES中處理關聯關係.

(3) 數據預熱

如果我們無法做到讓ES集羣中的數據量不超過OS Cache的容量, 那我們做一個緩存預熱子系統, 定時搜索"熱數據", 讓其進入OS Cache.

(4) 冷熱分離

在數據預熱的基礎上我們還可以進行冷熱數據分離, 比如我們有6臺機器, 創建兩個索引, 每個索引3個分片, 一個索引放熱數據, 一個索引放冷數據. 熱數據量一般只佔總數據量的10%, 這樣我們就能保證熱數據都在OS Cache中. 而冷數據雖然佔總數據的90%, 但卻只有10%的用戶訪問, 性能差點是可以接受的.

(5) 分頁性能優化

深度分頁的性能是很差的, 我們要防止出現深度分頁的情況, 用滾動翻頁來代替深度分頁.

  • search after
  • scroll

Elasticsearch分頁API

4. Elasticsearch生產集羣的部署架構是什麼?每個索引的數據量大概有多少?每個索引大概有多少個分片?

(1) ES生產集羣我們部署了5臺機器, 每臺機器是6核64G的, 集羣總內存是320G.

(2) 我們ES集羣的日增量數據大概是2000萬條, 500MB左右; 每月增量數據大概是6億條, 15G左右. 目前系統已經運行了幾個月, 現在ES集羣裏數據總量大概是100G左右.

(3) 目前線上有5個索引(這個結合你們自己業務來, 看看自己有哪些數據可以放ES的), 每個索引的數據量大概是20G, 所以這個數據量之內, 我們每個索引分配的是8個shard, 比默認的5個shard多了3個shard.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章