summaryrefslogtreecommitdiff
path: root/ovsdb/raft.c
diff options
context:
space:
mode:
authorHan Zhou <hzhou8@ebay.com>2019-04-19 12:17:47 -0700
committerBen Pfaff <blp@ovn.org>2019-04-22 13:02:59 -0700
commit4d9b28cbb797ad112d2aefccab93c7d37493941a (patch)
tree1a9af65f39ecdde9cb99c236b119868058a83c89 /ovsdb/raft.c
parent9f39622ab2c67b2f1496b9ee9a395c204527f584 (diff)
downloadopenvswitch-4d9b28cbb797ad112d2aefccab93c7d37493941a.tar.gz
ovsdb raft: Avoid unnecessary reconnecting during leader election.
If a server claims itself as "disconnected", all clients connected to that server will try to reconnect to a new server in the cluster. However, currently a server would claim itself as disconnected even when itself is the candidate and try to become the new leader (most likely it will be), and all its clients will reconnect to another node. During a leader fail-over (e.g. due to a leader failure), it is expected that all clients of the old leader will have to reconnect to other nodes in the cluster, but it is unnecessary for all the clients of a healthy node to reconnect, which could cause more disturbance in a large scale environment. This patch fixes the problem by slightly change the condition that a server regards itself as disconnected: if its role is candidate, it is regarded as disconnected only if the election didn't succeed at the first attempt. Related failure test cases are also unskipped and all passed with this patch. Signed-off-by: Han Zhou <hzhou8@ebay.com> Signed-off-by: Ben Pfaff <blp@ovn.org>
Diffstat (limited to 'ovsdb/raft.c')
-rw-r--r--ovsdb/raft.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/ovsdb/raft.c b/ovsdb/raft.c
index 77ad365c2..c60ef41a2 100644
--- a/ovsdb/raft.c
+++ b/ovsdb/raft.c
@@ -286,6 +286,8 @@ struct raft {
/* Candidates only. Reinitialized at start of election. */
int n_votes; /* Number of votes for me. */
+ bool candidate_retrying; /* The first round of election timed-out and it
+ is now retrying. */
};
/* All Raft structures. */
@@ -985,11 +987,17 @@ raft_get_sid(const struct raft *raft)
/* Returns true if 'raft' has completed joining its cluster, has not left or
* initiated leaving the cluster, does not have failed disk storage, and is
* apparently connected to the leader in a healthy way (or is itself the
- * leader).*/
+ * leader).
+ *
+ * If 'raft' is candidate:
+ * a) if it is the first round of election, consider it as connected, hoping
+ * it will successfully elect a new leader soon.
+ * b) if it is already retrying, consider it as disconnected (so that clients
+ * may decide to reconnect to other members). */
bool
raft_is_connected(const struct raft *raft)
{
- return (raft->role != RAFT_CANDIDATE
+ return (!(raft->role == RAFT_CANDIDATE && raft->candidate_retrying)
&& !raft->joining
&& !raft->leaving
&& !raft->left
@@ -1608,6 +1616,7 @@ raft_start_election(struct raft *raft, bool leadership_transfer)
}
ovs_assert(raft->role != RAFT_LEADER);
+ raft->candidate_retrying = (raft->role == RAFT_CANDIDATE);
raft->role = RAFT_CANDIDATE;
raft->n_votes = 0;