Repository navigation
Sync scrub superblk timestamps between leader and followers via RPC - #475
JacksonYao287 wants to merge 4 commits into
Conversation
Followers previously had no visibility into a PG's last_deep_scrub_timestamp/ last_shallow_scrub_timestamp, which the leader persists locally after each scrub. Add a PUSH_SCRUB_SUPERBLK data RPC channel and a periodic leader-side timer that pushes these timestamps to followers; each side keeps the newer value per field and the response is merged back into the leader.
cdd62c2 to
9560396
Compare
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## stable/v4.x #475 +/- ##
==============================================
Coverage ? 54.57%
==============================================
Files ? 39
Lines ? 6999
Branches ? 961
==============================================
Hits ? 3820
Misses ? 2764
Partials ? 415 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
| m_retry_timer_hdl = iomanager.schedule_thread_timer(5ull * 1000 * 1000 * 1000, true, nullptr /*cookie*/, | ||
| [this](void*) { check_scrub_timeouts(); }); | ||
| // TODO: make the interval configurable, for now set it to 30 seconds | ||
| m_push_scrub_timestamp_timer_hdl = |
There was a problem hiding this comment.
Does this mean that after this commit, we will start a periodic sync-up job by default, and on 4.x the value passed around will always be 0 because scrub is not enabled there?
Generally LGTM, but I am curious why we need to sync every 30 seconds. The scrub interval is usually on the order of days or even weeks, so do we really need such frequent synchronization? Also, if the follower has already received the value, do we still need to keep syncing it repeatedly?
There was a problem hiding this comment.
Does this mean that after this commit, we will start a periodic sync-up job by default, and on 4.x the value passed around will always be 0 because scrub is not enabled there?
no , if scrubber is disabled, scrubber->start() will not be called and this timer will not be started.
do we really need such frequent synchronization? Also, if the follower has already received the value, do we still need to keep syncing it repeatedly?
1 30 seconds , 1 minute , 1 hour or even 1 day will not make much difference for a single rpc call.
2 we need keep syncing it repeatedly since pg member will probably change(replace member) , we need let the new member be aware of this timestamp. besides, this rpc might timeout.
3 if leader crash before it syncs the latest timestamps to followers, then we lose it in this pg before it comes back. the longer interval is , the bigger possibility we have to lose it.
generally speaking, a single rpc call is very cheap here, no need to pay too much attention on the interval(frequency).
| scrub_timestamp_info sync_scrub_timestamp(const pg_id_t pg_id, const scrub_timestamp_info& incoming); | ||
|
|
||
| // leader-only: periodically push last_deep_scrub_timestamp/last_shallow_scrub_timestamp to followers of every pg | ||
| // this node leads, and merge back whatever the followers report as newer. Exposed publicly (in addition to being |
There was a problem hiding this comment.
Could you explain why we need to merge back here? My understanding is that the leader is the source of truth, so I am not fully clear on why we would update the state again based on data from the follower.
There was a problem hiding this comment.
let`s say we have A,B,C. A is leader.
after a scrub , A has the latest scrub timestamp. before this timestamp is synced to followers , leader switch happen and B becomes the new leader. B now does not have the latest scrub timestamp. when B syncs its scrub timestamp to A, A should echo back its timestamp to B, and B update its own timestamp.
A should not update its timestamp with the stale timestamp from B, even if B is leader now.
so , generall speaking, we should always keep the latest scrub timestamp across the pg, it is independent of leadership.
JacksonYao287
left a comment
There was a problem hiding this comment.
@Besroy thanks for the review, I have added my comments
| scrub_timestamp_info sync_scrub_timestamp(const pg_id_t pg_id, const scrub_timestamp_info& incoming); | ||
|
|
||
| // leader-only: periodically push last_deep_scrub_timestamp/last_shallow_scrub_timestamp to followers of every pg | ||
| // this node leads, and merge back whatever the followers report as newer. Exposed publicly (in addition to being |
There was a problem hiding this comment.
let`s say we have A,B,C. A is leader.
after a scrub , A has the latest scrub timestamp. before this timestamp is synced to followers , leader switch happen and B becomes the new leader. B now does not have the latest scrub timestamp. when B syncs its scrub timestamp to A, A should echo back its timestamp to B, and B update its own timestamp.
A should not update its timestamp with the stale timestamp from B, even if B is leader now.
so , generall speaking, we should always keep the latest scrub timestamp across the pg, it is independent of leadership.
| m_retry_timer_hdl = iomanager.schedule_thread_timer(5ull * 1000 * 1000 * 1000, true, nullptr /*cookie*/, | ||
| [this](void*) { check_scrub_timeouts(); }); | ||
| // TODO: make the interval configurable, for now set it to 30 seconds | ||
| m_push_scrub_timestamp_timer_hdl = |
There was a problem hiding this comment.
Does this mean that after this commit, we will start a periodic sync-up job by default, and on 4.x the value passed around will always be 0 because scrub is not enabled there?
no , if scrubber is disabled, scrubber->start() will not be called and this timer will not be started.
do we really need such frequent synchronization? Also, if the follower has already received the value, do we still need to keep syncing it repeatedly?
1 30 seconds , 1 minute , 1 hour or even 1 day will not make much difference for a single rpc call.
2 we need keep syncing it repeatedly since pg member will probably change(replace member) , we need let the new member be aware of this timestamp. besides, this rpc might timeout.
3 if leader crash before it syncs the latest timestamps to followers, then we lose it in this pg before it comes back. the longer interval is , the bigger possibility we have to lose it.
generally speaking, a single rpc call is very cheap here, no need to pay too much attention on the interval(frequency).
|
@xiaoxichen can you also take a look? |
|
@JacksonYao287 Thanks for the detailed explanation, LGTM. One edge case I'm not sure if needs to be considered (maybe in the future?): |
@Besroy thanks, this is a good point. I can add a push_scrub_timestamp_to_followers to on_become_leader, so that the new leader will sync scrub_timestamp as soon as it is elected |
|
@Besroy thanks for the suggestion, I have make the change , ptal |
|
Let me first ensure I read it correctly. The intent part is LGTM. Regarding the implementation, I have a few questions:
The information flow is naturally from leader to every member. If we go through raft, the consistency is ensured, no corner cases like leader switch, new leader join needed to be considered. Then we can make it only once that make a raft proposal to update PGMeta inside which update the scrub timestamp. Even if there are some corner cases, the worst case is just we lost track of "this" single PG scan timestamp It can be further extended to sync other via same message or different message, for example potentially sync the deep-scrub progress , or the scrub result...extra, extra |
|
@xiaoxichen thanks for the reivew.
if leader does not change , yes . but , as I mentioned above, after leader switch or replace member , the new leader or the new member also need to be aware of this latest timestamp. so I introduce a periodical rpc call to sync this across the entire pg.
this is actually my initial idea. but, if we add this to raft , it will be much complicated since we need to think carefully about how to handle this in BR, rollback, etc. that might bring a lot of changes and unknown issues to the well tested and stable raft path. so IMO, do not touch raft path unless it is really indeed necessary. in this PR , I use a single rpc call to achieve that goal. it works just like gossip, so we don`t need to worry about the corner cases that might be brought by raft. I have added a version number to this message (scrub_timestamp_info), so that we can extend it to v2 or v3.. to add more info in the future if we want. maybe we can change it to flatbuffer?
this not always true here, pls see #475 (comment) |
Followers previously had no visibility into a PG's last_deep_scrub_timestamp/ last_shallow_scrub_timestamp, which the leader persists locally after each scrub. Add a PUSH_SCRUB_TIMESTAMP data RPC channel and a periodic leader-side timer that pushes these timestamps to followers; each side keeps the newer value per field and the response is merged back into the leader.
after this is merged in this branch , will cherry-pick it to dev/5.x