發現方式
Zen discovery是內建的、默認的、用於Elasticsearch的發現模塊。它提供了單播和基於文件的發現,可以通過插件擴展到支持雲環境和其他形式的發現。
Zen Discovery 是與其他模塊集成的,例如,節點之間的所有通信都使用 transport 模塊完成。某個節點通過 發現機制 找到其他節點是使用 Ping 的方式實現的。
Zen Discovery 使用種子節點(seed nodes)列表來開始發現過程。在啟動時,或者在選舉新主節點的時候,Elasticsearch 會嘗試連接到其列表中的每個種子節點,並與他們進行類似'閑聊'的對話,以查找其他節點並構建集群的完整成員圖。
默認情況下,有兩種方法可用於配置種子節點列表:單播和基於文件。建議種子節點列表主要由集群中那些 Master-eligible 的節點組成。
Master-eligible:
node.master
設置為true
(默認)的節點,使其有資格被選為控制集群的主節點。
單播
單播發現 配置靜態主機列表以用作種子節點。 可以將這些主機指定為 主機名 或 IP地址。 指定為主機名的主機在每輪 ping 操作期間解析為 IP 地址。 請注意,如果您處於 DNS 解析隨時間變化的環境中,則可能需要調整 JVM安全設置。
可以在 elasticsearch.yml 配置文件中使用discovery.zen.ping.unicast.hosts
靜態設置設置主機列表。
discovery.zen.ping.unicast.hosts: ["host1", "host2"]
具體的值是一個主機數組或逗號分隔的字符串。每個值應采用host:port
或host
的形式(其中port默認為設置transport.profiles.default.port,如果未設置則返回transport.tcp.port)。 請注意,必須將IPv6主機置於括號內。 此設置的默認值為127.0.0.1,[:: 1]。
另外,discovery.zen.ping.unicast.resolve_timeout
配置在每輪ping操作中等待DNS查找的時間。需要指定時間單位,默認為5秒。
單播發現(unicast discovery)應用 transport 模塊實現發現(discovery)。
基於文件
除了靜態discovery.zen.ping.unicast.hosts
設置提供的主機之外,還可以通過外部文件提供主機列表。Elasticsearch在更改時會重新加載此文件,以便種子節點列表可以動態更改,而無需重新啟動每個節點。例如,這為在Docker容器中運行的Elasticsearch實例提供了一種方便的機制,可以動態提供一個IP地址列表,以便在節點啟動時無法知道這些IP地址時連接到Zen discovery。
要啟用基於文件的發現,請file按如下方式配置hosts提供程序:
discovery.zen.hosts_provider:file
然后以$ES_PATH_CONF/unicast_hosts.txt
下面描述的格式創建文件。每當對unicast_hosts.txt
文件進行更改時,Elasticsearch都會選擇新的更改,並使用新的主機列表。
請注意,基於文件的發現插件會增強單播主機列表 elasticsearch.yml
:如果存在有效的單播主機條目, discovery.zen.ping.unicast.hosts
則除了提供的那些之外,還將使用它們 unicast_hosts.txt。
該discovery.zen.ping.unicast.resolve_timeout
設置還適用於通過基於文件的發現由地址指定的節點的DNS查找。同樣需要指定時間單位,默認為5秒。
該文件的格式是每行指定一個節點條目。每個節點條目由主機(主機名或IP地址)和可選的傳輸端口號組成。如果指定了端口號,必須在主機(在同一行)之后使用“:”分割。如果未指定端口號,則使用默認值9300。
例如,這是 unicast_hosts.txt 具有四個參與單播發現的節點的集群的示例,其中一些節點未在默認端口上運行:
10.10.10.5
10.10.10.6:9305
10.10.10.5:10005
# an IPv6 address
[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:9301
允許使用主機名而不是IP地址(類似於 discovery.zen.ping.unicast.hosts
)。必須在括號中指定IPv6地址,並在括號后面添加端口。
也可以為此文件添加注釋,所有注釋必須在每行的開頭顯示_#_(即注釋不能在一行中間開始)。
選舉主節點
作為 ping 過程的一部分,一個集群的主節點需要是被選舉或者加入進來的(即選舉主節點也會執行ping,其他的操作也會執行ping)。這個過程是自動執行的。通過配置discovery.zen.ping_timeout
來控制節點加入某個集群或者開始選舉的響應時間(默認3s)。
在這段時間內有3個 ping 會發出。如果超時,重新啟動 ping 程序。在網絡緩慢時,3秒時間可能不夠,這種情況下,需要慎重增加超時時間,增加超時時間會減慢選舉進程。
一旦節點決定加入一個存在的集群,它會發出一個加入請求給主節點,這個請求的超時時間由discovery.zen.join_time
控制,默認是 ping 超時時間(discovery.zen.ping_timeout
)的20倍。
當主節點停止或者出現問題,集群中的節點會重新 ping 並選舉一個新節點。有時一個節點也許會錯誤的認為主節點已死,所以這種 ping 操作也可以作為部分網絡故障的保護性措施。在這種情況下,節點將只從其他節點監聽有關當前活動主節點的信息。
如果discovery.zen.master_election.ignore_non_master_pings
設置為true
時(默認值為false
),node.master
為false
的節點不參加主節點的選舉,同時選票也不包含這種節點。
通過設置node.master
為false
,可以將節點設置為非備選主節點,永遠沒有機會成為主節點。
discovery.zen.minimum_master_nodes
設置了最少有多少個備選主節點參加選舉,同時也設置了一個主節點需要控制最少多少個備選主節點才能繼續保持主節點身份。如果控制的備選主節點少於discovery.zen.minimum_master_nodes
個,那么當前主節點下台,重新開始選舉。
discovery.zen.minimum_master_nodes
必須設置一個恰當的備選主節點值(quonum
,一般設置 為備選主節點數/2+1),盡量避免只有兩個備選主節點,因為兩個備選主節點quonum
應該為2,那么如果一個節點出現問題,另一個節點的同意人數最多只能為1,永遠也不能選舉出新的主節點,這時就發生了腦裂現象。
集群故障檢測
有兩個故障檢測進程在集群的生命周期中一直運行。一個是主節點的,ping集群中所有的其他節點,檢查他們是否活着。另一種是每個節點都ping主節點,確認主節點是否仍在運行或者是否需要重新啟動選舉程序。
使用discovery.zen.fd
前綴設置來控制故障檢測過程,配置如下:
配置 | 描述 |
---|---|
discovery.zen.fd.ping_interval | 節點多久ping一次,默認1s |
discovery.zen.fd.ping_timeout | 等待響應時間,默認30s |
discovery.zen.fd.ping_retries | 失敗或超時后重試的次數,默認3 |
集群狀態更新
主節點是唯一一個能夠更新集群狀態的節點。主節點一次處理一個群集狀態更新,應用所需的更改並將更新的群集狀態發布到群集中的所有其他節點。當其他節點接收到狀態時,先確認收到消息,但是不應用最新狀態。如果主節點在規定時間(discovery.zen.commit_timeout
,默認30s)內沒有收到大多數節點(discovery.zen.minimum_master_nodes
)的確認,集群狀態更新不被通過。
一旦足夠的節點響應了更新的消息,新的集群狀態(cluster state)被提交並且會發送一條消息給所有的節點。這些節點開始在內部應用新的集群狀態。在繼續處理隊列中的下一個更新之前,主節點等待所有節點響應,直到超時(discovery.zen.publish_timeout
,默認設置為30秒)。上述兩個超時設置都可以通過集群更新設置api動態更改。
No master block
對於一個可以正常充分運作的集群來說,必須擁有一個活着的主節點和正常數量(discovery.zen.minimum_master_nodes
個)活躍的備選主節點。discovery.zen.no_master_block
設置了沒有主節點時限制的操作。它又兩個可選參數
all
:所有操作均不可做,讀寫、包括集群狀態的讀寫api,例如獲得索引配置(index settings),putMapping,和集群狀態(cluster state)apiwrite
:默認為write,寫操作被拒絕執行,基於最后一次已知的正常的集群狀態可讀,這也許會讀取到已過時的數據。
discovery.zen.no_master_block
,對於節點相關的基本api,這個參數是無效的,如集群統計信息(cluster stats),節點信息(node info),節點統計信息(node stats)。對這些api的請求不會被阻止,並且可以在任何可用節點上運行。