這個問題困擾過我一段時間,它其實是說未能選舉出一個主節點,最后在官網教程中找到答案。
首先是啟動(鏈接):
總結下來就是,如果ES集群是第一次啟動,那么需要 cluster.initial_master_nodes 配置指定一個master類型的節點列表來進行選舉一個主節點.
另外,已經加入集群的幾點信息保存在data目錄下,以供下次啟動使用,這樣也就是說cluster.initial_master_nodes就不在起作用了。
接着是選舉配置(鏈接)
大致意思是說,每個ES集群都維護一個選舉配置集合(Voting Configurations),這個選舉集合由可以選舉為主節點的master類型節點組成。
它除了提供選舉功能,還決定者集群的狀態,當選舉配置集合中超過一半的節點存活時,集群才提供服務(也就是過半原則,通常集群解決腦裂問題都是采用這種方式)
我們可以通過ES提供的API接口來查看選舉配置集合中有哪些節點:
curl -X GET "http://localhost:9200/_cluster/state?filter_path=metadata.cluster_coordination.last_committed_config&pretty"
基於這兩點,如果是第一次啟動集群,往往是因為沒有配置 cluster.initial_master_nodes 參數導致的。如果不是第一次啟動,也就是說集群啟動的節點不滿足過半原則,不能選舉出主節點,這樣只需要將過半的節點啟動就可以了。
但是這便有了另一個問題,但如果不願意啟動多個節點,也就是要將多節點集群降級,也就是如何減少集群中的節點數呢?
發現很多推薦做法是清空data目錄,確實這樣相當於重新啟動而創建一個全新的集群,可以解決問題,但是結果是導致所有的數據丟失。后來在官網上也找到了解決辦法(鏈接):
大致說了3點重要信息: 1、一次性刪除節點不要太多,比如我們原來集群選舉有7個master類型的節點,如果要縮減到只有3個節點的集群,如果直接關掉4個節點,會發現集群掛了,因為不滿足過半原則,同時拋出警告:master not discovered or elected yet。 2、建議一個個的刪除節點,然后留給集群足夠的時間,讓它自動調整Voting Configurations中的配置 3、如果只剩下最后兩個節點了,那么都不能刪除,如果要刪除,就要配置Voting configuration exclusions來實現
事實上,ES有個cluster.auto_shrink_voting_configuration配置,默認是true,表示當節點掛掉之后是否調整Voting Configurations,也就是說自動將掛掉的節點從Voting Configurations中剔除,這樣也會影響過半原則的判定,比如本來Voting Configurations中有5個節點,它最多可容忍2個節點丟失,如果停了2個節點,那么等ES自動調整Voting Configurations后,集群中還有3個節點,這也就是說還能容忍一個節點丟失,所以我們可以一台一台的停止一些節點,讓ES自動從Voting Configurations中剔除掉停止了的節點(切記不要一次停止過多節點,否則可能在Voting Configurations自動調整前而導致不滿足過半原則而導致集群停止服務),但是需要注意的是,它旨在master節點大於等於3時有效,也就是說Voting Configurations中至少會保存3個master類型的節點信息。
可能這與上面的描述有點差入,自動調整只能將Voting Configurations中的節點減少到3個,但是當Voting Configurations中有3個master類型節點時,雖然Voting Configurations不會再自動減少節點數,當有一個節點掛掉時,集群還是可以提供服務的,因為它滿足過半原則,所以可能作者認為2個和3個節點是一樣的吧。
換句話說,對於只有2個或者3個節點的集群,我們就要結合Voting configuration exclusions還實現了。
舉個例子,假如現在我們有3台服務器的集群(192.168.209.128,192.168.209.129,192.168.209.130),各節點配置如下:
192.168.209.128
# 節點名稱 node.name: node-128 # 節點列表 discovery.seed_hosts: ["192.168.209.128", "192.168.209.129", "192.168.209.130"] # 初始化時master節點的選舉列表 cluster.initial_master_nodes: [ "node-128", "node-129", "node-130" ] # 集群名稱 cluster.name: cluster-name
192.168.209.129
# 節點名稱 node.name: node-129 # 節點列表 discovery.seed_hosts: ["192.168.209.128", "192.168.209.129", "192.168.209.130"] # 初始化時master節點的選舉列表 #cluster.initial_master_nodes: [ "node-128", "node-129", "node-130" ] # 集群名稱 cluster.name: cluster-name
192.168.209.130
# 節點名稱 node.name: node-130 # 節點列表 discovery.seed_hosts: ["192.168.209.128", "192.168.209.129", "192.168.209.130"] # 初始化時master節點的選舉列表 #cluster.initial_master_nodes: [ "node-128", "node-129", "node-130" ] # 集群名稱 cluster.name: cluster-name
現在要將它降為單節點集群,如果我們直接關閉兩個節點,那么集群因為不滿足過半原則而無法提供服務。
Voting configuration exclusions是一個類似於Voting configuration的集合,只是處於這個排除列表中的節點不會被選舉,,等同於從選舉集合中刪除了(鏈接):
# 查看排除列表 curl -X GET "http://localhost:9200/_cluster/state?filter_path=metadata.cluster_coordination.voting_config_exclusions&pretty" # 添加排除,也就是從配置集合中刪除,可以使用節點Id(node_ids)或者節點名稱(node_names)來排除,如果執行失敗,加上參數 wait_for_removal=false 試試 curl -X POST "http://localhost:9200/_cluster/voting_config_exclusions?node_names=<node_names>" curl -X POST "http://localhost:9200/_cluster/voting_config_exclusions?node_ids=<node_ids>" # 清空排除列表 curl -X DELETE "http://localhost:9200/_cluster/voting_config_exclusions"
如果執行結果返回:timed out waiting for removal of nodes; if nodes should not be removed, set waitForRemoval to false
可以在執行時在url中添加參數 wait_for_removal=false,比如我這里因為要保留192.168.209.128,所在在192.168.209.128上執行:
# 添加到排除列表 curl -X POST "http://192.168.209.128:9200/_cluster/voting_config_exclusions?node_names=node-129,node-130" # 清空排除列表 curl -X DELETE "http://192.168.209.128:9200/_cluster/voting_config_exclusions?wait_for_removal=false"
上面我這里將node-129,node-130加入到排除列表之后,node-128就會被選舉為主節點,這個時候就可以將node-129和node-130停掉,而后node-128還是正常提供服務的
注:操作完成之后,記得清空Voting configuration exclusions
這樣,我們就從一個3個節點的集群降級為單節點集群了,之后只啟動node-128節點也就是單節點集群了。