Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[JUJU-672] Retry more classes of Raft leader errors #13788

Merged
merged 1 commit into from Feb 24, 2022

Conversation

manadart
Copy link
Member

@manadart manadart commented Feb 24, 2022

For API-based leases, the behaviour has been to pre-emptively check the Raft state prior to applying each operation, and if we are not running on the leader, return a NotLeaderError, which is interpreted downstream as being retry-able.

However it is possible after checking state and verifying leadership, that we can get an error such as raft.ErrLeadershipLost while applying the log, which flows up and is not recognised as retry-able, causing the lease manager to bounce.

Here we remove the pre-emptive check along with its local dedicated metric and time tracking. Instead we check the Raft state after getting leadership-based errors, with the following benefits:

  • The increased efficiency of not checking Raft state for every log application.
  • We represent more of the leadership error types as NotLeaderError, meaning retry instead of lease manager crash and restart.

QA steps

  • Bootstrap with --config features="[raft-api-leases]".
  • juju model-config -m controller logging-config="<root>=INFO;juju.worker.lease.raft=TRACE;juju.core.raftlease=TRACE;juju.worker.globalclockupdater.raft=TRACE;juju.worker.raft=TRACE;juju.worker.raft.raftforwarder=TRACE;juju.worker.raft.rafttransport=TRACE".
  • Watch debug-log -m controller.
  • juju enable-ha.
  • juju deploy ubuntu -n 3.
  • Normal operation will see logging with sections like this:
machine-0: 10:32:46 TRACE juju.worker.globalclockupdater.raft incremented lease clock by 1s
machine-0: 10:32:47 TRACE juju.worker.globalclockupdater.raft incremented lease clock by 1s
machine-0: 10:32:48 TRACE juju.worker.globalclockupdater.raft incremented lease clock by 1s
machine-0: 10:32:49 TRACE juju.worker.globalclockupdater.raft incremented lease clock by 1s
machine-0: 10:32:50 TRACE juju.worker.lease.raft [df51a1] machine-0 extending lease df51a145-6b04-434e-8abb-663951fcc757 for 1m0s
machine-0: 10:32:50 TRACE juju.worker.raft Dequeued 1 commands to be applied on the raft log
machine-0: 10:32:50 TRACE juju.worker.raft Applying command 0 version: 1
operation: extend
namespace: singular-controller
model-uuid: 847b5f2d-0dc6-440a-837e-86d7b0bc8ce8
lease: df51a145-6b04-434e-8abb-663951fcc757
holder: machine-0
duration: 1m0s
  • Note that the lease clock updater runs on the Raft leader, in the case above, machine-0.
  • Restart the leader node: juju ssh -m controller 0 -- sudo reboot now. You will probably have to reconnect your debug-log session.
  • Observe a period of churn where you may see lines like this:
machine-2: 10:33:49 ERROR juju.worker.raft Raft future error: node is not the leader
machine-2: 10:33:49 INFO juju.worker.raft Attempt to apply the lease failed, we're not the leader. State: Follower, Leader: 10.161.87.110:17070
  • Control plane should quiesce quite quickly, and normal lease operation will resume.
  • (BONUS) Step down the Mongo primary and observe relatively quick resumption of quiesced state.

Documentation changes

None.

Bug reference

N/A

apply to the Raft log.

Instead, we only make this check for certain classes of errors
specifically relating to leadership, and return our typed leadership
error indicating that such operations can be retried.
// not. This can be used to understand if we're hitting issues with the
// underlying raft instance.
Record(start time.Time, result string)
// RecordLeaderError calls out that there was a leader error, so didn't
// follow the usual flow.
RecordLeaderError(start time.Time)
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure I agree with the removal of this for two reasons:

  1. By not measuring failures, you don't show the real perception of the state of the world. Only showing good things leads to bad outcomes.
  2. By not measuring the actual timing of failures we don't know if we've actually improved anything here.

Copy link
Member Author

Choose a reason for hiding this comment

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

We still log failures as failures, with timing. This was only specific to the pre-emptive check, which is gone.

The failures can still be correlated with log errors, which will indicate cause.

@manadart manadart changed the title Retry more classes of Raft leader errors [JUJU-672] Retry more classes of Raft leader errors Feb 24, 2022
@manadart
Copy link
Member Author

$$merge$$

@jujubot jujubot merged commit 901ed81 into juju:2.9 Feb 24, 2022
@manadart manadart deleted the 2.9-retry-raft-leader-errors branch February 24, 2022 15:07
@manadart manadart mentioned this pull request Mar 7, 2022
jujubot added a commit that referenced this pull request Mar 8, 2022
#13793

Merge from 2.9 to bring forward:
- #13791 from tlm/darwin-makefile-changes
- #13790 from SimonRichardson/clean-up-error-message-for-raft-request
- #13789 from SimonRichardson/prevent-panic-in-uniter-report
- #13788 from manadart/2.9-retry-raft-leader-errors
- #13781 from tlm/caas-probe-support
- #13787 from ycliuhw/fix/nw-model-migration-amd64-gce
- #13765 from SimonRichardson/charmhub-channel-branches
- #13784 from arnodel/juju-606-remove-script
- #13740 from arnodel/juju-583-connector-interface
- #13778 from arnodel/juju-606-move-apiserver-params-to-rpc
- #13780 from arnodel/juju-582-remove-group-api-clients-script
- #13783 from benhoyt/fix-caasunitprovisioner-race
- #13782 from wallyworld/introspection-fixes
- #13773 from arnodel/juju-582-group-api-clients
- #13776 from juju/dependabot/pip/acceptancetests/cryptography-3.3.2
- #13779 from jack-w-shaw/Fix_shfmt_fail
- #13775 from ycliuhw/fix/nw-model-migration-amd64-gce
- #13568 from benhoyt/pebble-checks-integration
- #13774 from ycliuhw/disable-kubeflow-gh-action
- #13753 from jack-w-shaw/JUJU-422_Drop_Space.Subnets
- #13771 from wallyworld/fix-git-whoami
- #13754 from manadart/2.9-cleanup-force-destroy-storage
- #13770 from wallyworld/more-robust-ec2
- #13769 from ycliuhw/fix/nw-deploy-kubeflow
- #13630 from hmlanigan/set-series
- #13759 from hmlanigan/duplicate-error-messages
- #13762 from SimonRichardson/fix-charm-revisioner
- #13760 from ycliuhw/fix/nw-deploy-kubeflow
- #13761 from wallyworld/upgrade-tests
- #13758 from ycliuhw/fix/crd-upgrade
- #13659 from SimonRichardson/start-removing-model-cache-from-api
- #13747 from manadart/2.9-cleanup-enhancements
- #13744 from manadart/2.9-container-address-origin
- #13803 from tlm/darwin-makefile-changes

Conflicts:
- api/agent/provisioner/provisioner_test.go
- api/agent/uniter/state_test.go
- api/client/application/client.go
- api/client/application/client_test.go
- api/client/bundle/client_test.go
- api/controller/controller/controller.go
- api/controller/controller/controller_test.go
- api/controller/controller/gui.go
- api/controller/controller/gui_test.go
- api/controller/controller/identity_url.go
- api/controller/controller/mongo.go
- api/uniter/state_test.go
- api/uniter/uniter_test.go
- apiserver/facades/agent/upgradesteps/upgradesteps.go
- apiserver/facades/client/action/legacy.go
- apiserver/facades/client/action/legacy_test.go
- apiserver/facades/client/application/application_unit_test.go
- apiserver/facades/client/application/charmstore.go
- apiserver/facades/client/application/charmstore_test.go
- apiserver/facades/client/application/get.go
- apiserver/facades/client/backups/create.go
- apiserver/facades/client/backups/deprecated.go
- apiserver/facades/client/charmhub/charmhub.go
- apiserver/facades/client/charmhub/charmhub_test.go
- apiserver/facades/client/charmhub/convert.go
- apiserver/facades/client/client/bundles.go
- apiserver/facades/client/client/bundles_test.go
- apiserver/facades/client/cloud/cloudV2_test.go
- apiserver/facades/client/controller/controller.go
- apiserver/facades/controller/crossmodelrelations/crossmodelrelations_test.go
- apiserver/facades/controller/firewaller/firewaller_base_test.go
- apiserver/gui.go
- apiserver/gui_test.go
- caas/kubernetes/provider/bootstrap.go
- caas/kubernetes/provider/k8s.go
- cmd/containeragent/initialize/package_test.go
- cmd/juju/action/action.go
- cmd/juju/action/cancel_test.go
- cmd/juju/action/common.go
- cmd/juju/action/package_test.go
- cmd/juju/action/run_test.go
- cmd/juju/action/runaction.go
- cmd/juju/action/runaction_test.go
- cmd/juju/action/showoutput.go
- cmd/juju/action/showtask_test.go
- cmd/juju/action/status.go
- cmd/juju/action/status_test.go
- cmd/juju/application/bundle_test.go
- cmd/juju/application/removesaas_test.go
- cmd/juju/application/setseries.go
- cmd/juju/application/store/mocks/store_mock.go
- cmd/juju/caas/add_test.go
- cmd/juju/caas/update_test.go
- cmd/juju/commands/exec.go
- cmd/juju/commands/exec_test.go
- cmd/juju/commands/main_test.go
- cmd/juju/commands/mocks/statusapi_mock.go
- cmd/juju/controller/listcontrollers_test.go
- cmd/juju/controller/listmodelsold.go
- cmd/juju/gui/export_test.go
- cmd/juju/gui/gui.go
- cmd/juju/gui/gui_test.go
- cmd/juju/gui/upgradegui.go
- cmd/juju/gui/upgradegui_test.go
- cmd/juju/model/exportbundle.go
- cmd/juju/model/exportbundle_test.go
- cmd/juju/ssh/debughooks.go
- cmd/juju/ssh/ssh_container_test.go
- cmd/juju/ssh/ssh_unix_test.go
- worker/caasapplicationprovisioner/application.go
- worker/machineactions/worker.go
- worker/machineactions/worker_test.go
- worker/uniter/operation/runaction.go
- worker/uniter/remotestate/snapshot.go
- worker/uniter/runner/context/context_test.go
- worker/uniter/runner/context/mocks/hookunit_mock.go
- worker/uniter/runner/factory.go
- worker/uniter/runner/jujuc/mocks/context_mock.go
- Makefile
- go.mod
- go.sum
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants