Comments (6)
Thanks for the clarification!
from openraft.
👋 Thanks for opening this issue!
Get help or engage by:
/help
: to print help messages./assignme
: to assign this issue to you.
from openraft.
0.7.3 does not implement persistent learner storage in Membership
.
If you need this feature, use the main
branch instead. :(
from openraft.
Thanks for your response. I switched to the master branch, and I can confirm it works there!
I did want to ask about some possibly unrelated behavior: on the 0.7.x branch I saw Blank
messages were sent as heartbeats, but I didn't think they were appended to the log or applied to the state machine. In master, I see lots of Blank
traffic:
Node 1: append_to_log log_idx=LogId { leader_id: LeaderId { term: 1, node_id: 4 }, index: 69 } entry=Entry { log_id: LogId { leader_id: LeaderId { term: 1, node_id: 4 }, index: 69 }, payload: Blank }
Node 2: append_to_log log_idx=LogId { leader_id: LeaderId { term: 1, node_id: 4 }, index: 69 } entry=Entry { log_id: LogId { leader_id: LeaderId { term: 1, node_id: 4 }, index: 69 }, payload: Blank }
Node 3: append_to_log log_idx=LogId { leader_id: LeaderId { term: 1, node_id: 4 }, index: 69 } entry=Entry { log_id: LogId { leader_id: LeaderId { term: 1, node_id: 4 }, index: 69 }, payload: Blank }
Node 5: append_to_log log_idx=LogId { leader_id: LeaderId { term: 1, node_id: 4 }, index: 69 } entry=Entry { log_id: LogId { leader_id: LeaderId { term: 1, node_id: 4 }, index: 69 }, payload: Blank }
Node 4: append_to_log log_idx=LogId { leader_id: LeaderId { term: 1, node_id: 4 }, index: 70 } entry=Entry { log_id: LogId { leader_id: LeaderId { term: 1, node_id: 4 }, index: 70 }, payload: Blank }
Node 4: sending AppendEntriesRequest to 1 AppendEntriesRequest { vote: Vote { term: 1, node_id: 4, committed: true }, prev_log_id: Some(LogId { leader_id: LeaderId { term: 1, node_id: 4 }, index: 69 }), entries: [Entry { log_id: LogId { leader_id: LeaderId { term: 1, node_id: 4 }, index: 70 }, payload: Blank }], leader_commit: Some(LogId { leader_id: LeaderId { term: 1, node_id: 4 }, index: 69 }) }
Node 4: sending AppendEntriesRequest to 2 AppendEntriesRequest { vote: Vote { term: 1, node_id: 4, committed: true }, prev_log_id: Some(LogId { leader_id: LeaderId { term: 1, node_id: 4 }, index: 69 }), entries: [Entry { log_id: LogId { leader_id: LeaderId { term: 1, node_id: 4 }, index: 70 }, payload: Blank }], leader_commit: Some(LogId { leader_id: LeaderId { term: 1, node_id: 4 }, index: 69 }) }
Node 4: sending AppendEntriesRequest to 3 AppendEntriesRequest { vote: Vote { term: 1, node_id: 4, committed: true }, prev_log_id: Some(LogId { leader_id: LeaderId { term: 1, node_id: 4 }, index: 69 }), entries: [Entry { log_id: LogId { leader_id: LeaderId { term: 1, node_id: 4 }, index: 70 }, payload: Blank }], leader_commit: Some(LogId { leader_id: LeaderId { term: 1, node_id: 4 }, index: 69 }) }
Node 4: sending AppendEntriesRequest to 5 AppendEntriesRequest { vote: Vote { term: 1, node_id: 4, committed: true }, prev_log_id: Some(LogId { leader_id: LeaderId { term: 1, node_id: 4 }, index: 69 }), entries: [Entry { log_id: LogId { leader_id: LeaderId { term: 1, node_id: 4 }, index: 70 }, payload: Blank }], leader_commit: Some(LogId { leader_id: LeaderId { term: 1, node_id: 4 }, index: 69 }) }
Node 1: append_to_log log_idx=LogId { leader_id: LeaderId { term: 1, node_id: 4 }, index: 70 } entry=Entry { log_id: LogId { leader_id: LeaderId { term: 1, node_id: 4 }, index: 70 }, payload: Blank }
Node 2: append_to_log log_idx=LogId { leader_id: LeaderId { term: 1, node_id: 4 }, index: 70 } entry=Entry { log_id: LogId { leader_id: LeaderId { term: 1, node_id: 4 }, index: 70 }, payload: Blank }
Node 3: append_to_log log_idx=LogId { leader_id: LeaderId { term: 1, node_id: 4 }, index: 70 } entry=Entry { log_id: LogId { leader_id: LeaderId { term: 1, node_id: 4 }, index: 70 }, payload: Blank }
Node 5: append_to_log log_idx=LogId { leader_id: LeaderId { term: 1, node_id: 4 }, index: 70 } entry=Entry { log_id: LogId { leader_id: LeaderId { term: 1, node_id: 4 }, index: 70 }, payload: Blank }
Is that normal? It seems like heartbeats in the raft log would cause quite a bit of write amplification.
from openraft.
Follow up confirmation, this filter used to work for heartbeats:
impl RaftNetwork<ColDbRaftConfig> for GrpcNetworkConnection {
async fn send_append_entries(
&mut self,
req: AppendEntriesRequest<ColDbRaftConfig>,
) -> Result<AppendEntriesResponse<Nid>, RPCError<Nid, UuidNode, AppendEntriesError<Nid>>> {
let is_heartbeat = req.entries.is_empty();
if !is_heartbeat {
println!("Node {}: sending AppendEntriesRequest to {} {:?}", self.owner.node_id, self.target, req);
}
from openraft.
Yes, the heartbeat message is changed:
In main
branch, I was trying to implement a heartbeat with a message with a blank
log, instead of just a blank message, i.e., every heartbeat will commit a read log entry.
This simplifies the logic when granting a candidate's vote request. But it introduces unnecessary IO(to flush blank log to disk).
See:
from openraft.
Related Issues (20)
- Feature: Monoio Runtime HOT 3
- Add sync primitives to `AsyncRuntime` trait HOT 1
- Add `AsyncRuntime::oneshot` HOT 2
- RaftMsg::ExternalRequest: should not rely on RaftLogStorage and RaftNetworkFactory HOT 3
- Add random number generation to `Runtime` HOT 5
- Ditch `async_trait` in favor of the official `async_fn_in_trait` feature HOT 6
- Refactor: Move `client_resp_channels` from `LeaderData` to new `tx_...`-field in `RaftCore` HOT 2
- Linearizable read with `ReadIndex` HOT 1
- about single node HOT 6
- Cluster Bootstrap and Node Initialization Sequence HOT 4
- Tracking issue for examples update HOT 1
- Update example `raft-kv-memstore` to use `storage-v2` HOT 2
- Update example `raft-kv-rocksstore` to use `storage-v2` HOT 1
- Move examples into the workspace HOT 1
- Install Snapshot v1 api HOT 3
- Observe state changes in a Raft node HOT 6
- Split metrics into data metrics and server metrics HOT 5
- About automatic remove HOT 3
- Backing up the WAL HOT 6
- Raft Core Panicking HOT 10
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from openraft.