Browse files

Sentinel: more aggressive failover start desynchronization.

Sentinel needs to avoid split brain conditions due to multiple sentinels
trying to get voted at the exact same time.

So far some desynchronization was provided by fluctuating server.hz,
that is the frequency of the timer function call. However the
desynchonization provided in this way was not enough when using many
Sentinel instances, especially when a large quorum value is used in
order to force a greater degree of agreement (more than N/2+1).

It was verified that it was likely to trigger a split brain
condition, forcing the system to try again after a timeout.
Usually the system will succeed after a few retries, but this is not

This commit desynchronizes instances in a more effective way to make it
likely that the first attempt will be successful.
  • Loading branch information...
1 parent 08da025 commit 47750998a61c4ba88be542292fb438ae651f8de3 @antirez committed Mar 4, 2014
Showing with 3 additions and 2 deletions.
  1. +3 −2 src/sentinel.c
5 src/sentinel.c
@@ -84,6 +84,7 @@ typedef struct sentinelAddr {
/* Failover machine different states. */
#define SENTINEL_FAILOVER_STATE_NONE 0 /* No failover in progress. */
@@ -2943,7 +2944,7 @@ char *sentinelVoteLeader(sentinelRedisInstance *master, uint64_t req_epoch, char
* time to now, in order to force a delay before we can start a
* failover for the same master. */
if (strcasecmp(master->leader,server.runid))
- master->failover_start_time = mstime();
+ master->failover_start_time = mstime()+rand()%SENTINEL_MAX_DESYNC;
*leader_epoch = master->leader_epoch;
@@ -3088,7 +3089,7 @@ void sentinelStartFailover(sentinelRedisInstance *master) {
(unsigned long long) sentinel.current_epoch);
- master->failover_start_time = mstime();
+ master->failover_start_time = mstime()+rand()%SENTINEL_MAX_DESYNC;
master->failover_state_change_time = mstime();

0 comments on commit 4775099

Please sign in to comment.