Skip to content

Sentinel master reboot fix#9438

Merged
yossigo merged 8 commits into
redis:unstablefrom
hwware:sentinel-master-reboot-fix
Nov 30, 2021
Merged

Sentinel master reboot fix#9438
yossigo merged 8 commits into
redis:unstablefrom
hwware:sentinel-master-reboot-fix

Conversation

@hwware

@hwware hwware commented Aug 31, 2021

Copy link
Copy Markdown
Contributor

Background Information:

We have two issues #1297 and #4561
They mentioned that Sentinel does not trigger failover in case of master node reboot in very shot time.
This PR is to fix this problem for sentinel.

Sentinel send PING request to master, replicas and other sentinels according to the "down-after-milliseconds" parameters in
sentinel.conf or its own config file.

If down-after-milliseconds is greater than 1000, Sentinel will send PING every second.
If down-after-milliseconds is less than 1000, Sentinel will send PING according to the down-after-milliseconds value

For example:

// Sentinel send PING request every 1 second
Sentinel down-after-milliseconds mymaster 60000

// Sentinel send PING request every 600 milliseconds
Sentinel down-after-milliseconds mymaster 600

Solution:

If master reboot in very short time, Sentinel will receive one "reboot" information.
At this time, add SRI_MASTER_REBOOT to this Sentinel instance and record the master reboot time in master_reboot_since_time variable.

If Sentinel receives "Loading" reply with SRI_MASTER_REBOOT flag from master for 10 * PING time,
Sentinel think master is subjectively down, and ready to vote and failover process.

This solution could grantee if master is reboot in very short time, failover could finish in 10 seconds.

@yossigo yossigo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hwware Code looks good, a few nitpicks.

Basically we identify a rebooting master as a new distinct kind of failure mode, for which we apply reboot-down-after-milliseconds configuration. I have a couple of conceptual questions here:

  • Is it really necessary to do that, vs. just treating -LOADING as any other error and failing over?
  • If we do, won't it make sense to do this configurable rather than hard coded?

I will be happy to also get the perspective of recent reporters of this issue, @daniel-house and others.

Comment thread src/sentinel.c Outdated

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#define SRI_MASTER_REBOOT (1<<13) /* this flag set thinks that master is rebooted in very shot time*/
#define SRI_MASTER_REBOOT (1<<13) /* Master was detected as rebooting */

nit: typo/rephrase.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed

Comment thread src/sentinel.c Outdated
Comment thread src/sentinel.c Outdated
@daniel-house

Copy link
Copy Markdown

Does anyone know why LOADING was ever considered a reason to prevent failover? As far as I can tell, PONG, LOADING and MASTERDOWN were all determined to mean the instance is available in the same commit and I cannot see any obvious reason for including LOADING in the list.

If LOADING means "not available", and you shut down the master and all of it's replicas gracefully at a time when you have a significant amount of data, then start everything very quickly, you would see failovers during the restart. Could that have been the reason for adding this line? https://github.com/redis/redis/blob/e96bb30ebf532496e7f8b5fca208b6e86ab3ae4f/src/sentinel.c#L2818

@yossigo

yossigo commented Sep 6, 2021

Copy link
Copy Markdown
Collaborator

@daniel-house If you restart both masters and replicas, you'd probably get -LOADING from the master and -MASTERDOWN from the replica. I assume the rationale behind avoiding a failover is that in this case you may end up switching back and forth, whereas simply waiting should (eventually) yield a reasonable result.

On the other hand, if the replica is up and running and it's only the master that's -LOADING - failover does make sense.

@hwware

hwware commented Sep 7, 2021

Copy link
Copy Markdown
Contributor Author

@daniel-house If you restart both masters and replicas, you'd probably get -LOADING from the master and -MASTERDOWN from the replica. I assume the rationale behind avoiding a failover is that in this case you may end up switching back and forth, whereas simply waiting should (eventually) yield a reasonable result.

On the other hand, if the replica is up and running and it's only the master that's -LOADING - failover does make sense.

I think for this case, if you restart both masters and replicas in very short time, we could assume it takes only less than 0.1 or 0.5 seconds, then you could get -LOADING from the master and replica, because replica need to first load its own RDB file or AOF file and then try to connect to master. If at that time master is still unavailable, replica will declare "MASTERDOWN"

@hwware

hwware commented Sep 7, 2021

Copy link
Copy Markdown
Contributor Author

@hwware Code looks good, a few nitpicks.

Basically we identify a rebooting master as a new distinct kind of failure mode, for which we apply reboot-down-after-milliseconds configuration. I have a couple of conceptual questions here:

  • Is it really necessary to do that, vs. just treating -LOADING as any other error and failing over?
  • If we do, won't it make sense to do this configurable rather than hard coded?

I will be happy to also get the perspective of recent reporters of this issue, @daniel-house and others.

@yossigo For this issue, i find it almost exists in all previous versions, if do you think merge these changed codes to those versions, thanks.

@hwware

hwware commented Oct 18, 2021

Copy link
Copy Markdown
Contributor Author

@yossigo Let me describe the whole process for this solution. Thanks.
The issue happens when master node suddenly reboot in a very shot time. At this time, Because the reboot time is too short, Sentinel can not execute failover. The master node is loading data from RDB, thus client can not read and write data from this master node.
My solution is: because Sentinel could receive a "reboot" signal, then I add a new signal variable "SRI_MASTER_REBOOT" to indicate master node are rebooting and sentinel begins timing. Once master can not finish the reboot process in 10 seconds (I set this value), then Sentinel will failover process
one concern for this solution is: this solution is how to proceed if master and some replica reboot together? I think my solution works as well, Because if more than half replicas still works, failover could happens. And if most replicas and master do not work, thus failover will not happens. The Sentinel will period send ping and info to master and replica, If master finishes the loading process, then Sentinel will remove the "SRI_MASTER_REBOOT" signal. If master is still loading the data, and most replicas works, then Sentinel could be ready to another failover process.
Above is all summary for the Sentinel issue, please take sometime to review, welcome to any discussion, thanks

@yossigo yossigo added release-notes indication that this issue needs to be mentioned in the release notes state:to-be-merged The PR should be merged soon, even if not yet ready, this is used so that it won't be forgotten labels Oct 21, 2021
@yossigo

yossigo commented Nov 4, 2021

Copy link
Copy Markdown
Collaborator

@hwware I had another discussion about this with @oranagra.

One way to look at this fix is that it improves availability over durability of data because, at least in some scenarios, the master will have the most up to date dataset and we just need to wait for it to load.

The concern is that different deployments may have conflicting needs: some may want to push availability further and not even wait 10*ping time before failing over a master that's loading, and others may want to wait longer (or forever).

We could achieve that if master_reboot_down_after_period was configurable and support a value of zero to maintain the existing behavior. WDUT?

@hwware

hwware commented Nov 4, 2021

Copy link
Copy Markdown
Contributor Author

@hwware I had another discussion about this with @oranagra.

One way to look at this fix is that it improves availability over durability of data because, at least in some scenarios, the master will have the most up to date dataset and we just need to wait for it to load.

The concern is that different deployments may have conflicting needs: some may want to push availability further and not even wait 10*ping time before failing over a master that's loading, and others may want to wait longer (or forever).

We could achieve that if master_reboot_down_after_period was configurable and support a value of zero to maintain the existing behavior. WDUT?

I totally agree what you suggest, making master_reboot_down_after_period configurable gives user more flexible choices. I could update codes in this PR, Thanks

@hwware hwware force-pushed the sentinel-master-reboot-fix branch from d5c7afe to 6a8efaf Compare November 8, 2021 21:45
@hwware

hwware commented Nov 9, 2021

Copy link
Copy Markdown
Contributor Author

@hwware I had another discussion about this with @oranagra.

One way to look at this fix is that it improves availability over durability of data because, at least in some scenarios, the master will have the most up to date dataset and we just need to wait for it to load.

The concern is that different deployments may have conflicting needs: some may want to push availability further and not even wait 10*ping time before failing over a master that's loading, and others may want to wait longer (or forever).

We could achieve that if master_reboot_down_after_period was configurable and support a value of zero to maintain the existing behavior. WDUT?

@hwware Hi Yossi, follow your suggestion, I change "`master_reboot_down_after_period" as configurable, and client could
set it by command: sentinel set, please take a look the updated codes, Thanks a lot.

@yossigo

yossigo commented Nov 10, 2021

Copy link
Copy Markdown
Collaborator

@hwware I've pushed a commit with minor cleanups, I think the only thing missing to merge this is a test.

@hwware hwware force-pushed the sentinel-master-reboot-fix branch from a8a8a48 to de4c036 Compare November 18, 2021 20:27
@hwware hwware force-pushed the sentinel-master-reboot-fix branch from de4c036 to 666df41 Compare November 24, 2021 19:04
@hwware

hwware commented Nov 26, 2021

Copy link
Copy Markdown
Contributor Author

@yossigo Hi Yossi, I just add the test for this PR, please take a look, thanks

hwware added a commit to hwware/redis that referenced this pull request Dec 20, 2021
Add master-reboot-down-after-period as a configurable parameter, to make it possible to trigger a failover from a master that is responding with `-LOADING` for a long time after being restarted.
enjoy-binbin added a commit to enjoy-binbin/redis that referenced this pull request Mar 8, 2023
oranagra pushed a commit that referenced this pull request Mar 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release-notes indication that this issue needs to be mentioned in the release notes state:to-be-merged The PR should be merged soon, even if not yet ready, this is used so that it won't be forgotten

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants