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

raftstore: use read index to serve read request #1642

Merged
merged 12 commits into from
Mar 3, 2017

Conversation

BusyJay
Copy link
Member

@BusyJay BusyJay commented Feb 22, 2017

This pr is a clean version for #1628. Original version has too much conflict with master, so I rewrite it again.

@siddontang @hhkbp2 @zhangjinpeng1987 PTAL

@BusyJay
Copy link
Member Author

BusyJay commented Feb 23, 2017

PTAL

@siddontang
Copy link
Contributor

Please fix the conflict.

});
self.raft_group.advance_apply(res.apply_state.get_applied_index());
self.mut_store().apply_state = res.apply_state.clone();
if has_split {
Copy link
Contributor

Choose a reason for hiding this comment

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

should use blank to separate the different logic.

term: self.term(),
renew_lease_time: Some(renew_lease_time),
};
let mut req = RaftCmdRequest::new();
Copy link
Contributor

Choose a reason for hiding this comment

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

if we send an invalid request, seem that we will log an error when apply the error, it is a little strange.

Copy link
Member Author

Choose a reason for hiding this comment

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

Actually, this command should be filtered by stale epoch.

Copy link
Contributor

Choose a reason for hiding this comment

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

So we will log an info message for it?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes.

// update leader lease.

let uuid = Uuid::new_v4();
if self.proposals.contains(&uuid) {
Copy link
Contributor

Choose a reason for hiding this comment

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

seem it is a bug for the uuid lib if we have already had a same uuid.

Copy link
Member Author

Choose a reason for hiding this comment

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

In contrast, with version 1 and 2 UUIDs using randomly-generated node ids, hash-based version 3 and 5 UUIDs, and random version 4 UUIDs, collisions can occur even without implementation problems, albeit with a probability so small that it can normally be ignored.

https://en.wikipedia.org/wiki/Universally_unique_identifier#Collisions

Copy link
Contributor

Choose a reason for hiding this comment

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

got it

@BusyJay
Copy link
Member Author

BusyJay commented Feb 27, 2017

PTAL

@BusyJay BusyJay force-pushed the busyjay/use-safe-read-index-2 branch from c8e7234 to fc5dc45 Compare February 27, 2017 08:21
@@ -690,6 +723,17 @@ impl Peer {

let mut ready = self.raft_group.ready_since(self.last_ready_idx);

if ready.ss.as_ref().map_or(false, |s| s.raft_state != StateRole::Leader) {
Copy link
Contributor

Choose a reason for hiding this comment

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

extract this to a function

@@ -779,6 +823,31 @@ impl Peer {
}
}

let mut propose_time = None;
Copy link
Contributor

Choose a reason for hiding this comment

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

extract to a function

for (req, cb) in read.cmds {
self.handle_read(req, cb);
}
propose_time = Some(read.renew_lease_time);
Copy link
Contributor

Choose a reason for hiding this comment

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

no need to reduce pending_reads.ready_cnt 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.

ready_cnt is zero if this line is reached.

Copy link
Contributor

Choose a reason for hiding this comment

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

but I only see setting ready_cnt to 0 in L839

for (req, cb) in read.cmds {
let uuid = util::get_uuid_from_req(&req).unwrap();
apply::notify_stale_req(tag, term, uuid, cb);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

do we need to set ready_cnt to 0 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.

No, committed reads can still be handled.

@siddontang
Copy link
Contributor

PTAL @hhkbp2

@@ -564,10 +598,9 @@ impl Peer {
send_to_quorum_ts + self.cfg.raft_store_max_leader_lease
}

fn update_leader_lease(&mut self, ready: &Ready) {
fn on_role_changed(&mut self, ready: &Ready) {
// Update leader lease when the Raft state changes.
Copy link
Contributor

Choose a reason for hiding this comment

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

The comments should be updated when the function changes with its name modified.

return false;
}
// TODO: add it in queue directly.
return Ok(RequestPolicy::ReadIndex);
Copy link
Contributor

Choose a reason for hiding this comment

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

Similarly maybe it should check commit_index == current term here and return ProposeNormal since raft will drop the request directly.

Copy link
Member Author

Choose a reason for hiding this comment

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

No, this pr's goal is to avoid propose read request. No matter if commit_index is equal to current term or not, this is handled properly in read_index.

@@ -139,6 +163,14 @@ pub struct ConsistencyState {
pub hash: Vec<u8>,
}

enum RequestPolicy {
Copy link
Contributor

Choose a reason for hiding this comment

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

It's nice to add some comments for each policy to describe briefly what/how is a local read, read index request, consistent read, consistent write, etc., since it helps to understand and these terms lives in related comments.

@@ -599,6 +640,13 @@ impl Peer {
self.get_store().committed_index() == self.get_store().applied_index()
}

#[inline]
pub fn ready_to_handle_read(&self) -> bool {
// If committed_index doesn't equal to applied_index, written apply state may be overwritten
Copy link
Contributor

Choose a reason for hiding this comment

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

The comments doesn't match the code, it's possible that the committed_index != applied_index while applied_index_term == self.term().

for state in &ready.read_states {
let read = &self.pending_reads.reads[self.pending_reads.ready_cnt];
assert_eq!(state.request_ctx.as_slice(), read.uuid.as_bytes());
self.pending_reads.ready_cnt += 1;
Copy link
Contributor

Choose a reason for hiding this comment

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

It should record state.index for the read request, and check this state.index before performing read, after the log entry of this index is applied.

Copy link
Contributor

Choose a reason for hiding this comment

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

any update?


// Check if the leader does a consistent read and renew its lease.
// Check if the leader also propose an entry renew its lease.
Copy link
Contributor

Choose a reason for hiding this comment

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

s/renew/to renew/

let state: RaftLocalState = engine.get_msg_cf(storage::CF_RAFT, &state_key).unwrap().unwrap();
assert_eq!(state.get_last_index(), last_index + 1);

// wait some time to make the proposal to be applied.
Copy link
Contributor

Choose a reason for hiding this comment

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

s/to make/for/

@@ -107,21 +127,20 @@ fn test_renew_lease<T: Simulator>(cluster: &mut Cluster<T>) {
cluster.cfg.raft_store.raft_log_gc_threshold = 100;
Copy link
Contributor

Choose a reason for hiding this comment

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

Those comments in this file need to be updated, since a "consistent read" has change from "write a raft log to raft quorum" to "handle a read index request by cluster with ReadOnlyOption::Safe option enabled".

@hhkbp2
Copy link
Contributor

hhkbp2 commented Mar 1, 2017

Rest LGTM

self.raft_group.read_index(uuid.as_bytes().to_vec());

let pending_read_count = self.raft_group.raft.pending_read_count();
let ready_read_count = self.raft_group.raft.ready_read_count();
Copy link
Contributor

Choose a reason for hiding this comment

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

checking pending_read_count or ready_read_count only is enough?

Copy link
Member Author

Choose a reason for hiding this comment

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

No. The message may be either marked as ready immediately or pushed to pending queue.

@BusyJay
Copy link
Member Author

BusyJay commented Mar 3, 2017

Ping

@hhkbp2
Copy link
Contributor

hhkbp2 commented Mar 3, 2017

LGTM

Copy link
Contributor

@siddontang siddontang left a comment

Choose a reason for hiding this comment

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

LGTM

@BusyJay
Copy link
Member Author

BusyJay commented Mar 3, 2017

@siddontang @hhkbp2 PTAL

@siddontang
Copy link
Contributor

LGTM

1 similar comment
@hhkbp2
Copy link
Contributor

hhkbp2 commented Mar 3, 2017

LGTM

@BusyJay BusyJay merged commit c9fc4fc into master Mar 3, 2017
@BusyJay BusyJay deleted the busyjay/use-safe-read-index-2 branch March 3, 2017 12:58
iosmanthus pushed a commit to iosmanthus/tikv that referenced this pull request Oct 17, 2024
Signed-off-by: Ray Yan <yming0221@gmail.com>
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.

4 participants