補充章節
正如前文提到的,這就是第個補充的章節,這裏會介紹 Elasticsearch 如何在分佈式環境中運行。 本章解釋了經常使用術語,好比 集羣 (cluster), 節點 (node) 以及 分片 (shard),以及如何橫向擴展主機,如何處理硬件故障。node
儘管這一章不是必讀章節 —— 你能夠徹底不用理會分片,複製以及故障恢復就能長時間使用 Elasticsearch。你能夠先跳過這一章節,而後在你須要的時候再回來。數據庫
你能夠隨時根據你的須要擴展 Elasticsearch。你能夠購買配置更好的主機 (vertical scale or scaling up) 或者購買更多的主機 (horizontal scale or scaling out) 來達到擴展的目的。安全
硬件越強大,Elasticsearch 運行的也就越快,可是垂直擴展 (vertical scale) 方式也有它的侷限性。真正的擴展來自於橫向擴展 (horizontal scale) 方式,在集羣中添加更多的節點,這樣能在節點之間分配負載。elasticsearch
對於大多數數據庫來講,橫向擴展意味着你的程序每每須要大改,以充分使用這些新添加的設備。相比而言,Elasticsearch 自帶 分佈式功能:他知道如何管理多個節點並提供高可用性。這也就意味着你的程序根本不須要爲擴展作任何事情。分佈式
在這一章節,咱們將要探索如何根據你的須要建立你的 集羣,節點 以及 分片,並保障硬件故障後,你的數據依舊的安全。性能
若是咱們啓用一個既沒有數據,也沒有索引的單一節點,那咱們的集羣看起來就像是這樣 學習
節點 是 Elasticsearch 運行中的實例,而 集羣 則包含一個或多個具備相同 cluster.name
的節點,它們協同工做,共享數據,並共同分擔工做負荷。因爲節點是從屬集羣的,集羣會自我重組來均勻地分發數據。測試
集羣中的一個節點會被選爲 master 節點,它將負責管理集羣範疇的變動,例如建立或刪除索引,添加節點到集羣或從集羣刪除節點。master 節點無需參與文檔層面的變動和搜索,這意味着僅有一個 master 節點並不會因流量增加而成爲瓶頸。任意一個節點均可以成爲 master 節點。咱們例舉的集羣只有一個節點,所以它會扮演 master 節點的角色。搜索引擎
做爲用戶,咱們能夠訪問包括 master 節點在內的集羣中的任一節點。每一個節點都知道各個文檔的位置,並可以將咱們的請求直接轉發到擁有咱們想要的數據的節點。不管咱們訪問的是哪一個節點,它都會控制從擁有數據的節點收集響應的過程,並返回給客戶端最終的結果。這一切都是由 Elasticsearch 透明管理的。spa
在 Elasticsearch 集羣中能夠監控統計不少信息,其中最重要的就是:集羣健康(cluster health)。它的status
有 green
、yellow
、red
三種;
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 }
status
是咱們最應該關注的字段。status
能夠告訴咱們當前集羣是否處於一個可用的狀態。三種顏色分別表明:
狀態 | 意義 |
---|---|
green |
全部主分片和從分片均可用 |
yellow |
全部主分片可用,但存在不可用的從分片 |
red |
存在不可用的主要分片 |
在接下來的章節,咱們將學習一下什麼是主要分片(primary shard) 和 從分片(replica shard),並說明這些狀態在實際環境中的意義。
爲了將數據添加到 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> }
status
爲 yellow
.集羣的健康情況 yellow
意味着全部的 主分片(primary shards) 啓動而且運行了,這時集羣已經能夠成功的處理任意請求,可是 從分片(replica shards) 沒有徹底被激活。事實上,當前這三個從分片都處於unassigned
(未分配)的狀態,它們還未被分配到節點上。在同一個節點上保存相同的數據副本是沒有必要的,若是這個節點故障了,就等同於全部的數據副本也丟失了。
如今咱們的集羣已經可用了,可是依舊存在因硬件故障而致使數據丟失的風險。
在單一節點上運行意味着有單點故障的風險,沒有數據冗餘備份。幸運的是,咱們能夠啓用另外一個節點來保護咱們的數據。
啓動第二個節點
爲了測試在增長第二個節點後發生了什麼,你可使用與第一個節點相同的方式啓動第二個節點(你能夠參考 入門-》安裝-》運行 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 }
status
是 green
.咱們的集羣不只功能齊全的,而且具備高可用性。
隨着應用需求的增加,咱們該如何擴展?若是咱們啓動第三個節點,集羣內會自動重組,這時便成爲了三節點集羣(cluster-three-nodes)
分片已經被從新分配以平衡負載:
在 Node 1
和 Node 2
中分別會有一個分片被移動到 Node 3
上,這樣一來,每一個節點上就都只有兩個分片了。這意味着每一個節點的硬件資源(CPU、RAM、I/O)被更少的分片共享,因此每一個分片就會有更好的性能表現。
分片自己就是一個很是成熟的搜索引擎,它可使用單個節點的全部資源。咱們一共有6個分片(3個主分片和3個從分片),所以最多能夠擴展到6個節點,每一個節點上有一個分片,這樣每一個分片均可以使用到所在節點100%的資源了。
可是若是咱們想要擴展到六個節點以上應該怎麼辦?
主分片的數量在索引建立的時候就已經指定了,實際上,這個數字定義了能存儲到索引中的數據最大量(具體的數量取決於你的數據,硬件的使用狀況)。例如,讀請求——搜索或者文檔恢復就能夠由主分片或者從分片來執行,因此當你擁有更多份數據的時候,你就擁有了更大的吞吐量。
從分片的數量能夠在運行的集羣中動態的調整,這樣咱們就能夠根據實際需求擴展或者縮小規模。接下來,咱們來增長一下從分片組的數量:
PUT /blogs/_settings
{
"number_of_replicas" : 2 }
增長number_of_replicas
到2:
從圖中能夠看出,如今 blogs
的索引總共有9個分片:3個主分片和6個從分片。也就是說,如今咱們就能夠將總節點數擴展到9個,就又會變成一個節點一個分片的狀態了。最終咱們獲得了三倍搜索性能的三節點集羣。
提示
固然,僅僅是在一樣數量的節點上增長從分片的數量是根本不能提升性能的,由於每一個分片都有訪問系統資源的權限。你須要升級硬件配置以提升吞吐量。
不過更多的從分片意味着咱們有更多的冗餘:經過上文的配置,咱們能夠承受兩個節點的故障而不會丟失數據。
前文咱們已經提到過 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 的橫向擴展以及數據安全的相關內容。接下來,咱們將要繼續討論分片的生命週期等更多細節。