Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Add get-master-that-met-quorum-addr-by-name, to be used by sentinel-aware clients. #821

Open
wants to merge 1 commit into from

1 participant

@tanguylebarzic

Hi,

I asked the question on the mailing list, but I figured it would be easier to post some code.
Basically, according to the guidelines for sentinel-aware clients (http://redis.io/topics/sentinel-clients), clients should call get-master-addr-by-name to get the master address. However, sentinels will respond to this call with the master address even if the number of sentinels that appear to be connected to this master is less than the quorum. In some cases, this means that depending on the order in which the sentinels are queried, the resulting master address could be different if the sentinels are desynchronised.

This pull request adds a new method, get-master-that-met-quorum-addr-by-name (awful name, I agree), that answers with IDONTKNOW if the number of sentinels that appear to be connected to this master is less than the quorum.

Example of a real-world scenario that would trigger a desynchronization:

Two normal redis instances (called R1 and R2, with R1 being the master), and 3 sentinel instances S1, S2 and S3, quorum set to 2.
S1 and R1 become unavailable. Failover is initiated and completed, R2 is the new master, S2 and S3 respond accordingly.
Now S1 and R1 are available again. They don't know about the failover, so S1 becomes a master, and S1 answers to get-master-addr-by-name wtih R1.
At this point, if a client was given S1, S2 and S3 as starting sentinels, depending on the order in which it queries these sentinels, masters could be set to R1 (if calling S1 first) or R2 (if calling S2 or S3 first). If it were to call get-master-that-met-quorum-addr-by-name, S1 would respond with IDONTKNOW, and S2 and S3 would answer with R2, which is IMO the expected behaviour.

@tanguylebarzic tanguylebarzic Add get-master-that-met-quorum-addr-by-name method, similar to get-ma…
…ster-addr-by-name except it responds with IDONTKNOW if the number of sentinels connected to this master is less than the quorum.
bb8ce6b
@JackieXie168 JackieXie168 referenced this pull request from a commit
@AtnNn AtnNn Fix the fetched handlebars and lessc version
Review 598 by @neumino

Closes #821
2c96e05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Dec 11, 2012
  1. @tanguylebarzic

    Add get-master-that-met-quorum-addr-by-name method, similar to get-ma…

    tanguylebarzic authored
    …ster-addr-by-name except it responds with IDONTKNOW if the number of sentinels connected to this master is less than the quorum.
This page is out of date. Refresh to see the latest.
Showing with 39 additions and 0 deletions.
  1. +39 −0 src/sentinel.c
View
39 src/sentinel.c
@@ -2041,6 +2041,45 @@ void sentinelCommand(redisClient *c) {
addReplyBulkCString(c,addr->ip);
addReplyBulkLongLong(c,addr->port);
}
+ } else if (!strcasecmp(c->argv[1]->ptr,"get-master-that-met-quorum-addr-by-name")) {
+ /* SENTINEL GET-MASTER-THAT-MET-QUORUM-ADDR-BY-NAME <master-name> */
+ sentinelRedisInstance *ri;
+
+ if (c->argc != 3) goto numargserr;
+ ri = sentinelGetMasterByName(c->argv[2]->ptr);
+ if (ri == NULL) {
+ addReply(c,shared.nullmultibulk);
+ } else if (ri->info_refresh == 0) {
+ addReplySds(c,sdsnew("-IDONTKNOW I have not enough information to reply. Please ask another Sentinel.\r\n"));
+ } else {
+ sentinelAddr *addr = ri->addr;
+
+ if ((ri->flags & SRI_FAILOVER_IN_PROGRESS) && ri->promoted_slave)
+ addr = ri->promoted_slave->addr;
+
+ // Count the connected sentinels for this master.
+ dictIterator *di;
+ dictEntry *de;
+ int connectedSentinels = 1;
+
+ di = dictGetIterator(ri->sentinels);
+
+ while((de = dictNext(di)) != NULL) {
+ sentinelRedisInstance *otherri = dictGetVal(de);
+
+ if ((otherri->flags & SRI_DISCONNECTED) == 0) connectedSentinels++;
+ }
+ dictReleaseIterator(di);
+
+ if(connectedSentinels < ri->quorum){
+ addReplySds(c,sdsnew("-IDONTKNOW I have not enough information to reply, quorum not met. Please ask another Sentinel.\r\n"));
+ }
+ else {
+ addReplyMultiBulkLen(c,2);
+ addReplyBulkCString(c,addr->ip);
+ addReplyBulkLongLong(c,addr->port);
+ }
+ }
} else if (!strcasecmp(c->argv[1]->ptr,"failover")) {
/* SENTINEL FAILOVER <master-name> */
sentinelRedisInstance *ri;
Something went wrong with that request. Please try again.