亚欧色一区w666天堂,色情一区二区三区免费看,少妇特黄A片一区二区三区,亚洲人成网站999久久久综合,国产av熟女一区二区三区

  • 發布文章
  • 消息中心
點贊
收藏
評論
分享
原創

Elasticsearch7.x無法選主問題

2023-10-30 09:20:20
52
0

Elasticsearch 7.x 選舉算法改為基于 Raft 的實現,與標準 Raft 相比,最大的區別是允許選民可以投多票,當產生多個主節點的時候,讓最后一個當選,這樣,可以更快地選出主節點。但是這種機制同樣也有缺點,就是會使競選過程比較激烈。特別是當集群節點數量比較多的時候,候選人反復競爭可能會持續很長時間

當遇到這種無法選主情況時,節點會有如下的日志:

master not discovered or elected yet, an election requires at least XX nodes with ids from [] which is a quorum; discovery will continue using [] from hosts providers and [] from last-known cluster state; node term 14, last-accepted version 71 in term 5

或者

failed to join{…}
CoordinationStateRejectedException: incoming term 4996 does not match current term

 

但是這些報錯和問題根因沒有啥關系,探測到的節點已經能夠達到 quorum,然后繼續discovery,讓人很費解。這時得把日志調到 DEBUG:

{
    "persistent": {
        "logger.org.elasticsearch.cluster.service.MasterService": "DEBUG",
        "logger.org.elasticsearch.cluster.coordination": "DEBUG"
    }
}

跟隨報錯日志”which is a quorum; discovery will“,從代碼一路跟過去,發現只有becomeCandidate的時候才會觸發,搜索 debug 日志”coordinator becoming CANDIDATE“,找到以下信息:

[2021-02-17110:47:07,331][DEBUG][o.e.c.c.Coordinator[OWER, lastKnownLeader was [Optional[<C02D36GlMD6R}{HgU8AzfASnqvSij cDe][C02D36G1MD6R] joinLeaderlnTerm:oordinator becoming CANDIDATEin term 2513 (was0vFg}{fw2V24P5Stmhl6pEBu3xxg}{127.0.0.1}{127.0.0.1:9314}{dilmrt}{ml-machine_memory=34359738368f ml-max_open_jobs=20, xpack-installed=truef transform.node=true}]]) [2021-02-17T10:47:07,368][DEBUG][o.e.d.PeerFinder	] [C02D36G1MD6R] Peer{transportAddress=[::1]:9301f discoveryNode=nullf peersRequestInFlight=false} connection failedo rg- elasticsea rch.t ranspo rt. Connect? ranspo rtException: [][[::!]:9301] connect_exception
    at org.elasticsearch.transport.TcpTransport$ChannelsConnectedListener-onFailure(TcpTransport.java:998)?[elasticsearch-7.7.0.jar:7.7.0]
    at ora.elasticsearch.action.ActionListener.XambdaitoBiConsumeriZCActionListener.iava:198) ~Felasticsearch-7.7.0.iar:7.7.01

 

注意他上一個狀態是FOLLOWER,在 Elasticsearch 的選舉狀態圖里,只有加入集群才會切換到FOLLOWER狀態。這說明有主節點被選出來了,繼續搜 ”coordinator becoming FOLLOWER “,可以找到他切換到FOLLOWER時Leader的源地址:

[2021-02-17T10:47:07,153][DEBUG][o.e.c.c.PublicationTransportHandler] [C02D36G1MD6R] received full cluster state version [93] with size [13793]
[2021-02-17710:47:07,177][DEBUG][o.e.c.c.Coordinator][C02D36G1MD6R] onFollowerCheckRequest:of [{C02D36GlMD6R}{HgU8AzfASnqv5ijcDe0vFg}{fw2V24P5Stmhl6pEBu3xxg}{127.0.0.1}{|127.0.0.JXdilmrt.machine_memory=34359738368, ml.max_open_jobs=20, xpack.installed=true, transform.node=true}] in term 2511 (was CANDIDATE, lastKnownLeader was [Optional.empty])

 

然后看一下 Leader 節點的日志,發現有:

elected-as-master (.. nodes joined) 以及
failing [elected-as-master

 

[2021-02-17Tll:33:40f305][WARN ][o.e.c-s.MasterService ] [C02D36G1MD6R] failing [elected—卜 elect leader, _BECOME_MASTER_TASK_, —FINISH-ELECTION」]: failed to commit cluster state version [103])rg.elasticsearch.cluster.coordination.FailedToCommitClusterStateException: publication failed
at org.elasticsearch.cluster.coordination.Coordinator$CoordinatorPublication$4.onFailure(Coordinator-java:1431) ~[elasticsearch-7.7.0.jar:7.7.0]
at org.elasticsearch.action.ActionRunnable.onFailure(ActionRunnable-java:88) ~[elasticsearch-7.7.0.jar:7.7.0]
at org.elasticsearch.common.util.concurrent.AbstractRunnable- run(AbstractRunnable-java:39) ~[elasticsearch-7.7.0.jar:7-7.0]
at org.elasticsearch.common.util.concurrent.EsExecutors$DirectExecutorService.execute(EsExecutors.java:225) ~[elasticsearch-7.7.0.jar:7.7.0]
at org.elasticsearch.common.util.concurrent.ListenableFuture.notifyListener(ListenableFuture.java:106) ^[elasticsearch-7.7.0.jar:7.7.0]
at org.elasticsearch.common.util.concurrent.ListenableFuture.addListener(ListenableFuture-java:68) ~[elasticsearch-7.7.0.jar:7.7.0]
at org.elasticsearch.cluster.coordination.Coordinator$CoordinatorPublication.onCompletion(Coordinator-java:1354) ~[elasticsearch-7.7.0.jar:7.7.0]
at org.elasticsearch.cluster.coordination.Publication.onPossibleCompletion(Publication.java:125) [elasticsearch-7.7.0-jar:7.7.0]
at org.elasticsearch.cluster.coordination.Publication.cancel(Publication.java:89) [elasticsearch-7.7.0.jar:7.7.0]
at org.elasticsearch.cluster.coordination.Coordinator.cancelActivePublication(Coordinator.java:1129) ~[elasticsearch-7.7.0.jar:7.7.0]
at org.elasticsearch.cluster.coordination.Coordinator.becomeCandidate(Coordinator-java:544) ~[elasticsearch-7.7.0.jar:7.7.0]
at org.elasticsearch.cluster.coordination.Coordinator-joinLeaderInTerm(Coordinator-java:457) [elasticsearch-7.7.0.jar:7.7.0]
at org.elasticsearch.cluster.coordination.JoinHelper.lambda$new$2(JoinHelper-java:141) [elasticsearch-7.7.0.jar:7.7.0]

 

 

可以看到節點起初被成功選為 Master,但是后來因為收到其他節點拉選票的RequestVote 請求(joinLeaderInTerm函數是對競選請求的處理)取消集群狀態的發布,切換到候選人狀態。如果他成功發布了集群狀態,新主就可以順利當選了。

我們再觀察候選人每次發起 RequestVote 的周期以及成功情況:

 

grep -E "starting election with|elected-as-master" logs/my-debug.log |less

發現他有時候甚至來不及被選為master,都沒有走到發布集群狀態的流程:

[2021-02-18T15:58:19f541][DEBUG][o.e.c.c-Coordinator][C02D36G1MD6R]starting election with StartJoinRequest{tenn=10424,node={C02D36GlMD6R}{ahl6F9fBQ06WQVQQ3s5i5w}{7ERiDnWHRD-akA9aCUL9wA}{127?0.0.1}{127?0.0.1:9316}{dilmrt}{ml.machine_memory=34359738368f xpack-installed=true, transform■node=true、ml■max_open_jobs=20}}
[2021-02-18T15:58:24f909][DEBUG][o.e.c.c-Coordinator][C02D36G1MD6R]starting election with StartJoinRequest{term=10433/node={C02D36GlMD6R}{ahl6F9fBQ06WQVQQ3s5i5w}{7ERiDnWHRD-akA9aCUL9wA}{127.0.0.1}{127.0.0.1:9316}{dilmrt}{ml.machine_memory=34359738368f xpack.installed=true, transform■node=true、ml■max_open_jobs=20}}
[2021-02-18T15:58:33f470][DEBUG][o.e.c.c.Coordinator][C02D36G1MD6R]starting election]with StartJoinRequest{tenn=10448,node={C02D36GlMD6R}{ahl6F9fBQ06WQVQQ3s5i5w}{7ERiDnWHRD-akA9aCUL9wA}{127?0.0.1}{127?0.0.1:9316}{dilmrt}{ml.machine_memory=34359738368f xpack-installed=true, transform■node=true、ml■max_open_jobs=20}}

 

 

而來不及被選為 master 的原因是被其他候選人拉選票的請求打斷:

 

[2021-02-18715:53:27,194][DEBUG][o.e.c.c-CoordinationState] [C02D36G1MD6R]handleStart Join:ignoring [StartJoinRequest{term=9854fnode={C02D36GlMD6R}{m47W97RlSKirn4cEHabkQw}{Tgn9Ag5wS0eAwPRO0cw-bA}{127.0.0.1}{127.0.0.l:9314}{dilmrt}{ml.machine_memory=34359738368f ml.max_open_jobs=20# xpack-installed=true, transform.node=true}}] as term provided is not greater than current term [9855]
[2021-02-18715:53:27,194][DEBUG][o-e-c.c.PreVoteCollector I [C02D36G1MD6R] accpeting prevote for PreVoteRequest{sourceNode={C02D36GlMD6R}{BFhjJetNRoqViiREg8mPsg}{0AAm8XblTGiCR5oXqTtoMg}{127.0.0.1}{127.0.0.1:9319}{dilmrt}{ml.machine_memory=34359738368f ml.max_open_jobs=20# xpack-installed=true, transform.node=true}f currentTerm=9854}
[2021-02-18715:53:27,194][DEBUG][o-e.c.c.PreVoteCollector ] [C02D36G1MD6R] accpeting prevote for PreVoteRequest{sourceNode={C02D36GlMD6R}{jFZFK70bQy6jJUtAdG58MQ}{zJ_Jmw5fSOujYUxUDsXBzwH127.0.0.1H127.0.0.1:9307}{dil mrt}{ml.machine_memory=34359738368f ml.max_open_jobs=20# xpack-installed=true, transform.node=true}, currentTerm=9852}
[2021-02-18715:53:27,194][DEBUG][o-e-c.c.PreVoteCollector ] [C02D36G1MD6R] accpeting prevote for PreVoteRequest{sourceNode={C02D36GlMD6R}{J2P_QC8dSGGp5C6OJJP5nw}{CJqGAk5WQH6_VZlHRA5zOA}{127.0.0.1}{127.0.0.1:9304}{dil mrt}{ml.machine_memory=34359738368f ml.max_open_jobs=20# xpack-installed=truef transform.node=true}f currentTerm=9853}
[2021-02-18715:53:27,195][DEBUG][o.e.c.c-CoordinationState] [C02D36G1MD6R]handle StartJoin7.0B0Bl}{127.0B0Bl:9313}{dilmrt}{ml.machine_memory=34359738368f ml■max_open_jobs=20, xpack-installed=true, transform.node=true}}:leaving term [9855] due to StartJoinRequest{term=9856fnode={C02D36GlMD6R}{5TeQB34ARHG2tHCb2DR7QQ}{Yul-rl3iS4SUMy5Vos9g5w}{12at org-elasticsearch.cluster.coordination.CoordinationState-at org.elasticsearch.cluster-coordination.Coordinationstate.handlestartJoin handleSta rtJoin
(CoordinationState-java:181)?[elasticsearch-7.7.0.jar:7.7.0-SNAPSHOT]
(CoordinationState■java:181)?[elasticsearch-7.7.0.jar:7.7.0-SNAPSHOT]
[2021-02-18715:53:27340][TRACE][o-e.c-c.PreVoteCollector ] [C02D36GlMD6R] updating with preVoteResponse=RreVoteResponse{currentTerm=9856f lastAcceptedTerm=8597f 'lastAcceptedVersion=371}f leader=null
     at org-elasticsearch.cluster.coordination.Coordinationstate.(Coordinationstate■java:181)?[elasticsearch-7.7.0.jar:7.7.0-SNAPSHOT]

[2021-02-18715:53:27,606][DEBUG][o-e.c.c-CoordinationState] [C02D36G1MD6R]:ignoring [StartJoinRequest{term=9854fnode={C02D36GlMD6R}{J2P_QC8dSGGp5C6OJJP5nw}{CJqGAk5WQH6_VZlHRA5zOA}{127.0.0.1}{127.0.0.l:9304}{dilmrt}{ml.machine_memory=34359738368f ml.max_open_jobs=20# xpack.inctalledWrue, transform.node=true}}] as term provided is not greater than current term [9856]
[2021-02-18115:53:27,633][DEBUG][o.e.c.c.Coordinator][C02D36G1MD6R] Itarting election with]StartJoinRequest{term=9858/node={C02D36GlMD6R}{ahl6F9fBQ06WQVQQ3s5i5w}{7ERiDnWHRD-akA9aCUL9wA}{127.0B0.1}{127.0.0.1:9316}{dilmrt-machine_memory=34359738368f xpack-installed=true, transform-node=truef ml-max_open_jobs=20}}
[2021-02-18715:53:27,632][DEBUG][o-e-c.c.PreVoteCollector ] [C02D36G1MD6R] accpeting prevote for PreVoteRequest{sourceNode={C02D36GlMD6R}{vY2rqLL9SbO3x_qg-nkJ9w}{Idvlwl9ySQqxAw43ANiRzQ}{127.0.0.1}{127.0.0.1:9310}{dilmarhi ha mAmnml hhah i nhc=7A	i nc-f-al 1 Arl=± n ia 十 rnnsfcrm nndA=± n	ri irfah-I-Tarm=QRRAl

 

 

在 Elasticsearch 的選舉算法中,允許選民投多票,并讓最后一個leader當選,這需要

  • 候選人在拉選票的過程中,如果收到其他候選人的 RequestVote,則清空自己已經收到的選票
  • 如果一個 leader 收到 RequestVote,則切換到候選人

決定競選激烈程度的是幾個超時時間控制的選舉周期:

  • gracePeriod:固定的競選時長限制,由cluster.election.duration配置,默認 500ms
  • maxTimeout:選舉前的最大等待時間,由cluster.election.max_timeout配置,默認 10s
  • backoffTime:競選失敗進行重試時,用重試次數乘以 backoffTime,由cluster.election.back_off_time
    配置,默認 100ms

候選人的競選過程周期性執行,執行周期就是在cluster.election.duration的基礎上加上不超過最大等待時間的隨機值。

 

//重試次數,每次加 1
final long thisAttempt = attempt.getAndIncrement();
//最大延遲時間不超過cluster.election.max_timeout配置,每次遞增cluster.election.back_off_time
final long maxDelayMillis = Math.min(maxTimeout.millis(), initialTimeout.millis() + thisAttempt * backoffTime.millis());
//執行延遲在cluster.election.duration基礎上遞增隨機值
final long delayMillis = toPositiveLongAtMost(random.nextLong(), maxDelayMillis) + gracePeriod.millis();
threadPool.scheduleUnlessShuttingDown(TimeValue.timeValueMillis(delayMillis), Names.GENERIC, runnable);

 

這個延遲時間是一個比較小的時間,我們截取兩個時間點可以大致看一下增長情況,經過 4 分鐘左右,競選周期從 1 秒內增長到 7 秒。這個過程是線性增長的。

[2021-02-18T00:13:48,869][DEBUG]scheduleNextElection{ delayMillis=658}
[2021-02-18T00:17:53,743][DEBUG]scheduleNextElection{ delayMillis=7597}

從上面的實現可以看出,加大 cluster.election.duration可以降低選舉激烈程度。

這里還有一個疑問,PreVote 是干什么去了,為什么沒有攔截住?有兩種情況:

  • 選民收到首次集群狀態,才認為集群存在 Leader 了,后續的 Prevote 返回 false,但是在競爭激烈的時候沒有節點被選為 leader。
  • 選民收到了首次集群狀態,但在此之前又收到了其他節點的 RequestVote,導致自己的 term 更大了,首次集群狀態因為 term 更低被忽略。如下圖:
[2021-02-18712:53:02,797][DEBUG][o.e.c.c.PreVoteCollector ] [C02D36G1MD6R] accpeting prevote for PreVoteRequest{sourceNode={C02D36GlMD6R}{Y80RYqNyRiK_rE38TbpZFw}{LFwjK-FlRHKiPnrsIGoYFQ}{127?0?0? 1}{127?0?0?l:9317}{dilmrt.machine_memory=34359738368, ml.max_open_jobs=20, xpack.installed=truef transform.node=true}, currentTerm=8592}

[2021-02-18712:53:03,464][DEBUG][o.e.c.c.PreVoteCollector ] [C02D36G1MD6R]accpeting prevote for PreVoteRequest{sourceNode={C02D36GlMD6R}{5TeQB34ARHG2tHCb2DR7QQ}{9u5fcoDBTZKMsPlqGKntVw}{127?0?0?1}{127?0?0?l:9309}{dilmrt.machine_memory=34359738368, ml.max_open_jobs=20, xpack.installed=true, transform?node=true}, currentTerm=8592}

[2021-02-18T12£53:03f470][DEBUG][o.e.c.c.Coordinationstate] [C02D36G1MD6R]
handteStartJoin :leaving term [8593] due to StartJoinRequest{term=8594fnode={C02D36GlMD6R}{HgU8AzfASnqv5ijcDe0vFg}{WyVP-LtOTtiUtCo6ilgiIQ}{127.0.0.1}{dilmrt.machine_memory=34359738368, ml.max_open_jobs=20, xpack.installed=true, transform.node=true}}

[2021-02-18712:53:04,118][TRACE][o.e.c.c.PreVoteCollector ] [C02D36G1MD6R] updating with preVoteResponse=PreVoteResponse{currentTerm=8594f lastAcceptedTerm=8470, lastAcceptedVersion=366}, leader=null
[2021-02-18712:53:06,380][DEBUG][o.e.c.c.PreVoteCoUector ] [C02D36G1MD6R] accpeting prevote for PreVoteRequest{sourceNode={C02D36GlMD6R}{joJil3nEQGCbLeXQVrE2Mw}{zKHyGdq0Q3e0bnG9tt3NLQ}{127?0?0?1}{127?0?0?l:9304}{dilmrt.machine_memory=34359738368, ml.max_open_jobs=20, xpack.installed=truef transform.node=true}, currentTerm=8593}

[2021-02-18712:53:06,600][DEBUG][o.e.c.c.PreVoteCollector ] [C02D36G1MD6R] accpeting prevote for PreVoteRequest{sourceNode={C02D36GlMD6R}{hDfYOFUSqyWqwm0TqyaCg}{gBGf5AAkQYervsfPBr6W9g}{127?0?0?1}{127?0?0?l:9308}{dilmrt.machine_memory=34359738368, ml.max_open_jobs=20, xpack.installed=truef transform.node=true}, currentTerm=8593}

 

最后總結一下,雖然分析過程比較復雜,但是解決起來比較簡單(不很完美):部署獨立的主節點,并且可以考慮適當增大cluster.election.duration的配置

0條評論
0 / 1000
1****n
10文章數
0粉絲數
1****n
10 文章 | 0 粉絲
原創

Elasticsearch7.x無法選主問題

2023-10-30 09:20:20
52
0

Elasticsearch 7.x 選舉算法改為基于 Raft 的實現,與標準 Raft 相比,最大的區別是允許選民可以投多票,當產生多個主節點的時候,讓最后一個當選,這樣,可以更快地選出主節點。但是這種機制同樣也有缺點,就是會使競選過程比較激烈。特別是當集群節點數量比較多的時候,候選人反復競爭可能會持續很長時間

當遇到這種無法選主情況時,節點會有如下的日志:

master not discovered or elected yet, an election requires at least XX nodes with ids from [] which is a quorum; discovery will continue using [] from hosts providers and [] from last-known cluster state; node term 14, last-accepted version 71 in term 5

或者

failed to join{…}
CoordinationStateRejectedException: incoming term 4996 does not match current term

 

但是這些報錯和問題根因沒有啥關系,探測到的節點已經能夠達到 quorum,然后繼續discovery,讓人很費解。這時得把日志調到 DEBUG:

{
    "persistent": {
        "logger.org.elasticsearch.cluster.service.MasterService": "DEBUG",
        "logger.org.elasticsearch.cluster.coordination": "DEBUG"
    }
}

跟隨報錯日志”which is a quorum; discovery will“,從代碼一路跟過去,發現只有becomeCandidate的時候才會觸發,搜索 debug 日志”coordinator becoming CANDIDATE“,找到以下信息:

[2021-02-17110:47:07,331][DEBUG][o.e.c.c.Coordinator[OWER, lastKnownLeader was [Optional[<C02D36GlMD6R}{HgU8AzfASnqvSij cDe][C02D36G1MD6R] joinLeaderlnTerm:oordinator becoming CANDIDATEin term 2513 (was0vFg}{fw2V24P5Stmhl6pEBu3xxg}{127.0.0.1}{127.0.0.1:9314}{dilmrt}{ml-machine_memory=34359738368f ml-max_open_jobs=20, xpack-installed=truef transform.node=true}]]) [2021-02-17T10:47:07,368][DEBUG][o.e.d.PeerFinder	] [C02D36G1MD6R] Peer{transportAddress=[::1]:9301f discoveryNode=nullf peersRequestInFlight=false} connection failedo rg- elasticsea rch.t ranspo rt. Connect? ranspo rtException: [][[::!]:9301] connect_exception
    at org.elasticsearch.transport.TcpTransport$ChannelsConnectedListener-onFailure(TcpTransport.java:998)?[elasticsearch-7.7.0.jar:7.7.0]
    at ora.elasticsearch.action.ActionListener.XambdaitoBiConsumeriZCActionListener.iava:198) ~Felasticsearch-7.7.0.iar:7.7.01

 

注意他上一個狀態是FOLLOWER,在 Elasticsearch 的選舉狀態圖里,只有加入集群才會切換到FOLLOWER狀態。這說明有主節點被選出來了,繼續搜 ”coordinator becoming FOLLOWER “,可以找到他切換到FOLLOWER時Leader的源地址:

[2021-02-17T10:47:07,153][DEBUG][o.e.c.c.PublicationTransportHandler] [C02D36G1MD6R] received full cluster state version [93] with size [13793]
[2021-02-17710:47:07,177][DEBUG][o.e.c.c.Coordinator][C02D36G1MD6R] onFollowerCheckRequest:of [{C02D36GlMD6R}{HgU8AzfASnqv5ijcDe0vFg}{fw2V24P5Stmhl6pEBu3xxg}{127.0.0.1}{|127.0.0.JXdilmrt.machine_memory=34359738368, ml.max_open_jobs=20, xpack.installed=true, transform.node=true}] in term 2511 (was CANDIDATE, lastKnownLeader was [Optional.empty])

 

然后看一下 Leader 節點的日志,發現有:

elected-as-master (.. nodes joined) 以及
failing [elected-as-master

 

[2021-02-17Tll:33:40f305][WARN ][o.e.c-s.MasterService ] [C02D36G1MD6R] failing [elected—卜 elect leader, _BECOME_MASTER_TASK_, —FINISH-ELECTION」]: failed to commit cluster state version [103])rg.elasticsearch.cluster.coordination.FailedToCommitClusterStateException: publication failed
at org.elasticsearch.cluster.coordination.Coordinator$CoordinatorPublication$4.onFailure(Coordinator-java:1431) ~[elasticsearch-7.7.0.jar:7.7.0]
at org.elasticsearch.action.ActionRunnable.onFailure(ActionRunnable-java:88) ~[elasticsearch-7.7.0.jar:7.7.0]
at org.elasticsearch.common.util.concurrent.AbstractRunnable- run(AbstractRunnable-java:39) ~[elasticsearch-7.7.0.jar:7-7.0]
at org.elasticsearch.common.util.concurrent.EsExecutors$DirectExecutorService.execute(EsExecutors.java:225) ~[elasticsearch-7.7.0.jar:7.7.0]
at org.elasticsearch.common.util.concurrent.ListenableFuture.notifyListener(ListenableFuture.java:106) ^[elasticsearch-7.7.0.jar:7.7.0]
at org.elasticsearch.common.util.concurrent.ListenableFuture.addListener(ListenableFuture-java:68) ~[elasticsearch-7.7.0.jar:7.7.0]
at org.elasticsearch.cluster.coordination.Coordinator$CoordinatorPublication.onCompletion(Coordinator-java:1354) ~[elasticsearch-7.7.0.jar:7.7.0]
at org.elasticsearch.cluster.coordination.Publication.onPossibleCompletion(Publication.java:125) [elasticsearch-7.7.0-jar:7.7.0]
at org.elasticsearch.cluster.coordination.Publication.cancel(Publication.java:89) [elasticsearch-7.7.0.jar:7.7.0]
at org.elasticsearch.cluster.coordination.Coordinator.cancelActivePublication(Coordinator.java:1129) ~[elasticsearch-7.7.0.jar:7.7.0]
at org.elasticsearch.cluster.coordination.Coordinator.becomeCandidate(Coordinator-java:544) ~[elasticsearch-7.7.0.jar:7.7.0]
at org.elasticsearch.cluster.coordination.Coordinator-joinLeaderInTerm(Coordinator-java:457) [elasticsearch-7.7.0.jar:7.7.0]
at org.elasticsearch.cluster.coordination.JoinHelper.lambda$new$2(JoinHelper-java:141) [elasticsearch-7.7.0.jar:7.7.0]

 

 

可以看到節點起初被成功選為 Master,但是后來因為收到其他節點拉選票的RequestVote 請求(joinLeaderInTerm函數是對競選請求的處理)取消集群狀態的發布,切換到候選人狀態。如果他成功發布了集群狀態,新主就可以順利當選了。

我們再觀察候選人每次發起 RequestVote 的周期以及成功情況:

 

grep -E "starting election with|elected-as-master" logs/my-debug.log |less

發現他有時候甚至來不及被選為master,都沒有走到發布集群狀態的流程:

[2021-02-18T15:58:19f541][DEBUG][o.e.c.c-Coordinator][C02D36G1MD6R]starting election with StartJoinRequest{tenn=10424,node={C02D36GlMD6R}{ahl6F9fBQ06WQVQQ3s5i5w}{7ERiDnWHRD-akA9aCUL9wA}{127?0.0.1}{127?0.0.1:9316}{dilmrt}{ml.machine_memory=34359738368f xpack-installed=true, transform■node=true、ml■max_open_jobs=20}}
[2021-02-18T15:58:24f909][DEBUG][o.e.c.c-Coordinator][C02D36G1MD6R]starting election with StartJoinRequest{term=10433/node={C02D36GlMD6R}{ahl6F9fBQ06WQVQQ3s5i5w}{7ERiDnWHRD-akA9aCUL9wA}{127.0.0.1}{127.0.0.1:9316}{dilmrt}{ml.machine_memory=34359738368f xpack.installed=true, transform■node=true、ml■max_open_jobs=20}}
[2021-02-18T15:58:33f470][DEBUG][o.e.c.c.Coordinator][C02D36G1MD6R]starting election]with StartJoinRequest{tenn=10448,node={C02D36GlMD6R}{ahl6F9fBQ06WQVQQ3s5i5w}{7ERiDnWHRD-akA9aCUL9wA}{127?0.0.1}{127?0.0.1:9316}{dilmrt}{ml.machine_memory=34359738368f xpack-installed=true, transform■node=true、ml■max_open_jobs=20}}

 

 

而來不及被選為 master 的原因是被其他候選人拉選票的請求打斷:

 

[2021-02-18715:53:27,194][DEBUG][o.e.c.c-CoordinationState] [C02D36G1MD6R]handleStart Join:ignoring [StartJoinRequest{term=9854fnode={C02D36GlMD6R}{m47W97RlSKirn4cEHabkQw}{Tgn9Ag5wS0eAwPRO0cw-bA}{127.0.0.1}{127.0.0.l:9314}{dilmrt}{ml.machine_memory=34359738368f ml.max_open_jobs=20# xpack-installed=true, transform.node=true}}] as term provided is not greater than current term [9855]
[2021-02-18715:53:27,194][DEBUG][o-e-c.c.PreVoteCollector I [C02D36G1MD6R] accpeting prevote for PreVoteRequest{sourceNode={C02D36GlMD6R}{BFhjJetNRoqViiREg8mPsg}{0AAm8XblTGiCR5oXqTtoMg}{127.0.0.1}{127.0.0.1:9319}{dilmrt}{ml.machine_memory=34359738368f ml.max_open_jobs=20# xpack-installed=true, transform.node=true}f currentTerm=9854}
[2021-02-18715:53:27,194][DEBUG][o-e.c.c.PreVoteCollector ] [C02D36G1MD6R] accpeting prevote for PreVoteRequest{sourceNode={C02D36GlMD6R}{jFZFK70bQy6jJUtAdG58MQ}{zJ_Jmw5fSOujYUxUDsXBzwH127.0.0.1H127.0.0.1:9307}{dil mrt}{ml.machine_memory=34359738368f ml.max_open_jobs=20# xpack-installed=true, transform.node=true}, currentTerm=9852}
[2021-02-18715:53:27,194][DEBUG][o-e-c.c.PreVoteCollector ] [C02D36G1MD6R] accpeting prevote for PreVoteRequest{sourceNode={C02D36GlMD6R}{J2P_QC8dSGGp5C6OJJP5nw}{CJqGAk5WQH6_VZlHRA5zOA}{127.0.0.1}{127.0.0.1:9304}{dil mrt}{ml.machine_memory=34359738368f ml.max_open_jobs=20# xpack-installed=truef transform.node=true}f currentTerm=9853}
[2021-02-18715:53:27,195][DEBUG][o.e.c.c-CoordinationState] [C02D36G1MD6R]handle StartJoin7.0B0Bl}{127.0B0Bl:9313}{dilmrt}{ml.machine_memory=34359738368f ml■max_open_jobs=20, xpack-installed=true, transform.node=true}}:leaving term [9855] due to StartJoinRequest{term=9856fnode={C02D36GlMD6R}{5TeQB34ARHG2tHCb2DR7QQ}{Yul-rl3iS4SUMy5Vos9g5w}{12at org-elasticsearch.cluster.coordination.CoordinationState-at org.elasticsearch.cluster-coordination.Coordinationstate.handlestartJoin handleSta rtJoin
(CoordinationState-java:181)?[elasticsearch-7.7.0.jar:7.7.0-SNAPSHOT]
(CoordinationState■java:181)?[elasticsearch-7.7.0.jar:7.7.0-SNAPSHOT]
[2021-02-18715:53:27340][TRACE][o-e.c-c.PreVoteCollector ] [C02D36GlMD6R] updating with preVoteResponse=RreVoteResponse{currentTerm=9856f lastAcceptedTerm=8597f 'lastAcceptedVersion=371}f leader=null
     at org-elasticsearch.cluster.coordination.Coordinationstate.(Coordinationstate■java:181)?[elasticsearch-7.7.0.jar:7.7.0-SNAPSHOT]

[2021-02-18715:53:27,606][DEBUG][o-e.c.c-CoordinationState] [C02D36G1MD6R]:ignoring [StartJoinRequest{term=9854fnode={C02D36GlMD6R}{J2P_QC8dSGGp5C6OJJP5nw}{CJqGAk5WQH6_VZlHRA5zOA}{127.0.0.1}{127.0.0.l:9304}{dilmrt}{ml.machine_memory=34359738368f ml.max_open_jobs=20# xpack.inctalledWrue, transform.node=true}}] as term provided is not greater than current term [9856]
[2021-02-18115:53:27,633][DEBUG][o.e.c.c.Coordinator][C02D36G1MD6R] Itarting election with]StartJoinRequest{term=9858/node={C02D36GlMD6R}{ahl6F9fBQ06WQVQQ3s5i5w}{7ERiDnWHRD-akA9aCUL9wA}{127.0B0.1}{127.0.0.1:9316}{dilmrt-machine_memory=34359738368f xpack-installed=true, transform-node=truef ml-max_open_jobs=20}}
[2021-02-18715:53:27,632][DEBUG][o-e-c.c.PreVoteCollector ] [C02D36G1MD6R] accpeting prevote for PreVoteRequest{sourceNode={C02D36GlMD6R}{vY2rqLL9SbO3x_qg-nkJ9w}{Idvlwl9ySQqxAw43ANiRzQ}{127.0.0.1}{127.0.0.1:9310}{dilmarhi ha mAmnml hhah i nhc=7A	i nc-f-al 1 Arl=± n ia 十 rnnsfcrm nndA=± n	ri irfah-I-Tarm=QRRAl

 

 

在 Elasticsearch 的選舉算法中,允許選民投多票,并讓最后一個leader當選,這需要

  • 候選人在拉選票的過程中,如果收到其他候選人的 RequestVote,則清空自己已經收到的選票
  • 如果一個 leader 收到 RequestVote,則切換到候選人

決定競選激烈程度的是幾個超時時間控制的選舉周期:

  • gracePeriod:固定的競選時長限制,由cluster.election.duration配置,默認 500ms
  • maxTimeout:選舉前的最大等待時間,由cluster.election.max_timeout配置,默認 10s
  • backoffTime:競選失敗進行重試時,用重試次數乘以 backoffTime,由cluster.election.back_off_time
    配置,默認 100ms

候選人的競選過程周期性執行,執行周期就是在cluster.election.duration的基礎上加上不超過最大等待時間的隨機值。

 

//重試次數,每次加 1
final long thisAttempt = attempt.getAndIncrement();
//最大延遲時間不超過cluster.election.max_timeout配置,每次遞增cluster.election.back_off_time
final long maxDelayMillis = Math.min(maxTimeout.millis(), initialTimeout.millis() + thisAttempt * backoffTime.millis());
//執行延遲在cluster.election.duration基礎上遞增隨機值
final long delayMillis = toPositiveLongAtMost(random.nextLong(), maxDelayMillis) + gracePeriod.millis();
threadPool.scheduleUnlessShuttingDown(TimeValue.timeValueMillis(delayMillis), Names.GENERIC, runnable);

 

這個延遲時間是一個比較小的時間,我們截取兩個時間點可以大致看一下增長情況,經過 4 分鐘左右,競選周期從 1 秒內增長到 7 秒。這個過程是線性增長的。

[2021-02-18T00:13:48,869][DEBUG]scheduleNextElection{ delayMillis=658}
[2021-02-18T00:17:53,743][DEBUG]scheduleNextElection{ delayMillis=7597}

從上面的實現可以看出,加大 cluster.election.duration可以降低選舉激烈程度。

這里還有一個疑問,PreVote 是干什么去了,為什么沒有攔截住?有兩種情況:

  • 選民收到首次集群狀態,才認為集群存在 Leader 了,后續的 Prevote 返回 false,但是在競爭激烈的時候沒有節點被選為 leader。
  • 選民收到了首次集群狀態,但在此之前又收到了其他節點的 RequestVote,導致自己的 term 更大了,首次集群狀態因為 term 更低被忽略。如下圖:
[2021-02-18712:53:02,797][DEBUG][o.e.c.c.PreVoteCollector ] [C02D36G1MD6R] accpeting prevote for PreVoteRequest{sourceNode={C02D36GlMD6R}{Y80RYqNyRiK_rE38TbpZFw}{LFwjK-FlRHKiPnrsIGoYFQ}{127?0?0? 1}{127?0?0?l:9317}{dilmrt.machine_memory=34359738368, ml.max_open_jobs=20, xpack.installed=truef transform.node=true}, currentTerm=8592}

[2021-02-18712:53:03,464][DEBUG][o.e.c.c.PreVoteCollector ] [C02D36G1MD6R]accpeting prevote for PreVoteRequest{sourceNode={C02D36GlMD6R}{5TeQB34ARHG2tHCb2DR7QQ}{9u5fcoDBTZKMsPlqGKntVw}{127?0?0?1}{127?0?0?l:9309}{dilmrt.machine_memory=34359738368, ml.max_open_jobs=20, xpack.installed=true, transform?node=true}, currentTerm=8592}

[2021-02-18T12£53:03f470][DEBUG][o.e.c.c.Coordinationstate] [C02D36G1MD6R]
handteStartJoin :leaving term [8593] due to StartJoinRequest{term=8594fnode={C02D36GlMD6R}{HgU8AzfASnqv5ijcDe0vFg}{WyVP-LtOTtiUtCo6ilgiIQ}{127.0.0.1}{dilmrt.machine_memory=34359738368, ml.max_open_jobs=20, xpack.installed=true, transform.node=true}}

[2021-02-18712:53:04,118][TRACE][o.e.c.c.PreVoteCollector ] [C02D36G1MD6R] updating with preVoteResponse=PreVoteResponse{currentTerm=8594f lastAcceptedTerm=8470, lastAcceptedVersion=366}, leader=null
[2021-02-18712:53:06,380][DEBUG][o.e.c.c.PreVoteCoUector ] [C02D36G1MD6R] accpeting prevote for PreVoteRequest{sourceNode={C02D36GlMD6R}{joJil3nEQGCbLeXQVrE2Mw}{zKHyGdq0Q3e0bnG9tt3NLQ}{127?0?0?1}{127?0?0?l:9304}{dilmrt.machine_memory=34359738368, ml.max_open_jobs=20, xpack.installed=truef transform.node=true}, currentTerm=8593}

[2021-02-18712:53:06,600][DEBUG][o.e.c.c.PreVoteCollector ] [C02D36G1MD6R] accpeting prevote for PreVoteRequest{sourceNode={C02D36GlMD6R}{hDfYOFUSqyWqwm0TqyaCg}{gBGf5AAkQYervsfPBr6W9g}{127?0?0?1}{127?0?0?l:9308}{dilmrt.machine_memory=34359738368, ml.max_open_jobs=20, xpack.installed=truef transform.node=true}, currentTerm=8593}

 

最后總結一下,雖然分析過程比較復雜,但是解決起來比較簡單(不很完美):部署獨立的主節點,并且可以考慮適當增大cluster.election.duration的配置

文章來自個人專欄
文章 | 訂閱
0條評論
0 / 1000
請輸入你的評論
0
0