在使用中我們把文檔存入ElasticSearch,但是如果能夠了解ElasticSearch內部是如何存儲的,將會對我們學習ElasticSearch有很清晰的認識。本文中的所使用的ElasticSearch集群環境,可以通過查看ElasticSearch 5學習(3)——單台服務器部署多個節點搭建學習。
ElasticSearch用於構建高可用和可擴展的系統。擴展的方式可以是購買更好的服務器(縱向擴展(vertical scale or scaling up))或者購買更多的服務器(橫向擴展(horizontal scale or scaling out))。
Elasticsearch雖然能從更強大的硬件中獲得更好的性能,但是縱向擴展有它的局限性。真正的擴展應該是橫向的,它通過增加節點來均攤負載和增加可靠性。
對於大多數數據庫而言,橫向擴展意味着你的程序將做非常大的改動才能利用這些新添加的設備。對比來說,Elasticsearch天生就是分布式的:它知道如何管理節點來提供高擴展和高可用。這意味着你的程序不需要關心這些。
下面的例子主要圍繞着集群(cluster)、節點(node)和分片(shard)講解,相信學習以后,對於學習Elasticsearch會有很大收獲。
空集群
如果我們啟動一個單獨的節點,它還沒有數據和索引,這個集群看起來如下圖:
只有一個空節點的集群。一個節點(node)就是一個Elasticsearch實例,而一個集群(cluster)由一個或多個節點組成,它們具有相同cluster.name
,它們協同工作,分享數據和負載。當加入新的節點或者刪除一個節點時,集群就會感知到並平衡數據。
集群中一個節點會被選舉為主節點(master),它將臨時管理集群級別的一些變更,例如新建或刪除索引、增加或移除節點等。主節點不參與文檔級別的變更或搜索,這意味着在流量增長的時候,該主節點不會成為集群的瓶頸。任何節點都可以成為主節點。我們例子中的集群只有一個節點,所以它會充當主節點的角色。
做為用戶,我們能夠與集群中的任何節點通信,包括主節點。每一個節點都知道文檔存在於哪個節點上,它們可以轉發請求到相應的節點上。我們訪問的節點負責收集各節點返回的數據,最后一起返回給客戶端。這一切都由Elasticsearch處理。
集群健康
在Elasticsearch集群中可以監控統計很多信息,但是只有一個是最重要的:集群健康(cluster health
)。集群健康有三種狀態:green
、yellow
或red
,健康狀況在后面會有很多體現。
GET /_cluster/health
在一個沒有索引的空集群中運行如上查詢,將返回這些信息:
{
"cluster_name": "elasticsearch",
"status": "green",
"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
:不是所有的主要分片都可用。
添加索引
為了將數據添加到Elasticsearch,我們需要索引(index)——一個存儲關聯數據的地方。實際上,索引只是一個用來指向一個或多個分片(shards)的“邏輯命名空間(logical namespace)”.
一個分片(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>
}
- 集群的狀態現在是
yellow
- 我們的三個復制分片還沒有被分配到節點上
下面我們可以看下,在Kibana監控工具中查看具體情況,如下圖:
和上面分析的內容是一致的。
集群的健康狀態yellow
表示所有的主分片(primary shards)啟動並且正常運行了——集群已經可以正常處理任何請求——但是復制分片(replica shards)還沒有全部可用。事實上所有的三個復制分片現在都是unassigned
狀態——它們還未被分配給節點。在同一個節點上保存相同的數據副本是沒有必要的,如果這個節點故障了,那所有的數據副本也會丟失。
現在我們的集群已經功能完備,但是依舊存在因硬件故障而導致數據丟失的風險。
添加故障轉移
在單一節點上運行意味着有單點故障的風險——沒有數據備份。幸運的是,要防止單點故障,我們唯一需要做的就是啟動另一個節點。
具體啟動方式可以查看ElasticSearch 5學習(3)——單台服務器部署多個節點。
如果我們啟動了第二個節點,這個集群看起來就像下圖。雙節點集群——所有的主分片和復制分片都已分配:
第二個節點已經加入集群,三個復制分片(replica shards)也已經被分配了——分別對應三個主分片,這意味着在丟失任意一個節點的情況下依舊可以保證數據的完整性。
文檔的索引將首先被存儲在主分片中,然后並發復制到對應的復制節點上。這可以確保我們的數據在主節點和復制節點上都可以被檢索。
cluster-health
現在的狀態是green
,這意味着所有的6個分片(三個主分片和三個復制分片)都已可用:
{
"cluster_name": "elasticsearch",
"status": "green",
"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
}
集群的狀態是green
,我們的集群不僅是功能完備的,而且是高可用的。
同樣我們可以看下實際的操作結果:
橫向擴展
隨着應用需求的增長,我們該如何擴展?如果我們啟動第三個節點,我們的集群會重新組織自己,包含3個節點的集群——分片已經被重新分配以平衡負載:
Node 3包含了分別來自Node 1和Node 2的一個分片,這樣每個節點就有兩個分片,和之前相比少了一個,這意味着每個節點上的分片將獲得更多的硬件資源(CPU、RAM、I/O)。
分片本身就是一個完整的搜索引擎,它可以使用單一節點的所有資源。我們擁有6個分片(3個主分片和三個復制分片),最多可以擴展到6個節點,每個節點上有一個分片,每個分片可以100%使用這個節點的資源。
同樣我們可以看下實際的操作結果:
繼續擴展
如果我們要擴展到6個以上的節點,要怎么做?
主分片的數量在創建索引時已經確定。實際上,這個數量定義了能存儲到索引里數據的最大數量(實際的數量取決於你的數據、硬件和應用場景)。然而,主分片或者復制分片都可以處理讀請求——搜索或文檔檢索,所以數據的冗余越多,我們能處理的搜索吞吐量就越大。
復制分片的數量可以在運行中的集群中動態地變更,這允許我們可以根據需求擴大或者縮小規模。讓我們把復制分片的數量從原來的1增加到2:
PUT /blogs/_settings
{
"number_of_replicas" : 2
}
從圖中可以看出,blogs索引現在有9個分片:3個主分片和6個復制分片。這意味着我們能夠擴展到9個節點,再次變成每個節點一個分片。這樣使我們的搜索性能相比原始的三節點集群增加“三倍”。
實際操作也是同樣的效果:
注意:可以看到上面的“三倍”我們用加了引號,因為在同樣數量的節點上增加更多的復制分片並不一定提高性能,因為這樣做的話平均每個分片的所占有的硬件資源就減少了(大部分請求都聚集到了分片少的節點,導致一個節點吞吐量太大,反而降低性能),你需要增加硬件來提高吞吐量。所以說添加復制分片和添加節點,在保證成本的情況下,需要有一個平衡點。
不過這些額外的復制節點還是有另外一個好處,使我們有更多的冗余:通過以上對節點的設置,我們能夠承受兩個節點故障而不丟失數據。
總結
對於ES分布式集群如果對節點、分片的處理基本學習完畢,可以感受到ES分布式集群的自動化,對於用戶來說幾乎完全透明化。但是,一個分布式集群主要看它的高性能、高並發和高可用。上面的內容雖然體現了一些,但是還包括對故障的處理能力,在ElasticSearch 5學習(7)——分布式集群學習分享2和大家分享。
轉載請注明出處。
作者:wuxiwei
出處:http://www.cnblogs.com/wxw16/p/6188044.html