首先看下ElasticSearch(ES)的架構:node
術語解釋:json
discovery.zen,ES自動發現節點的機制,ES是一個基於P2P協議的系統,它先經過廣播尋找存在的節點,再經過多播協議來進行節點之間的通訊,同時也支持點對點的交互;架構
ES的分佈式操做大可能是自動完成的:
一、跨節點平衡集羣中各節點的索引與搜索負載;
二、自動複製索引數據以提供冗餘副本,防止硬件錯誤致使數據丟失;
三、自動在節點之間路由,以幫助找到檢索的數據;
四、無縫擴展或者恢復集羣;負載均衡
node(節點)是ES運行中的實例,一個或多個具備相同cluster.name的節點構成一個cluster(集羣),它們協同工做,共享數據,並共同分擔工做負載。
集羣中的一個節點會被選爲master,它將負責管理集羣範疇的變動,例如建立或刪除索引,在集羣中添加或刪除節點,但master無需參與文檔層面的變動和搜索,這意味着僅有一個master並不會因流量增加而成爲瓶頸。
做爲用戶,咱們能夠訪問包括master在內的集羣中的任一節點,每一個節點都知道各個文檔的位置,並可以將咱們的請求直接轉發到擁有咱們想要的數據的節點,不管咱們訪問的是哪一個節點它都會控制從擁有數據的節點收集響應的過程,並返回給客戶端最終的結果,這一切都是由ES透明管理的。elasticsearch
在ES中,分片用來分配集羣中的數據。把分片想象成一個數據的容器。數據被存儲在分片中,而後分片又被分配在集羣的節點上。當你的集羣擴展或者縮小時,elasticsearch會自動的在節點之間遷移分配分片,以便集羣保持均衡。分佈式
分片分爲 主分片(primary shard) 以及 從分片(replica shard) 兩種:memcached
索引中的主分片的數量在索引建立後就固定下來了,可是從分片的數量能夠隨時改變。性能
接下來,咱們在空的單節點集羣中上建立一個叫作blogs的索引。一個索引默認設置了5個主分片,可是爲了演示,咱們這裏只設置3個主分片和一組從分片(每一個主分片有一個從分片對應):搜索引擎
PUT /blogs { "settings" : { "number_of_shards" : 3, "number_of_replicas" : 1 } }
如今,咱們的集羣看起來就像下圖所示了有索引的單節點集羣,這三個主分片都被分配在Node 1。spa
在ES集羣中能夠監控統計不少信息,其中最重要的就是:集羣健康(cluster health)。它的 status 有 green、yellow、red 三種;
GET /_cluster/health
返回:
{
"cluster_name": "elasticsearch",
"status": "yellow",
"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
}
其中status能夠告訴咱們當前集羣是否處於一個可用的狀態。三種顏色分別表明:
狀態 | 意義 |
---|---|
green |
全部主分片和從分片均可用 |
yellow |
全部主分片可用,但存在不可用的從分片 |
red |
存在不可用的主要分片 |
集羣的健康情況yellow意味着全部的 主分片(primary shards) 啓動而且運行了,這時集羣已經能夠成功的處理任意請求,可是 從分片(replica shards) 沒有徹底被激活。事實上,當前這3個從分片都處於unassigned(未分配)的狀態,它們還未被分配到節點上。在同一個節點上保存相同的數據副本是沒有必要的,若是這個節點故障了,就等同於全部的數據副本也丟失了。
爲了提升系統的可用性,生產環境幾乎不會使用單節點ES集羣。
下面介紹如何使用雙節點集羣(cluster-two-nodes),只要第二個節點與第一個節點的cluster.name相同(參見./config/elasticsearch.yml文件中的配置),它就能自動發現並加入到第一個節點的集羣中。若是沒有,請結合日誌找出問題所在。這多是多播(multicast)被禁用,或者防火牆阻止了節點間的通訊。
以下圖,雙節點集羣——全部的主分片和從分片都被分配:
當第二個節點加入後,就產生了三個 從分片(replica shards) ,它們分別於三個主分片一一對應。也就意味着即便有一個節點發生了損壞,咱們能夠保證數據的完整性。
全部被索引的新文檔都會先被存儲在主分片中,以後纔會被平行復制到關聯的從分片上。這樣能夠確保咱們的文檔在主節點和從節點上都能被檢索。
隨着應用需求的增加,咱們該如何擴展?若是咱們啓動第三個節點,集羣內會自動重組,這時便成爲了三節點集羣(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 }
將從分片的數量增長到2份:
從圖中能夠看出,如今blogs的索引總共有9個分片:3個主分片和6個從分片。也就是說,如今咱們就能夠將總節點數擴展到9個,就又會變成一個節點一個分片的狀態了。最終咱們獲得了三倍搜索性能的三節點集羣。
若是上面的三節點集羣中有一個節點發生故障,例如:
被殺掉的節點是主節點。而爲了集羣的正常工做必須須要一個主節點,因此首先進行的進程就是從各節點中選擇了一個新的主節點: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依舊還有舊節點的內容,系統會嘗試從新利用他們,並只會複製在故障期間的變動數據。
當須要新增一個文檔到索引中時,須要爲這個文檔找到一個主分片進行存儲,它按照下面的公式選擇主分片:
shard = HASH(文檔ID) % 主分片數量
其中,文檔ID也能夠被替換成其它能惟一表示一個文檔的字符串。另外,主分片數量在索引建立時就已經肯定了,運行過程當中不容許修改,所以,同一個文檔老是會被路由到同一個主分片上。
ES集羣若是包含多個節點,每一個節點均可以服務全部請求,節點能夠根據上面的方法計算出當前請求的文檔在哪一個分片,而後轉發請求到該節點上。
參考文檔: