es為分布式而生,而且它的設(shè)計隱藏了分布式本身的復(fù)雜性。es在分布式概念上做了很大程度上的透明話,在教程中你不需要知道任何關(guān)于分布式系統(tǒng),分片、集群發(fā)現(xiàn)或者其他大量的分布式概念。所有的教程你既可以運行在你的筆記本上,也可以運行在擁有100個節(jié)點上的集群上,其工作方式是一樣的。
es致力于隱藏分布式系統(tǒng)的復(fù)雜性。以下這些操作都是在底層自動完成的:
將你的文檔分區(qū)到不同的容器或者分片(shards)中,它們可以存在于一個或多個節(jié)點中。
將分片均勻的分配到各個節(jié)點,對索引和搜索做負載均衡。
冗余每一個分片,防止硬件故障造成的數(shù)據(jù)丟失。
將集群中任意一個節(jié)點上的請求路由到相應(yīng)數(shù)據(jù)所在的節(jié)點。
無論是增加節(jié)點,還是移除節(jié)點,分片都可以做到無縫的擴展和遷移。
es用于構(gòu)建高可用和可擴展的系統(tǒng)。擴展的方式可以是購買更好的服務(wù)器(縱向擴展)或者購買更多的服務(wù)器(橫向擴展)。es雖然能從更強大的硬件中獲得更好的性能,但是縱向有他的局限性。真正的擴展應(yīng)該是橫向的。它通過增加節(jié)點來均攤負載和增加可靠性。
對于大多數(shù)數(shù)據(jù)庫而言,橫向擴展意味著你的程序?qū)⒆龇浅4蟮母膭硬拍芾眠@些新添加的設(shè)備。對比來說,es天生就是分布式的:它知道如何管理節(jié)點來提供高擴展和高可用。這意味著你的程序不需要關(guān)心這些。
一個節(jié)點(node)就是一個es實例,而一個集群(cluster)由一個或多個節(jié)點組成,他們具有相同的cluster.name,它們協(xié)同工作,分享數(shù)據(jù)和負載。當(dāng)加入新的節(jié)點或者刪除一個節(jié)點時,集群就會感知到并平衡數(shù)據(jù)。
集群中一個節(jié)點會被選舉為主節(jié)點(master),它將臨時管理集群級別的一些變化,例如新建或刪除索引,增加或移除節(jié)點等。主節(jié)點不參與文檔級別的的變更或搜索,這意味著在流量增長的時候,該主節(jié)點不會成為集群的瓶頸。任何節(jié)點都可以成為主節(jié)點。
作為用戶,我們能夠與集群中的任何節(jié)點通信,包括主節(jié)點。每一個節(jié)點都知道文檔存在于哪個節(jié)點上,它們可以轉(zhuǎn)發(fā)請求到相應(yīng)的節(jié)點上。我們訪問的節(jié)點負責(zé)收集各節(jié)點返回的數(shù)據(jù),最后一起返回給客戶端。這一切都是由es處理。
集群有一些健康狀態(tài):
green 所有主要分片和復(fù)制分片都可用
yellow 所有主要分片可用,但不是所有復(fù)制分片都可用
red 不是所有的主要分片都可用
為了將數(shù)據(jù)添加到es,我們需要索引(index)——一個存儲關(guān)聯(lián)數(shù)據(jù)的地方。實際上,索引只是一個用來指向一個或多個分片(shards)的邏輯命名空間。
一個分片(shard)是一個最小級別的“工作單元”,它只是保存了索引中所有數(shù)據(jù)的一部分。分片就是一個Lucene實例,并且它本身就是一個完整的搜索引擎。我們的文檔存儲在分片中,并且在分片中被索引,但是我們應(yīng)用程序不會直接與它們通信,取而代之的是,直接與索引通信。
分片是es在集群中分發(fā)數(shù)據(jù)的關(guān)鍵。把分片想象成數(shù)據(jù)的容器。文檔存儲在分片中,然后分片分配到你集群中的節(jié)點 上。當(dāng)你的集群擴容或縮小,es將會自動在你的節(jié)點間遷移分片,以使集群保持平衡。
分片可以是主分片(primary shard)或者是復(fù)制分片(replica shard)。你索引中的每個文檔 屬于一個單獨的主分片,所以主分片的數(shù)量決定了索引最多能存儲多少數(shù)據(jù)。
復(fù)制分片只是主分片的一個副本,它可以防止硬件故障導(dǎo)致的數(shù)據(jù)丟失,同時可以提供讀請求,比如搜索或者從別的shard取回文檔。當(dāng)索引創(chuàng)建完成時,主分片的數(shù)量就固定了,但是復(fù)制分片的數(shù)量可以隨時(動態(tài))調(diào)整。主分片或者復(fù)制分片都可以處理讀請求——搜索或文檔檢索,所以數(shù)據(jù)的冗余越多,我們能處理的搜索吞吐量就越大。