本文主要參考尚硅谷的資料,少部分自己原創(chuàng),有錯(cuò)誤之處請指出。
單節(jié)點(diǎn)集群
node-1001配置如下:
# 集群名稱,節(jié)點(diǎn)之間要保持一致
cluster.name: my-elasticsearch
# 節(jié)點(diǎn)名稱,集群內(nèi)要唯一
node.name: node-1001
# 表示節(jié)點(diǎn)是否具有成為主節(jié)點(diǎn)的資格(此屬性的值為true,并不意味著這個(gè)節(jié)點(diǎn)就是主節(jié)點(diǎn))
node.master: true
# 表示節(jié)點(diǎn)是否存儲數(shù)據(jù)
node.data: true
# IP地址
network.host: localhost
# http端口
http.port: 1001
# tcp監(jiān)聽端口(節(jié)點(diǎn)間通信端口)
transport.tcp.port: 9301
# 該節(jié)點(diǎn)會與哪些候選地址進(jìn)行通信
#discovery.seed_hosts: ["localhost:9301", "localhost:9302", "localhost:9303"]
# 集群內(nèi)可以被選為主節(jié)點(diǎn)的節(jié)點(diǎn)列表
#cluster.initial_master_nodes: ["node-1001", "node-1002", "node-1003"]
# 是否支持跨域,默認(rèn)為false(因?yàn)槲覀兘酉聛硪褂胑lasticsearch-head插件連接es服務(wù))
http.cors.enabled: true
# 當(dāng)設(shè)置允許跨域,默認(rèn)為*,表示支持所有域名,如果我們只是允許某些網(wǎng)站能訪問,那么可以使用正則表達(dá)式。比如只允許本地地址。 /https?:\/\/localhost(:[0-9]+)?/
http.cors.allow-origin: "*"
坑1:如果之前啟動過此 ES 服務(wù),需要刪除 data文件夾以及l(fā)ogs里面的所有日志,否則可能配置失效
坑2:discovery.seed_hosts以及cluster.initial_master_nodes不需要配置,否則訪問此 ES 服務(wù)會報(bào)錯(cuò)找不到主節(jié)點(diǎn),其實(shí)和坑3的出現(xiàn)是一個(gè)原因。
我們創(chuàng)建名為 user 的索引,為了演示目的,我們將分配3個(gè)主分片和一份副本(每個(gè)主分片擁有一個(gè)副本份片)
{
"settings" : {
"number_of_shards" : 3,
"number_of_replicas" : 1
}
}
我們的集群現(xiàn)在是擁有一個(gè)索引的單節(jié)點(diǎn)集群。所有 3 個(gè)主分片都被分配在 node-1。
通過 elasticsearch-head 插件查看集群情況
可以看到,三個(gè)副本分片都沒有被分配到任何節(jié)點(diǎn)。在同一個(gè)節(jié)點(diǎn)上即保存原始數(shù)據(jù)又保存副本是沒有意義的,因?yàn)橐坏┦チ四莻€(gè)節(jié)點(diǎn),我們也將丟失該節(jié)點(diǎn)上的所有副本數(shù)據(jù)。
故障轉(zhuǎn)移
當(dāng)集群中只有一個(gè)節(jié)點(diǎn)在運(yùn)行時(shí),意味著會有一個(gè)單點(diǎn)故障問題——沒有冗余。幸運(yùn)的是,我們只需要再啟動一個(gè)節(jié)點(diǎn)即可防止數(shù)據(jù)丟失。當(dāng)你在同一臺機(jī)器上啟動了第二個(gè)節(jié)點(diǎn)時(shí),只要它和第一個(gè)節(jié)點(diǎn)有同樣的 cluster.name 配置,它就會自動發(fā)現(xiàn)集群并加入其中。但是在不同機(jī)器上啟動節(jié)點(diǎn)的時(shí)候,為了加入到統(tǒng)一集群,你需要配置一個(gè)可連接到的單播主機(jī)列表。之所以配置為使用單播發(fā)現(xiàn),以防止節(jié)點(diǎn)無意中加入集群。
如果啟動了兩個(gè)節(jié)點(diǎn),我們的集群將會擁有兩個(gè)節(jié)點(diǎn)的集群:所有主分片和副本分片都被分配。
node-1002配置如下:
# 集群名稱,節(jié)點(diǎn)之間要保持一致
cluster.name: my-elasticsearch
# 節(jié)點(diǎn)名稱,集群內(nèi)要唯一
node.name: node-1002
# 表示節(jié)點(diǎn)是否具有成為主節(jié)點(diǎn)的資格(此屬性的值為true,并不意味著這個(gè)節(jié)點(diǎn)就是主節(jié)點(diǎn))
node.master: true
# 表示節(jié)點(diǎn)是否存儲數(shù)據(jù)
node.data: true
# IP地址
network.host: localhost
# http端口
http.port: 1002
# tcp監(jiān)聽端口(節(jié)點(diǎn)間通信端口)
transport.tcp.port: 9302
# 該節(jié)點(diǎn)會與哪些候選地址進(jìn)行通信
discovery.seed_hosts: ["localhost:9301"]
# 集群內(nèi)可以被選為主節(jié)點(diǎn)的節(jié)點(diǎn)列表
#cluster.initial_master_nodes: ["node-1001", "node-1002", "node-1003"]
# 是否支持跨域,默認(rèn)為false(因?yàn)槲覀兘酉聛硪褂胑lasticsearch-head插件連接es服務(wù))
http.cors.enabled: true
# 當(dāng)設(shè)置允許跨域,默認(rèn)為*,表示支持所有域名,如果我們只是允許某些網(wǎng)站能訪問,那么可以使用正則表達(dá)式。比如只允許本地地址。 /https?:\/\/localhost(:[0-9]+)?/
http.cors.allow-origin: "*"
通過 elasticsearch-head 插件查看集群情況
水平擴(kuò)容
怎樣為我們的正在增長中的應(yīng)用程序按需擴(kuò)容呢?當(dāng)啟動了第三個(gè)節(jié)點(diǎn),我們的集群會擁有三個(gè)節(jié)點(diǎn)的集群:為了分散負(fù)載而對分片進(jìn)行重新分配。
node-1003配置如下:
# 集群名稱,節(jié)點(diǎn)之間要保持一致
cluster.name: my-elasticsearch
# 節(jié)點(diǎn)名稱,集群內(nèi)要唯一
node.name: node-1003
# 表示節(jié)點(diǎn)是否具有成為主節(jié)點(diǎn)的資格(此屬性的值為true,并不意味著這個(gè)節(jié)點(diǎn)就是主節(jié)點(diǎn))
node.master: true
# 表示節(jié)點(diǎn)是否存儲數(shù)據(jù)
node.data: true
# IP地址
network.host: localhost
# http端口
http.port: 1003
# tcp監(jiān)聽端口(節(jié)點(diǎn)間通信端口)
transport.tcp.port: 9303
# 該節(jié)點(diǎn)會與哪些候選地址進(jìn)行通信
discovery.seed_hosts: ["localhost:9301", "localhost:9302"]
# 集群內(nèi)可以被選為主節(jié)點(diǎn)的節(jié)點(diǎn)列表
# cluster.initial_master_nodes: ["node-1001", "node-1002", "node-1003"]
# 是否支持跨域,默認(rèn)為false(因?yàn)槲覀兘酉聛硪褂胑lasticsearch-head插件連接es服務(wù))
http.cors.enabled: true
# 當(dāng)設(shè)置允許跨域,默認(rèn)為*,表示支持所有域名,如果我們只是允許某些網(wǎng)站能訪問,那么可以使用正則表達(dá)式。比如只允許本地地址。 /https?:\/\/localhost(:[0-9]+)?/
http.cors.allow-origin: "*"
通過 elasticsearch-head 插件查看集群情況:
Node1 和 Node2 上各有一個(gè)分片被遷移到了新的 Node3 節(jié)點(diǎn),現(xiàn)在每個(gè)結(jié)點(diǎn)上都擁有2個(gè)分片,而不是之前的3個(gè)。這表示每個(gè)節(jié)點(diǎn)的硬件資源(CPU,RAM,I/O)將被更少的分片所共享,每個(gè)分片的性能將會得到提升。
分片是一個(gè)功能完善的搜索引擎,它擁有使用一個(gè)節(jié)點(diǎn)上所有資源的能力。我們這個(gè)擁有6個(gè)分片(3主3副)的索引可以擴(kuò)容到6個(gè)節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)上存在一個(gè)分片,并且每個(gè)分片擁有所在節(jié)點(diǎn)的全部資源。
但是如果我們想要擴(kuò)容超過6個(gè)節(jié)點(diǎn)怎么辦?
主分片的數(shù)目在索引創(chuàng)建時(shí)就已經(jīng)確定了下來。實(shí)際上,這個(gè)數(shù)目定義了這個(gè)索引能夠存儲的最大數(shù)據(jù)量。(實(shí)際大小取決于你的數(shù)據(jù)、硬件和使用場景。)但是,讀操作和返回?cái)?shù)據(jù)可以同時(shí)被主分片或副本分片所處理,所以當(dāng)你擁有越多的副本分片時(shí),也將擁有越高的吞吐量。
在運(yùn)行中的集群上是可以動態(tài)調(diào)整副本分片數(shù)目的,我們可以按需伸縮群。讓我們把副本數(shù)從默認(rèn)的 1 增加到 2
{
"number_of_replicas": 2
}
user索引現(xiàn)在擁有9個(gè)分片:3主6副。這意味著我們可以將集群擴(kuò)容到9個(gè)節(jié)點(diǎn)每個(gè)節(jié)點(diǎn)上一個(gè)分片。相比原來 3 個(gè)節(jié)點(diǎn)時(shí),集群搜索性能可以提升 3 倍
通過 elasticsearch-head 插件查看集群情況:
當(dāng)然,如果只是在相同節(jié)點(diǎn)數(shù)據(jù)的集群上增加更多的副本并不能提高性能,因?yàn)槊總€(gè)分片從節(jié)點(diǎn)上獲得的資源會變少。你需要增加更多的硬件資源來提升吞吐量。
但是更多的副本分片數(shù)提高了數(shù)據(jù)冗余量:按照上面節(jié)點(diǎn)配置,我們可以在失去 2 個(gè)節(jié)點(diǎn)的情況下不丟失任何數(shù)據(jù)。
應(yīng)對故障
我們關(guān)閉第一個(gè)節(jié)點(diǎn),這時(shí)集群的狀態(tài)為:關(guān)閉了一個(gè)節(jié)點(diǎn)后的集群。
我們關(guān)閉的節(jié)點(diǎn)是一個(gè)主節(jié)點(diǎn)。而集群必須擁有一個(gè)主節(jié)點(diǎn)來保證正常工作,所以發(fā)生的第一件事情就是選舉集群的主節(jié)點(diǎn):node-1002。在我們關(guān)閉 Node-1001 的同時(shí)也失去了主分片2,并且在缺失主分片的時(shí)候索引也不能正常工作。如果此時(shí)來檢查集群的狀況,我們看到的狀態(tài)將會為red:不是所有主分片都在正常工作。
幸運(yùn)的是,在其他節(jié)點(diǎn)上存在著這個(gè)主分片的完整副本,所以新的主節(jié)點(diǎn)立即將這些分片在node-1002和node-1003上對應(yīng)的副本分片提升為主分片,此時(shí)集群的狀態(tài)將會為yellow。這個(gè)提升主分片的過程是瞬間發(fā)生的,如同按下一個(gè)開關(guān)一般。
為什么我們集群狀態(tài)是 yellow 而不是 green 呢?
雖然我們擁有所有的三個(gè)主分片,但是同時(shí)設(shè)置了每個(gè)主分片需要對應(yīng) 2 份副本分片,而此時(shí)只存在一份副本分片。所以集群不能為 green 的狀態(tài)。
坑3:當(dāng)你關(guān)閉了兩個(gè)節(jié)點(diǎn)的時(shí)候,第三個(gè)節(jié)點(diǎn)是無法操作訪問的,這里涉及到另外一個(gè)知識點(diǎn):discovery.zen.minimum_master_nodes,感興趣的朋友可以再研究一下。
如果我們重新啟動node-1001,集群可以將缺失的副本分片再次進(jìn)行分配,那么集群的狀態(tài)也將恢復(fù)成之前的狀態(tài)。如果node-1001依然擁有著之前的分片,它將嘗試去重用它們,同時(shí)僅從主分片復(fù)制發(fā)生了修改的數(shù)據(jù)文件。和之前的集群相比,只是 master 節(jié)點(diǎn)切換了。
注意:重啟node-1001的之前添加配置:discovery.seed_hosts: [“l(fā)ocalhost:9302”, “l(fā)ocalhost:9303”],用來發(fā)現(xiàn)node-1002和node-1003節(jié)點(diǎn)
路由計(jì)算
當(dāng)索引一個(gè)文檔的時(shí)候,文檔會被存儲到一個(gè)主分片中。Elasticsearch 如何知道一個(gè)文檔應(yīng)該存放到哪個(gè)分片中呢?當(dāng)我們創(chuàng)建文檔時(shí),它如何決定這個(gè)文檔應(yīng)該被存放在分片 1 還是分片 2 中呢?首先這肯定不是隨機(jī)的,否則將來要獲取文檔的時(shí)候我們就不知道從何處尋找了。實(shí)際上,這個(gè)過程是根據(jù)下面這個(gè)公式?jīng)Q定的:
分片 = hash(routing) % 主分片數(shù)量
routing 是一個(gè)可變值,默認(rèn)是文檔的 _id,也可以設(shè)置成一個(gè)自定義值。routing 通過 hash 函數(shù)生成一個(gè)數(shù)字,然后這個(gè)數(shù)字再除以主分片的數(shù)量后得到余數(shù)。這個(gè)分布在 0 到 主分片數(shù)量 -1 之間的余數(shù),就是我們所尋求的文檔所在分片的位置。
這就解釋了為什么我們在創(chuàng)建索引的時(shí)候就確定好主分片的數(shù)量,并且永遠(yuǎn)不會改變這個(gè)數(shù)量:因?yàn)閿?shù)量變化了,那么之前路由的值會無效,文檔也再也找不到了。文章來源:http://www.zghlxwxcb.cn/news/detail-494415.html
所有的文檔API(get、index、delete、bulk、update以及mget)都接受一個(gè)叫做 routing 的路由參數(shù),通過這個(gè)參數(shù)我們可以自定義文檔到分片的映射。一個(gè)自定義的路由參數(shù)可以用來確保所有相關(guān)的文檔(例如:所有屬于同一個(gè)用戶的文檔)一一都被存儲到同一個(gè)分片中。文章來源地址http://www.zghlxwxcb.cn/news/detail-494415.html
到了這里,關(guān)于【ES】分布式集群的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!