Elasticsearch 教程--分布式集群


集群

補充章節

正如前文提到的,這就是第個補充的章節,這里會介紹 Elasticsearch 如何在分布式環境中運行。 本章解釋了常用術語,比如 集群 (cluster)節點 (node) 以及 分片 (shard),以及如何橫向擴展主機,如何處理硬件故障。

盡管這一章不是必讀章節 —— 你可以完全不用理會分片,復制以及故障恢復就能長時間使用 Elasticsearch。你可以先跳過這一章節,然后在你需要的時候再回來。


你可以隨時根據你的需要擴展 Elasticsearch。你可以購買配置更好的主機 (vertical scale or scaling up) 或者購買更多的主機 (horizontal scale or scaling out) 來達到擴展的目的。

硬件越強大,Elasticsearch 運行的也就越快,但是垂直擴展 (vertical scale) 方式也有它的局限性。真正的擴展來自於橫向擴展 (horizontal scale) 方式,在集群中添加更多的節點,這樣能在節點之間分配負載。

對於大多數數據庫來說,橫向擴展意味着你的程序往往需要大改,以充分使用這些新添加的設備。相比而言,Elasticsearch 自帶 分布式功能:他知道如何管理多個節點並提供高可用性。這也就意味着你的程序根本不需要為擴展做任何事情。

在這一章節,我們將要探索如何根據你的需要創建你的 集群節點 以及 分片,並保障硬件故障后,你的數據依舊的安全。

2.1 空集群

空集群

如果我們啟用一個既沒有數據,也沒有索引的單一節點,那我們的集群看起來就像是這樣 A cluster with one empty node

節點 是 Elasticsearch 運行中的實例,而 集群 則包含一個或多個具有相同 cluster.name 的節點,它們協同工作,共享數據,並共同分擔工作負荷。由於節點是從屬集群的,集群會自我重組來均勻地分發數據。

集群中的一個節點會被選為 master 節點,它將負責管理集群范疇的變更,例如創建或刪除索引,添加節點到集群或從集群刪除節點。master 節點無需參與文檔層面的變更和搜索,這意味着僅有一個 master 節點並不會因流量增長而成為瓶頸。任意一個節點都可以成為 master 節點。我們例舉的集群只有一個節點,因此它會扮演 master 節點的角色。

作為用戶,我們可以訪問包括 master 節點在內的集群中的任一節點。每個節點都知道各個文檔的位置,並能夠將我們的請求直接轉發到擁有我們想要的數據的節點。無論我們訪問的是哪個節點,它都會控制從擁有數據的節點收集響應的過程,並返回給客戶端最終的結果。這一切都是由 Elasticsearch 透明管理的。

2.2 集群健康

集群健康

在 Elasticsearch 集群中可以監控統計很多信息,其中最重要的就是:集群健康(cluster health)。它的status 有 greenyellowred 三種;

GET /_cluster/health

在一個沒有索引的空集群中,它將返回如下信息:

{
   "cluster_name": "elasticsearch", "status": "green", <1> "timed_out": false, "number_of_nodes": 1, "number_of_data_nodes": 1, "active_primary_shards": 0, "active_shards": 0, "relocating_shards": 0, "initializing_shards": 0, "unassigned_shards": 0 } 
    1. status 是我們最應該關注的字段。

status 可以告訴我們當前集群是否處於一個可用的狀態。三種顏色分別代表:

狀態 意義
green 所有主分片和從分片都可用
yellow 所有主分片可用,但存在不可用的從分片
red 存在不可用的主要分片

在接下來的章節,我們將學習一下什么是主要分片(primary shard) 和 從分片(replica shard),並說明這些狀態在實際環境中的意義。

2.3 添加索引

添加索引

為了將數據添加到 Elasticsearch,我們需要 索引(index) —— 存儲關聯數據的地方。實際上,索引只是一個邏輯命名空間(logical namespace),它指向一個或多個 分片(shards)

分片(shard) 是 工作單元(worker unit) 底層的一員,它只負責保存索引中所有數據的一小片。在接下來的《深入分片》一章中,我們還將深入學習分片是如何運作的,但是現在你只要知道分片是一個獨立的Lucene實例既可,並且它自身也是一個完整的搜索引擎。我們的文檔存儲並且被索引在分片中,但是我們的程序並不會直接與它們通信。取而代之,它們直接與索引進行通信的。

在 elasticsearch 中,分片用來分配集群中的數據。把分片想象成一個數據的容器。數據被存儲在分片中,然后分片又被分配在集群的節點上。當你的集群擴展或者縮小時,elasticsearch 會自動的在節點之間遷移分配分片,以便集群保持均衡。

分片分為 主分片(primary shard) 以及 從分片(replica shard) 兩種。在你的索引中,每一個文檔都屬於一個主分片,所以具體有多少主分片取決於你的索引能存儲多少數據。

雖然理論上主分片對存儲多少數據是沒有限制的。分片的最大數量完全取決於你的實際狀況:硬件的配置、文檔的大小和復雜度、如何索引和查詢你的文檔,以及你期望的響應時間。

從分片只是主分片的一個副本,它用於提供數據的冗余副本,在硬件故障時提供數據保護,同時服務於搜索和檢索這種只讀請求。

索引中的主分片的數量在索引創建后就固定下來了,但是從分片的數量可以隨時改變。

接下來,我們在空的單節點集群中上創建一個叫做 blogs 的索引。一個索引默認設置了5個主分片,但是為了演示,我們這里只設置3個主分片和一組從分片(每個主分片有一個從分片對應):

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

現在,我們的集群看起來就像下圖所示了有索引的單節點集群,這三個主分片都被分配在 Node 1

有索引的單節點集群

如果我們現在查看 集群健康(cluster-health) ,我們將得到如下信息:

{
   "cluster_name": "elasticsearch", "status": "yellow", <1> "timed_out": false, "number_of_nodes": 1, "number_of_data_nodes": 1, "active_primary_shards": 3, "active_shards": 3, "relocating_shards": 0, "initializing_shards": 0, "unassigned_shards": 3 <2> } 
    1. 集群的 status 為 yellow.
    2. 我們的三個從分片還沒有被分配到節點上。

集群的健康狀況 yellow 意味着所有的 主分片(primary shards) 啟動並且運行了,這時集群已經可以成功的處理任意請求,但是 從分片(replica shards) 沒有完全被激活。事實上,當前這三個從分片都處於unassigned(未分配)的狀態,它們還未被分配到節點上。在同一個節點上保存相同的數據副本是沒有必要的,如果這個節點故障了,就等同於所有的數據副本也丟失了。

現在我們的集群已經可用了,但是依舊存在因硬件故障而導致數據丟失的風險。

2.4 容錯轉移

增加故障轉移

在單一節點上運行意味着有單點故障的風險,沒有數據冗余備份。幸運的是,我們可以啟用另一個節點來保護我們的數據。


啟動第二個節點

為了測試在增加第二個節點后發生了什么,你可以使用與第一個節點相同的方式啟動第二個節點(你可以參考 入門-》安裝-》運行 Elasticsearch 一章),而且在同一個目錄——多個節點可以分享同一個目錄。

只要第二個節點與第一個節點的 cluster.name 相同(參見./config/elasticsearch.yml文件中的配置),它就能自動發現並加入到第一個節點的集群中。如果沒有,請結合日志找出問題所在。這可能是多播(multicast)被禁用,或者防火牆阻止了節點間的通信。


如果我們啟動了第二個節點,這個集群應該叫做 雙節點集群(cluster-two-nodes)

雙節點集群——所有的主分片和從分片都被分配: 雙節點集群

當第二個節點加入后,就產生了三個 從分片(replica shards) ,它們分別於三個主分片一一對應。也就意味着即使有一個節點發生了損壞,我們可以保證數據的完整性。

所有被索引的新文檔都會先被存儲在主分片中,之后才會被平行復制到關聯的從分片上。這樣可以確保我們的文檔在主節點和從節點上都能被檢索。

當前,cluster-health 的狀態為 green,這意味着所有的6個分片(三個主分片和三個從分片)都已激活:

{
   "cluster_name": "elasticsearch", "status": "green", <1> "timed_out": false, "number_of_nodes": 2, "number_of_data_nodes": 2, "active_primary_shards": 3, "active_shards": 6, "relocating_shards": 0, "initializing_shards": 0, "unassigned_shards": 0 } 
    1. 集群的 status 是 green.

我們的集群不僅功能齊全的,並且具有高可用性

2.5 橫向擴展

橫向擴展

隨着應用需求的增長,我們該如何擴展?如果我們啟動第三個節點,集群內會自動重組,這時便成為了三節點集群(cluster-three-nodes)

分片已經被重新分配以平衡負載: 三節點集群

在 Node 1 和 Node 2 中分別會有一個分片被移動到 Node 3 上,這樣一來,每個節點上就都只有兩個分片了。這意味着每個節點的硬件資源(CPU、RAM、I/O)被更少的分片共享,所以每個分片就會有更好的性能表現。

分片本身就是一個非常成熟的搜索引擎,它可以使用單個節點的所有資源。我們一共有6個分片(3個主分片和3個從分片),因此最多可以擴展到6個節點,每個節點上有一個分片,這樣每個分片都可以使用到所在節點100%的資源了。

2.6 擴展

擴展更多

但是如果我們想要擴展到六個節點以上應該怎么辦?

主分片的數量在索引創建的時候就已經指定了,實際上,這個數字定義了能存儲到索引中的數據最大量(具體的數量取決於你的數據,硬件的使用情況)。例如,讀請求——搜索或者文檔恢復就可以由主分片或者從分片來執行,所以當你擁有更多份數據的時候,你就擁有了更大的吞吐量。

從分片的數量可以在運行的集群中動態的調整,這樣我們就可以根據實際需求擴展或者縮小規模。接下來,我們來增加一下從分片組的數量:

PUT /blogs/_settings
{
   "number_of_replicas" : 2 } 

增加number_of_replicas到2: 三節點兩從集群

從圖中可以看出,現在 blogs 的索引總共有9個分片:3個主分片和6個從分片。也就是說,現在我們就可以將總節點數擴展到9個,就又會變成一個節點一個分片的狀態了。最終我們得到了三倍搜索性能的三節點集群。


提示

當然,僅僅是在同樣數量的節點上增加從分片的數量是根本不能提高性能的,因為每個分片都有訪問系統資源的權限。你需要升級硬件配置以提高吞吐量。

不過更多的從分片意味着我們有更多的冗余:通過上文的配置,我們可以承受兩個節點的故障而不會丟失數據。

2.7 故障恢復

故障恢復

前文我們已經提到過 Elasticsearch 可以應對節點故障。讓我們來嘗試一下。如果我們把第一個節點殺掉,我們的集群就會如下圖所示:

殺掉一個節點后的集群

被殺掉的節點是主節點。而為了集群的正常工作必須需要一個主節點,所以首先進行的進程就是從各節點中選擇了一個新的主節點:Node 2

主分片 1 和 2 在我們殺掉 Node 1 后就丟失了,我們的索引在丟失主節點的時候是不能正常工作的。如果我們在這個時候檢查集群健康狀態,將會顯示 red:存在不可用的主節點!

幸運的是,丟失的兩個主分片的完整拷貝在存在於其他的節點上,所以新的主節點所完成的第一件事情就是將這些在 Node 2 和 Node 3 上的從分片提升為主分片,然后集群的健康狀態就變回至 yellow。這個提升的進程是瞬間完成了,就好像按了一下開關。

那么為什么集群健康狀態依然是是 yellow 而不是 green 呢?是因為現在我們有3個主分片,但是我們之前設定了1個主分片有2個從分片,但是現在卻只有1份從分片,所以狀態無法變為 green,不過我們可以不用太擔心這里:當我們再次殺掉 Node 2 的時候,我們的程序依舊可以在沒有丟失任何數據的情況下運行,因為Node 3 中依舊擁有每個分片的備份。

如果我們重啟 Node 1,集群就能夠重新分配丟失的從分片,這樣結果就會與三節點兩從集群一致。如果Node 1 依舊還有舊節點的內容,系統會嘗試重新利用他們,並只會復制在故障期間的變更數據。

到目前為止,我們已經清晰地了解了 Elasticsearch 的橫向擴展以及數據安全的相關內容。接下來,我們將要繼續討論分片的生命周期等更多細節。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM