elasticsearch(三)---分佈式集羣

Elasticsearch用於構建高可用和可擴展的系統。擴展的方式能夠是購買更好的服務器(縱向擴展(vertical scale or scaling up))或者購買更多的服務器(橫向擴展(horizontal scale or scaling out))。html

Elasticsearch雖然能從更強大的硬件中得到更好的性能,可是縱向擴展有它的侷限性。真正的擴展應該是橫向的,它經過增長節點來均攤負載和增長可靠性。node

對於大多數數據庫而言,橫向擴展意味着你的程序將作很是大的改動才能利用這些新添加的設備。對比來講,Elasticsearch天生就是分佈式的:它知道如何管理節點來提供高擴展和高可用。這意味着你的程序不須要關心這些。 在這章咱們將探索如何建立你的集羣(cluster)、節點(node)和分片(shards),使其按照你的需求進行擴展,並保證在硬件故障時數據依舊安全。數據庫

空集羣

若是咱們啓動一個單獨的節點,它尚未數據和索引,這個集羣看起來就像圖1。安全

圖1:只有一個空節點的集羣服務器

一個節點(node)就是一個Elasticsearch實例,而一個集羣(cluster)由一個或多個節點組成,它們具備相同的cluster.name,它們協同工做,分享數據和負載。當加入新的節點或者刪除一個節點時,集羣就會感知到並平衡數據。網絡

集羣中一個節點會被選舉爲主節點(master),它將臨時管理集羣級別的一些變動,例如新建或刪除索引、增長或移除節點等。主節點不參與文檔級別的變動或搜索,這意味着在流量增加的時候,該主節點不會成爲集羣的瓶頸。任何節點均可以成爲主節點。咱們例子中的集羣只有一個節點,因此它會充當主節點的角色。併發

作爲用戶,咱們可以與集羣中的任何節點通訊,包括主節點。每個節點都知道文檔存在於哪一個節點上,它們能夠轉發請求到相應的節點上。咱們訪問的節點負責收集各節點返回的數據,最後一塊兒返回給客戶端。這一切都由Elasticsearch處理。elasticsearch

集羣健康

在Elasticsearch集羣中能夠監控統計不少信息,可是隻有一個是最重要的:集羣健康(cluster health)。集羣健康有三種狀態: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
}
複製代碼

status字段提供一個綜合的指標來表示集羣的的服務情況。三種顏色各自的含義:

在接下來的章節,咱們將說明什麼是主要分片(primary shard)和複製分片(replica shard),並說明這些顏色(狀態)在實際環境中的意義。

添加索引

爲了將數據添加到Elasticsearch,咱們須要索引(index)——一個存儲關聯數據的地方。實際上,索引只是一個用來指向一個或多個分片(shards)的「邏輯命名空間(logical namespace)」.

一個分片(shard)是一個最小級別「工做單元(worker unit)」,它只是保存了索引中全部數據的一部分。在接下來的《深刻分片》一章,咱們將詳細說明分片的工做原理,可是如今咱們只要知道分片就是一個Lucene實例,而且它自己就是一個完整的搜索引擎。咱們的文檔存儲在分片中,而且在分片中被索引,可是咱們的應用程序不會直接與它們通訊,取而代之的是,直接與索引通訊。

分片是Elasticsearch在集羣中分發數據的關鍵。把分片想象成數據的容器。文檔存儲在分片中,而後分片分配到你集羣中的節點上。當你的集羣擴容或縮小,Elasticsearch將會自動在你的節點間遷移分片,以使集羣保持平衡。

分片能夠是主分片(primary shard)或者是複製分片(replica shard)。你索引中的每一個文檔屬於一個單獨的主分片,因此主分片的數量決定了索引最多能存儲多少數據。

理論上主分片能存儲的數據大小是沒有限制的,限制取決於你實際的使用狀況。分片的最大容量徹底取決於你的使用情況:硬件存儲的大小、文檔的大小和複雜度、如何索引和查詢你的文檔,以及你指望的響應時間。
複製代碼

複製分片只是主分片的一個副本,它能夠防止硬件故障致使的數據丟失,同時能夠提供讀請求,好比搜索或者從別的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> 集羣的狀態如今是 yellow

<2> 咱們的三個複製分片尚未被分配到節點上

集羣的健康狀態yellow表示全部的主分片(primary shards)啓動而且正常運行了——集羣已經能夠正常處理任何請求——可是複製分片(replica shards)尚未所有可用。事實上全部的三個複製分片如今都是unassigned狀態——它們還未被分配給節點。在同一個節點上保存相同的數據副本是沒有必要的,若是這個節點故障了,那全部的數據副本也會丟失。

如今咱們的集羣已經功能完備,可是依舊存在因硬件故障而致使數據丟失的風險。

故障轉移

在單一節點上運行意味着有單點故障的風險——沒有數據備份。幸運的是,要防止單點故障,咱們惟一須要作的就是啓動另外一個節點。

啓動第二個節點
爲了測試在增長第二個節點後發生了什麼,你可使用與第一個節點相同的方式啓動第二個節點,並且命令行在同一個目錄——一個節點能夠啓動多個Elasticsearch實例。
只要第二個節點與第一個節點有相同的cluster.name(請看./config/elasticsearch.yml文件),它就能自動發現並加入第一個節點所在的集羣。若是沒有,檢查日誌找出哪裏出了問題。這多是網絡廣播被禁用,或者防火牆阻止了節點通訊。
複製代碼

若是咱們啓動了第二個節點,這個集羣看起來就像下圖。 雙節點集羣——全部的主分片和複製分片都已分配:

第二個節點已經加入集羣,三個複製分片(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
}
複製代碼

咱們的集羣不只是功能完備的,並且是高可用的。

橫向擴展

隨着應用需求的增加,咱們該如何擴展?若是咱們啓動第三個節點,咱們的集羣會從新組織本身,就像圖4:

圖4:包含3個節點的集羣——分片已經被從新分配以平衡負載:

Node3包含了分別來自Node 1和Node 2的一個分片,這樣每一個節點就有兩個分片,和以前相比少了一個,這意味着每一個節點上的分片將得到更多的硬件資源(CPU、RAM、I/O)。

分片自己就是一個完整的搜索引擎,它可使用單一節點的全部資源。咱們擁有6個分片(3個主分片和三個複製分片),最多能夠擴展到6個節點,每一個節點上有一個分片,每一個分片能夠100%使用這個節點的資源。

繼續擴展

若是咱們要擴展到6個以上的節點,要怎麼作?

主分片的數量在建立索引時已經肯定。實際上,這個數量定義了能存儲到索引裏數據的最大數量(實際的數量取決於你的數據、硬件和應用場景)。然而,主分片或者複製分片均可以處理讀請求——搜索或文檔檢索,因此數據的冗餘越多,咱們能處理的搜索吞吐量就越大。

複製分片的數量能夠在運行中的集羣中動態地變動,這容許咱們能夠根據需求擴大或者縮小規模。讓咱們把複製分片的數量從原來的1增長到2:

PUT /blogs/_settings
{
   "number_of_replicas" : 2
}
複製代碼

圖5:增長number_of_replicas到2:

從圖中能夠看出,blogs索引如今有9個分片:3個主分片和6個複製分片。這意味着咱們可以擴展到9個節點,再次變成每一個節點一個分片。這樣使咱們的搜索性能相比原始的三節點集羣增長三倍。

固然,在一樣數量的節點上增長更多的複製分片並不能提升性能,由於這樣作的話平均每一個分片的所佔有的硬件資源就減小了(譯者注:大部分請求都彙集到了分片少的節點,致使一個節點吞吐量太大,反而下降性能),你須要增長硬件來提升吞吐量。

不過這些額外的複製節點使咱們有更多的冗餘:經過以上對節點的設置,咱們可以承受兩個節點故障而不丟失數據。
複製代碼

應對故障

咱們已經說過Elasticsearch能夠應對節點失效,因此讓咱們繼續嘗試。若是咱們殺掉第一個節點的進程(如下簡稱殺掉節點),咱們的集羣看起來就像這樣:

圖5:殺掉第一個節點後的集羣

咱們殺掉的節點是一個主節點。一個集羣必需要有一個主節點才能使其功能正常,因此集羣作的第一件事就是各節點選舉了一個新的主節點:Node 2。

主分片1和2在咱們殺掉Node 1時已經丟失,咱們的索引在丟失主分片時不能正常工做。若是此時咱們檢查集羣健康,咱們將看到狀態red:不是全部主分片均可用!

幸運的是丟失的兩個主分片的完整拷貝存在於其餘節點上,因此新主節點作的第一件事是把這些在Node 2和Node 3上的複製分片升級爲主分片,這時集羣健康回到yellow狀態。這個提高是瞬間完成的,就好像按了一下開關。

爲何集羣健康狀態是yellow而不是green?咱們有三個主分片,可是咱們指定了每一個主分片對應兩個複製分片,當前卻只有一個複製分片被分配,這就是集羣狀態沒法達到green的緣由,不過不用太擔憂這個:當咱們殺掉Node 2,咱們的程序依然能夠在沒有丟失數據的狀況下繼續運行,由於Node 3還有每一個分片的拷貝。

若是咱們重啓Node 1,集羣將可以從新分配丟失的複製分片,集羣情況與上一節的 圖5:增長number_of_replicas到2 相似。若是Node 1依舊有舊分片的拷貝,它將會嘗試再利用它們,它只會從主分片上覆制在故障期間有數據變動的那一部分。

如今你應該對分片如何使Elasticsearch能夠水平擴展並保證數據安全有了一個清晰的認識。接下來咱們將會討論分片生命週期的更多細節。

參考:es官方文檔

相關文章
相關標籤/搜索