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

raft: clean-up log conflict search #126318

Merged
merged 3 commits into from
Jun 27, 2024
Merged

Conversation

pav-kv
Copy link
Collaborator

@pav-kv pav-kv commented Jun 27, 2024

Use the new entryID and logSlice types. Move the preceding entry check into the conflict search method rather than do it outside. Add a bunch of TODOs for optimization: most log append requests can skip the term check scanning or do it more efficiently.

Epic: CRDB-37516
Release note: none

@pav-kv pav-kv requested a review from a team June 27, 2024 11:55
@cockroach-teamcity
Copy link
Member

This change is Reviewable

@pav-kv pav-kv force-pushed the log-find-conflict branch 2 times, most recently from 6af12f3 to efe2947 Compare June 27, 2024 12:04
@pav-kv pav-kv requested review from miraradeva and arulajmani June 27, 2024 12:19
Copy link
Contributor

@miraradeva miraradeva left a comment

Choose a reason for hiding this comment

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

:lgtm:

Just a couple of questions, for my own understanding of Raft.

Reviewed 1 of 1 files at r1, 2 of 2 files at r2.
Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (waiting on @arulajmani and @pav-kv)


pkg/raft/log.go line 165 at r2 (raw file):

	// Check the term match at min(s.lastIndex(), l.lastIndex()) entry, and fall
	// back to conflict search only if it mismatches.
	// TODO(pav-kv): also, there should be no mismatch if s.term == l.accTerm, so

What's l.accTerm?


pkg/raft/log.go line 170 at r2 (raw file):

	// TODO(pav-kv): every matchTerm call in the linear scan below can fall back
	// to fetching an entry from storage. This is inefficient, we can improve it.
	// Logs that don't match at one index, don't match at all indices above. So we

Is this always true? Could two logs have disjoint matching parts? E.g. if the second entry with term 1 below is missing from the second log:
log1: (index: 1, term: 1), (index: 2, term: 1), (index: 3, term: 2), (index: 4, term: 3) ...
log2: (index: 1, term: 1), (index: 2, term: 2), (index: 3, term: 3), (index: 4, term: 3) ...

Or will the missing entry correspond to a missing index as well? So it will look like this:
log1: (index: 1, term: 1), (index: 2, term: 1), (index: 3, term: 2), (index: 4, term: 3) ...
log2: (index: 1, term: 1), (index: 3, term: 2), (index: 4, term: 3), (index: 5, term: 3) ...

It seems like it's the latter, based on the Log Matching property of raft you mention above.

Copy link
Collaborator Author

@pav-kv pav-kv 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! 1 of 0 LGTMs obtained (waiting on @arulajmani and @miraradeva)


pkg/raft/log.go line 165 at r2 (raw file):

Previously, miraradeva (Mira Radeva) wrote…

What's l.accTerm?

It is the term of the leader whose append we accepted last:

cockroach/pkg/raft/raft.go

Lines 348 to 363 in 5769b24

// accTerm is the term of the leader whose append was accepted into the log
// last. Note that a rejected append does not update accTerm, by definition.
//
// Invariant: the log is a prefix of the accTerm's leader log
// Invariant: raftLog.lastEntryID().term <= accTerm <= Term
//
// In steady state, accTerm == Term. When someone campaigns, Term briefly
// overtakes the accTerm. However, accTerm catches up as soon as we accept a
// log append from the new leader.
//
// NB: the log can be partially or fully compacted. When we say "log" above,
// we logically include all the entries that were the pre-image of a snapshot,
// as well as the entries that are still physically in the log.
//
// TODO(pav-kv): move accTerm to raftLog.
accTerm uint64

By raft invariants, we have a guarantee that our log is a prefix of the accTerm leader's log. So, if the accTerm leader sends us log appends, we may skip all the matchTerm checks (they will all succeed).


pkg/raft/log.go line 170 at r2 (raw file):

Previously, miraradeva (Mira Radeva) wrote…

Is this always true? Could two logs have disjoint matching parts? E.g. if the second entry with term 1 below is missing from the second log:
log1: (index: 1, term: 1), (index: 2, term: 1), (index: 3, term: 2), (index: 4, term: 3) ...
log2: (index: 1, term: 1), (index: 2, term: 2), (index: 3, term: 3), (index: 4, term: 3) ...

Or will the missing entry correspond to a missing index as well? So it will look like this:
log1: (index: 1, term: 1), (index: 2, term: 1), (index: 3, term: 2), (index: 4, term: 3) ...
log2: (index: 1, term: 1), (index: 3, term: 2), (index: 4, term: 3), (index: 5, term: 3) ...

It seems like it's the latter, based on the Log Matching property of raft you mention above.

Yes, it is the latter. Both of the following are true:

  • if two logs have the same entry at index, then all the entries at lower indices match too
  • if two logs mismatch at some index, they also mismatch at all higher indices

This is true because all the entries in raft form a tree. See "Background" section in etcd-io/raft#144 for more details.

pav-kv added 3 commits June 27, 2024 15:46
Epic: none
Release note: none
Use the new entryID and logSlice types. Move the preceding entry check
into the conflict search method rather than do it outside. Add a bunch
of TODOs for optimization: most log append requests can skip the term
check scanning or do it more efficiently.

Epic: none
Release note: none
The append function call right after this does the same check, we don't
need to do this in two places. TestLogMaybeAppend exercises these
panics, and confirms the behaviour is the same after the first panic is
removed.

Epic: none
Release note: none
@pav-kv pav-kv force-pushed the log-find-conflict branch from efe2947 to 8a7cfe0 Compare June 27, 2024 14:49
@pav-kv
Copy link
Collaborator Author

pav-kv commented Jun 27, 2024

bors r=miraradeva

@craig craig bot merged commit a817ebc into cockroachdb:master Jun 27, 2024
22 checks passed
@pav-kv pav-kv deleted the log-find-conflict branch June 27, 2024 16:58
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.

3 participants