[Elasticsearch] 叢集的工作原理 - 第一部分
ES就是為高可用和可擴充套件而生的。擴充套件可以通過購置效能更強的伺服器(垂直擴充套件或者向上擴充套件,Vertical Scale / Scaling Up),亦或是通過購置更多的伺服器(水平擴充套件或者向外)擴充套件,水平縮放/縮小)來完成。
儘管ES能夠利用更強勁的硬體,垂直擴充套件畢竟還是有它的極限。真正的可擴充套件性來自於水平擴充套件 - 通過向叢集中新增更多的節點來分佈負載,增加可靠性。
在大多數資料庫中,水平擴充套件通常都需要你對應用進行一次大的重構來利用更多的節點相反,ES天生就是分散式的:它知道如何管理多個節點來完成擴充套件和實現高可用性。這也意味著你的應用不需要在乎這一點。
在本章中,我們會介紹如何建立叢集(叢集),節點(節點)和分片(碎片)來根據你的需求完成擴充套件,同時也能夠保證即使發生硬體故障你的資料也會安然無恙。
一個空的叢集
如果我們啟動了一個沒有任何資料和索引的節點(節點),我們的叢集(Cluster)的看起來就像下面這樣:
一個節點會執行一個ES的例項,而叢集一個所有遊戲則會擁有相同cluster.name
的一個或者多個節點,這些節點共同工作來完成資料共享和負載分擔。隨著節點被新增到叢集,或者從叢集中被刪除,叢集會通過自身調節來將資料均勻分佈。
叢集中的一個節點會被選為主節點(主節點),它負責管理整個叢集的變化,如建立或者刪除一個索引(Index),向叢集中新增或者刪除節點。主節點並不需要參與到文件級別的變化或者搜尋中,這意味著雖然只有一個主節點,但它並不會隨著流量的增加而成為瓶頸。任何節點都可以成為主節點。在我們的例子中只有一個節點,所以它就承擔了主節點的功能。
對於使用者,可以和叢集中的任意節點進行通訊,包括主節點。每個節點都知道每份文件的存放位置,並且能夠將請求轉發到持有所需資料的節點。使用者通訊的節點會負責將需要的資料從各個節點收集起來,然後返回給使用者。以上整個過程都會由ES透明地進行管理。
叢集健康指標(Cluster Health)
在一個ES叢集中,有很多可以被監測的統計資料,但是其中最重要的是叢集健康指標,它會以綠色,黃色和紅色來報告叢集的健康狀態。
-
# Retrieve the cluster health
-
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
-
}
狀態欄位提供的值反應了叢集整體的健康程度它的值的意義如下:
- green:所有的主分片(Primary Shard)和副本分片(Replica Shard)都處於活動狀態
- 黃:所有的主分片都處於活動狀態,但是並不是所有的副本分片都處於活躍狀態
- 紅:不是所有的主分片都處於活動狀態
在本章剩下的部分中,我們會解釋什麼是主分片和副本分片,以及以上的幾種顏色狀態資訊所帶來的實際影響。
新增索引
為了向ES中新增資料,我們需要一個索引(Index) - 它是一個用來儲存相關資料的地方。實際上,一個索引實際上只是一個“邏輯名稱空間(Logical Namespace)”,用來指向一個或者多個物理分片(Physical Shard)。
一個分片就是底層的“工作單元(工人單位)”,它擁有索引中所有資料的一部分。在分片一章中,會對分片的工作方式進行詳細說明,但是就現在然言,我們只需要知道一個分片就是一個Lucene的的例項,一個分片本身就是一個完整的搜尋引擎。我們的文件會被儲存和索引在分片中,但是應用是不會直接和分片進行互動的。相反地,應用和索引進行互動。
ES通過分片將資料分佈在叢集中。可以將分片想象成資料的容器。文件會被儲存在分片中,而分片則會被分配到叢集中的節點中。隨著叢集的擴大和雖小,ES會自動地將分片在節點之間進行遷移,以保證叢集能夠保持一種平衡。
一個分片可以是主分片(Primary Shard)或者副本分片(Replica Shard)。索引中的每份文件都屬於一個主分片,所以主分片的數量就決定了你的索引能夠儲存的最大資料量。
儘管在理論上,一個主分片能夠容納的最大資料量並沒有限制,但是在實際生產中這個限制是存在的分片的最大空間完全取決於你的用例:硬體條件,文件的大小和複雜度,如何索引和查詢文件,以及期望的響應時間。
一個副本分片則只是一個主分片的拷貝。副本用來提供資料冗餘,用來保護資料在發生硬體故障是不會丟失,同時也能夠處理像搜尋和獲取文件這樣的讀請求。
主分片的數量在索引建立之初就會被確定下來,而副本分片的數量則可以在任何時候被更改。
讓我們在當前只有一個節點的叢集中建立一個新的部落格索引。預設情況下,索引會擁有5個主分片,但是為了演示,我們會讓索引有3個主分片和1個副本分片(每個主分片都有1個副本分片):
-
PUT /blogs
-
{
-
"settings" : {
-
"number_of_shards" : 3,
-
"number_of_replicas" : 1
-
}
-
}
此時我們的叢集就變成這樣了:
這個時候我們如果檢查叢集的健康狀態,會得到如下的結果:
-
{
-
"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
-
}
叢集的健康狀態變成了黃色,同時響應中還說明了有3個未被分配的分片。
黃色說明了所有的主分片都正在正常執行,處於活動狀態 - 叢集現在能夠成功處理來自外部的請求 - 但是並不是所有的副本分片都處於活動狀態。實際上,所有的3個副本分片目前都處於“未分配”的狀態 - 它們不存在於任何節點上。這是因為將相同資料的拷貝存放在同一節點上是沒有意義的。如果我們失去了該節點,那麼我們會失去所有資料和它們的拷貝。
因此當前我們的叢集能夠正常工作,只不過抵禦不了硬體故障帶來的風險。