Skip to content

allocatorimpl: Prioritize non-voters in voter additions#89650

Merged
craig[bot] merged 1 commit intocockroachdb:masterfrom
KaiSun314:prioritize-non-voters
Oct 28, 2022
Merged

allocatorimpl: Prioritize non-voters in voter additions#89650
craig[bot] merged 1 commit intocockroachdb:masterfrom
KaiSun314:prioritize-non-voters

Conversation

@KaiSun314
Copy link
Copy Markdown
Contributor

@KaiSun314 KaiSun314 commented Oct 10, 2022

Fix #63810

Previously, when adding a voter via the allocator, we would not prioritize stores with non-voters when selecting candidate stores.

This was inadequate because selecting a store without a non-voter would require sending a snapshot over the WAN in order to add a voter onto that store. On the other hand, selecting a store with a non-voter would only require promoting that non-voter to a voter, no snapshot needs to be sent over the WAN.

To address this, this patch determines if candidate stores have a non-voter replica and prioritize this status when sorting candidate stores (priority lower than balance score, but higher than range count). By prioritizing selecting a store with a non-voter, we can reduce the number of snapshots that need to be sent over the WAN.

Release note (ops change): We prioritized non-voters in voter additions, meaning that when selecting a store to add a voter on (in the allocator), we would prioritize candidate stores that contain a non-voter replica higher. This allows us to reduce the number of snapshots that need to be sent over the WAN.

@cockroach-teamcity
Copy link
Copy Markdown
Member

This change is Reviewable

@KaiSun314 KaiSun314 requested a review from kvoli October 10, 2022 13:23
@KaiSun314 KaiSun314 force-pushed the prioritize-non-voters branch from 46491eb to a9e862d Compare October 10, 2022 14:47
Copy link
Copy Markdown
Contributor

@kvoli kvoli left a comment

Choose a reason for hiding this comment

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

Great work on this so far. A few things to add in:

(1) Update the score fn to be consistent in ordering values it returns
(2) Add some testing to exercise the example we want this to work in, then a few where there's too great imbalance or other reasons where a non-voter exists for promotion but we don't want to promote it.

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @KaiSun314)


pkg/kv/kvserver/allocator/allocatorimpl/allocator_scorer.go line 693 at r1 (raw file):

		return -(1 + (float64(o.balanceScore-c.balanceScore))/10.0)
	}
	if c.hasNonVoter != o.hasNonVoter {

The above scores are strictly ordered. The 10 is out of order with the other scores returned:

...
converges (+-)[2,3]
balance (+-)[1,2]
nonVoter +-10

This is fine for calling Less which is used to sort them and for allocation.

However it does matter for rebalancing, which won't be in this patch here but we should keep consistent to avoid confusion in the future.

https://github.com/cockroachdb/cockroach/blob/20e55fcca7651472a6b112900c413e67b270979f/pkg/roachpb/data.pb.go#L285-L288

We can adjust the other values up and slot this one in below. or just return a value in the range (+-)[0,1).

@KaiSun314 KaiSun314 force-pushed the prioritize-non-voters branch 2 times, most recently from 422afa8 to cb0e4cd Compare October 11, 2022 20:00
Copy link
Copy Markdown
Contributor Author

@KaiSun314 KaiSun314 left a comment

Choose a reason for hiding this comment

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

(1) Done - added a bunch of unit 0s
(2) Done - added 3 unit tests:

  1. One store with non-voter and range count 516 + one store with voter and range count 480 - make sure allocator selects store with the non-voter despite higher range count
  2. Stores with non-voter and range count > 475 + one store with voter and range count < 475 (resulting in different balance scores) - make sure allocator selects store with the voter due to higher balance score
  3. One store with non-voter and range count 516 but does not satisfy voter constraint + one store with voter and range count 480 that satisfies voter constraint - make sure allocator selects store with voter that satisfies voter constraint

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @kvoli)


pkg/kv/kvserver/allocator/allocatorimpl/allocator_scorer.go line 693 at r1 (raw file):

Previously, kvoli (Austen) wrote…

The above scores are strictly ordered. The 10 is out of order with the other scores returned:

...
converges (+-)[2,3]
balance (+-)[1,2]
nonVoter +-10

This is fine for calling Less which is used to sort them and for allocation.

However it does matter for rebalancing, which won't be in this patch here but we should keep consistent to avoid confusion in the future.

https://github.com/cockroachdb/cockroach/blob/20e55fcca7651472a6b112900c413e67b270979f/pkg/roachpb/data.pb.go#L285-L288

We can adjust the other values up and slot this one in below. or just return a value in the range (+-)[0,1).

Done.

@KaiSun314 KaiSun314 force-pushed the prioritize-non-voters branch 2 times, most recently from ca5dbe8 to 08176bf Compare October 11, 2022 22:04
@kvoli kvoli marked this pull request as ready for review October 17, 2022 22:55
@kvoli kvoli requested a review from a team as a code owner October 17, 2022 22:55
Copy link
Copy Markdown
Contributor

@kvoli kvoli left a comment

Choose a reason for hiding this comment

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

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @KaiSun314)


pkg/kv/kvserver/allocator/allocatorimpl/allocator_test.go line 8186 at r2 (raw file):

}

func TestNonVoterPrioritizationInVoterAdditions(t *testing.T) {

Could you add the test scenario descriptions that you mentioned, above each test case to make this easier to parse for future readers.

// NB: ... is overfull despite having a nonvoter, we select store X.

pkg/kv/kvserver/allocator/allocatorimpl/allocator_test.go line 8280 at r2 (raw file):

			},
			expectedTargetAllocate: roachpb.ReplicationTarget{NodeID: 4, StoreID: 4},
		},

Could you add in the test case from the issue.

Perhaps in a TestMultiiRegion... , just so we can cover our cases.

region 1: voter (leaseholder), voter, voter
region 2: non-voter
region 3: non-voter

@KaiSun314 KaiSun314 force-pushed the prioritize-non-voters branch from 08176bf to 178631c Compare October 25, 2022 15:49
Copy link
Copy Markdown
Contributor Author

@KaiSun314 KaiSun314 left a comment

Choose a reason for hiding this comment

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

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @kvoli)


pkg/kv/kvserver/allocator/allocatorimpl/allocator_test.go line 8186 at r2 (raw file):

Previously, kvoli (Austen) wrote…

Could you add the test scenario descriptions that you mentioned, above each test case to make this easier to parse for future readers.

// NB: ... is overfull despite having a nonvoter, we select store X.

Done.


pkg/kv/kvserver/allocator/allocatorimpl/allocator_test.go line 8280 at r2 (raw file):

Previously, kvoli (Austen) wrote…

Could you add in the test case from the issue.

Perhaps in a TestMultiiRegion... , just so we can cover our cases.

region 1: voter (leaseholder), voter, voter
region 2: non-voter
region 3: non-voter

Done.

Copy link
Copy Markdown
Contributor Author

@KaiSun314 KaiSun314 left a comment

Choose a reason for hiding this comment

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

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @kvoli)


pkg/kv/kvserver/allocator/allocatorimpl/allocator_test.go line 8280 at r2 (raw file):

Previously, KaiSun314 (Kai Sun) wrote…

Done.

In replicate_queue_test.go

Copy link
Copy Markdown
Contributor

@kvoli kvoli left a comment

Choose a reason for hiding this comment

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

small nits otherwise great stuff

:lgtm_strong:

Reviewed 1 of 3 files at r2, 1 of 3 files at r3, all commit messages.
Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (waiting on @KaiSun314)


pkg/kv/kvserver/replicate_queue_test.go line 2015 at r3 (raw file):

			Knobs: base.TestingKnobs{
				SpanConfig: &spanconfig.TestingKnobs{
					ConfigureScratchRange: true,

nit: I don't think you need this field anymore.


pkg/kv/kvserver/replicate_queue_test.go line 2033 at r3 (raw file):

	// predictable behaviour when the allocator ranks stores using balance score.
	_, err := db.Exec(
		"ALTER DATABASE system CONFIGURE ZONE USING num_replicas = 7, num_voters = 7",

nit: Add a local function

initConstraintFn := func(count int, range string) { ... }
initConstraintFn(7, "system")
...
initConstraintFn(7, "default")

@KaiSun314 KaiSun314 force-pushed the prioritize-non-voters branch 2 times, most recently from 0d9f478 to 35a46a9 Compare October 27, 2022 15:30
Copy link
Copy Markdown
Contributor Author

@KaiSun314 KaiSun314 left a comment

Choose a reason for hiding this comment

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

Thank you for the review Austen!

Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (waiting on @kvoli)

@KaiSun314
Copy link
Copy Markdown
Contributor Author

bors r=kvoli

@craig
Copy link
Copy Markdown
Contributor

craig bot commented Oct 27, 2022

🕐 Waiting for PR status (Github check) to be set, probably by CI. Bors will automatically try to run when all required PR statuses are set.

@craig
Copy link
Copy Markdown
Contributor

craig bot commented Oct 27, 2022

GitHub status checks took too long to complete, so bors is giving up. You can adjust bors configuration to have it wait longer if you like.

Previously, when adding a voter via the allocator, we would not
prioritize stores with non-voters when selecting candidate stores.

This was inadequate because selecting a store without a non-voter would
require sending a snapshot over the WAN in order to add a voter onto
that store. On the other hand, selecting a store with a non-voter would
only require promoting that non-voter to a voter, no snapshot needs to
be sent over the WAN.

To address this, this patch determines if candidate stores have a
non-voter replica and prioritize this status when sorting candidate
stores (priority lower than balance score, but higher than range
count). By prioritizing selecting a store with a non-voter, we can
reduce the number of snapshots that need to be sent over the WAN.

Release note (ops change): We prioritized non-voters in voter
additions, meaning that when selecting a store to add a voter on (in the
allocator), we would prioritize candidate stores that contain a
non-voter replica higher. This allows us to reduce the number of
snapshots that need to be sent over the WAN.
@KaiSun314 KaiSun314 force-pushed the prioritize-non-voters branch from 35a46a9 to c637e64 Compare October 27, 2022 18:39
@KaiSun314
Copy link
Copy Markdown
Contributor Author

bors r=kvoli

@craig
Copy link
Copy Markdown
Contributor

craig bot commented Oct 28, 2022

Build failed:

@KaiSun314
Copy link
Copy Markdown
Contributor Author

bors r=kvoli

@craig
Copy link
Copy Markdown
Contributor

craig bot commented Oct 28, 2022

This PR was included in a batch that was canceled, it will be automatically retried

@craig
Copy link
Copy Markdown
Contributor

craig bot commented Oct 28, 2022

Build succeeded:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

kv: switching from ZONE to REGION survival causes unexpected data movement

3 participants