ElasticSearch 分佈式集羣

公號:碼農充電站pro
主頁:https://codeshellme.github.iohtml

1,ES 的分佈式架構

ES 是一個分佈式的集羣,具備高可用性可擴展性node

  • 高可用性指的是:當某些節點意外宕機或者數據丟失的時候,不影響整個集羣的使用。
  • 可擴展性指的是:當業務數據量增長的時候,能夠增長節點的數量,從而加強整個集羣的能力。

ES 集羣git

ES 集羣中能夠有一個或多個節點,ES 經過集羣名字來區分不一樣的集羣,集羣名能夠經過 cluster.name 進行設置,默認爲 "elasticsearch"。github

2,ES 的節點類型

ES 的一個節點就是一個 Java 進程,因此一臺機器能夠運行一個或多個節點,生產環境建議一臺機器只運行一個節點。算法

每一個節點啓動以後,都會分配一個 UID,並保存在 data 目錄下。shell

每一個節點都有節點名字,節點名可經過 node.name 設置。緩存

2.1,Master 節點

Master 節點的職責:網絡

  • 處理客戶端的請求。
  • 決定分片被分配到哪一個節點。
  • 負責索引的建立於刪除。
  • 維護集羣狀態。
  • 等。

集羣的狀態包括:架構

  • 全部的節點信息
  • 全部的索引及其 Mapping 和 Setting 信息
  • 分片的路由信息

全部的節點有保存了集羣的狀態信息,但只有主節點可以修改集羣狀態。app

2.2,Master-eligible 節點

在 ES 集羣中,只有 Master-eligible 節點能夠被選舉爲 Master 節點。

每一個節點啓動後默認就是 Master-eligible 節點,能夠經過設置 node.masterfalse 來禁止成爲 Master-eligible 節點。

默認狀況下,集羣中的第一個節點啓動後,會將本身選舉爲 Master 節點。

集羣中的每一個節點都保存了集羣的狀態,但只有 Master 節點可以修改集羣的狀態信息。

2.3,Data 與 Coordinating 節點

用於保存 ES 數據的節點,就是 Data 節點,它對數據擴展起到了相當重要的做用。

Coordinating 節點叫作協調節點,它負責接收 Client 的請求,將請求分發到合適的節點,並最終彙總結果返回給 Client。

在 ES 中,全部的節點都是 Coordinating 節點。

2.4,Ingest 節點

Ingest 節點用於對數據預處理,經過添加一些 processors 來完成特定的處理。

Ingest 節點是在 ES 5.0 後引入的一種節點類型,能夠達到必定的 Logstash 的功能。

默認狀況下,全部的節點都是 Ingest 節點。

2.5,配置節點類型

理論上,一個節點能夠扮演過多個角色,但生產環境中,建議設置單一角色。

節點的類型能夠經過下面參數進行配置:

節點類型 配置參數 默認值
Master-eligible node.master true
Data Node node.data true
Ingest Node node.ingest true
Coordinating Node 設置上面 3 個都爲 false

3,集羣的健康狀態

咱們能夠經過下面的 API 來查看整個集羣的健康狀態:

在這裏插入圖片描述

集羣有 3 種級別的健康狀態:

  • green:全部的主分片與副本分片都正常。
  • yellow:全部的主分片都正常,某些副本分片不正常。
  • red:部分主分片不正常。

咱們也能夠經過 Kibana 中的索引管理,來查看每一個索引的健康狀態:

在這裏插入圖片描述

索引的狀態級別與集羣的狀態級別一致。

4,腦裂問題

腦裂問題是分佈式系統中的經典問題。

腦裂問題指的是,當出現網絡故障時,一些節點沒法與另外一些節點鏈接,這時這兩大部分節點會各自爲主;當網絡恢復時,也沒法恢復成一個總體。

在這裏插入圖片描述

如何避免腦裂問題

要限定一個選舉條件,設置 Quorum(仲裁):

  • Quorum = (master 節點總數 / 2)+ 1

只有當 Master eligible 節點數大於 Quorum 時,才能進行選舉。

在 ES 7.0 以前,爲了不腦裂問題,須要手動設置 discovery.zen.minimum_master_nodes 爲 Quorum。

在 ES 7.0 以後,ES 會本身處理腦裂問題,不須要用戶處理。

5,ES 中的分片

ES 中的分片(Shard)用於存儲數據,是存儲的最小單元

分片有兩種:主分片(Primary Shard)和副本分片(Replica Shard),副本分片是主分片的拷貝。

主分片用於數據水平擴展的問題,主分片數在索引建立時指定,以後不容許修改

副本分片用於解決數據高可用的問題,副本分片數能夠動態調整

分片數能夠經過索引的 setting 進行設置,好比:

PUT /index_name 
{
    "settings" : {
        "number_of_shards" : 3,
        "number_of_replicas" : 1
    }
}

其中 number_of_shards 表示主分片數,number_of_replicas 表示每一個主分片的副本分片數。

若是一個集羣有 3 個數據節點,某個索引有 3 個主分片,1 一個副本分片,那麼它的節點分佈會像下面這樣:

在這裏插入圖片描述

其中藍色框爲主分片,白色框爲副本分片。

ES 在分配主副分片時,會將副本分片與主分片應該在不一樣的節點上

主分片和副本分片分別分佈到不一樣的數據節點上,這樣的話,若是有某個數據節點宕機,也不會影響整個系統的使用。

ES 7.0 開始,默認的主分片數爲 1,默認的副本分片數爲 0。在生產環境中,副本分片數至少爲 1。

5.1,生產環境如何設置分片數

分片數設置不合理引起的問題:

在這裏插入圖片描述

5.2,集羣節點的變化

在這裏插入圖片描述

根據這樣的配置(3 個主分片,1 個副本分片),若是隻有一個節點,則會致使副本分片沒法分配(ES 會將主副分片分配在不一樣的節點上),集羣狀態爲 yellow

若是此時增長一個數據節點,那麼副本分片就得以分配,集羣具有了故障轉移能力,集羣狀態轉爲 green

在這裏插入圖片描述

若是此時再增長一個數據節點,那麼主節點會從新分配分片的分佈。同時,集羣的總體能力也獲得了提高。

在這裏插入圖片描述

5.3,故障轉移

若是此時有一個節點發生故障,好比主節點發生了故障:

在這裏插入圖片描述

此時集羣的狀態會變爲 yellow,而後會從新選舉主節點(假設選舉了 Node2 爲主節點),而且原來的 Node1 節點上的 p0R1 分片,會被分配到 Node2Node3 上。

在這裏插入圖片描述

集羣調整完畢後,會從新恢復到 green 狀態。

6,分片的內部原理

ES 中的一個分片對應了 Lucene 中的一個 Index。

6.1,Lucene Index

在 Lucene 中,單個倒排索引文件稱爲 Segment

Segment 是不可變的,當有新的文檔寫入時,會生成新的 Segment(放在文件系統緩存中)。

多個 Segment 彙總在一塊兒稱爲 Lucene 中的 Index,也就是 ES 中的分片。

在這裏插入圖片描述

6.2,Refresh 刷新

ES 的文檔在寫入時,會先放在 Index Buffer(內存) 中,當 Index Buffer 的空間被佔用到必定程度/時間週期後,會 Refresh 到 Segment 中,Index Buffer 則會被清空。

在這裏插入圖片描述

Refresh 的刷新頻率能夠經過 index.refresh_interval 參數進行設置,默認爲 1 秒。

或者當 Index Buffer 被佔用到 JVM 的 10%(默認值),也會觸發 Refresh。

當文檔被 Refresh 到 Segment 後,就能夠被 ES 檢索到了。

6.3,Transaction log

寫入文檔時,會先放在 Index Buffer 中,而 Index Buffer 是在內存中,爲了防止內存意外(好比斷電)丟失,在寫入 Index Buffer 的同時,也會寫到 Transaction log(磁盤)中。

在這裏插入圖片描述

一個 Transaction log 默認是 512M。

6.4,Flush 操做

ES 的 Flush 會觸發如下操做:

  • 調用 Refresh
  • 調用 fsync,將文件系統緩存中的 Segment 寫入磁盤。
  • 清空 Transaction log。

Flush 操做默認 30 分鐘調用一次,或者當 Transaction log 滿(默認 512 M)時也會觸發 Flush。

6.5,Merge 合併

當愈來愈多的 Segment 被寫入到磁盤後,磁盤上的 Segment 會變得不少,ES 會按期 Merge 這些 Segment。

文檔的刪除操做並不會立刻被真正的刪除,而是會寫入 del 文件中,Merge 操做也會刪除該文件。

Merge 操做能夠由 ES 自動觸發,也能夠手動強制 Merge,語法以下:

POST index_name/_forcemerge

7,文檔的分佈式存儲

文檔會均勻分佈在分片上,充分利用硬件資源,避免資源利用不均。

文檔到分片的路由算法:

  • shard_index = hash(_routing) % number_of_primary_shards
  • Hash 算法能夠保證文檔均勻的分散到分片上。
  • 默認的 _routing 值爲文檔 id。
  • _routing 的值也能夠自行指定。

正是由於文檔的路由算法是基於主分片數來計算的,因此主分片數一旦肯定之後,就不能修改。

_routing 的設置語法以下:

POST index_name/_doc/doc_id/routing=xxx
{
  # 文檔數據
}

文檔的 Write 操做(插入,更新,刪除)的流程:

  1. 客戶將文檔的 Write 請求發送到 Coordinating 節點(Coordinating 節點負責處理客戶請求,而不是 Master 節點)。
  2. Coordinating 節點經過 Hash 算法找到該文檔的主分片
  3. 在主分片上進行 Write 操做,主分片 Write 成功後,將該 Write 請求發送到全部的副本分片
  4. 全部副本分片進行相應的 Write 操做,成功後,將結果返回給主分片。
  5. 主分片將因此的執行結果反饋給 Coordinating 節點。
  6. Coordinating 節點將最終的結果反饋給客戶端。

在這裏插入圖片描述

8,分佈式查詢及相關性算分

8.1,Query Then Fetch 過程

ES 的搜索過程分兩個階段:

  • Query 階段:
    • 用戶將查詢請求發送到 Coordinating 節點,Coordinating 節點會隨機選擇 N(主分片數) 個分片,發送查詢請求。
    • 收到查詢請求的分片執行查詢,並進行排序。而後每一個分片都會返回 From + Size 個排好序的文檔 ID 和排序值(score),給 Coordinating 節點。
  • Fetch 階段:
    • Coordinating 節點會將從全部分片獲得的文檔從新排序,從新獲得 From + Size 個文檔的 ID。
    • Coordinating 節點以 Multi Get 的方式,到相應的分片獲取具體的文檔信息,並返回給用戶。

這兩個階段合稱爲 Query Then Fetch

在這裏插入圖片描述

8.2,Query Then Fetch 的問題

在這裏插入圖片描述

8.3,算分不許的解決辦法

在這裏插入圖片描述

(本節完。)


推薦閱讀:

ElasticSearch 文檔及操做

ElasticSearch 搜索模板與建議

ElasticSearch 聚合分析

ElasticSearch 中的 Mapping

ElasticSearch 數據建模


歡迎關注做者公衆號,獲取更多技術乾貨。

碼農充電站pro

相關文章
相關標籤/搜索