Skip to content

Introduce plumtree broadcast method in corrosion.#492

Open
somtochiama wants to merge 13 commits into
mainfrom
somto/test-bcast
Open

Introduce plumtree broadcast method in corrosion.#492
somtochiama wants to merge 13 commits into
mainfrom
somto/test-bcast

Conversation

@somtochiama

@somtochiama somtochiama commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

This pull requests adds a new plumtree protocol for broadcasting changes across a cluster. It is modelled after the original plumtree protocol outlined in the original paper but it differs in a number of key ways.

  1. Full membership: Corrosion's plumtree protocol is built top of SWIM, a full membership protocol while the paper uses hyparview which is a partial membership. A node knows about every node in the cluster, and randomly selects eager and lazy peers from known peers.
  2. Multi-sender: The original plumtree protocol is ideal for single-sender trees but we have multi-master setup where every node can disseminate changes. To make the tree stable under many concurrent senders:
    • We tolerate a configurable number of duplicates: a PRUNE is only sent once a duplicate count crosses prune_threshold, rather than on the first duplicate. We trade a little duplication for tree stability, since we're trying to find peers that are good sources across multiple senders. This also has the additional benefit that each node has multiple links for a particular sender so that a failed node doesn't
    • Links are asymmetric: receiving a gossip from a peer does not add them to our eager set. A peer is only promoted to eager when it deliberately sends a GRAFT.
  3. Fanout: We use a much wider fanout than recommended in the paper, while the paper recommends a fanout of five we adjust based on the current number of nodes in the cluster to (log N * 3). This is mostly because we are aiming for lower latency, and can tolerate some duplication.
  4. RTT-aware peer selection: Rather than picking eager and lazy peers at random, we bias toward low-RTT peers for the eager set, with a handful of far ones mixed in so messages still spread quickly across clusters that aren't close to each other. This would still get adjusted via prunes and grafts by the protocol.

The plumtree method can be enabled by adding this to the node config

[gossip]
broadcast_method = "plumtree"

This was partly inspired by: https://github.com/johnnywale/memberlist-plumtree

@somtochiama somtochiama requested a review from gorbak25 June 24, 2026 14:45
Signed-off-by: Somtochi Onyekwere <somtochionyekwere@gmail.com>

@gorbak25 gorbak25 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Amazing work! Mostly nits. The main thing i'm worrying about is that there are no tests for rebalancing the tree when a peer gets down/shuts down ungracefully. I don't see other peers getting notified that we're down on graceful shutdown.

Comment thread doc/config/gossip.md Outdated
Comment thread doc/config/gossip.md

Lower values optimize the tree more aggressively (more `GRAFT`/`PRUNE` churn); higher values leave the tree alone unless the improvement is large. Defaults to `7`.

##### `batch_gossip`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Does it seem that we will use that option?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, Batching gossips didn't help smaller regional clusters. But I think it would be useful on global clusters that is pushing a lot of changes.

Comment thread crates/plum-foca/tests/sim.rs Outdated
Comment thread crates/plum-foca/tests/sim.rs Outdated
Comment thread crates/plum-foca/tests/sim.rs Outdated
Comment thread crates/plum-foca/src/lib.rs Outdated
let (near_pool, mid_pool, far_pool) = self.bucket_pools();

// we mostly want eager peers to be low rtt, but throw in a mix of mid and far peers;
// percentage is roughly 50% near, 30% mid, 20% far. targets are computed over the

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we make that ratio configurable and exposed in the config?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

That sounds good

@@ -0,0 +1,2209 @@
use indexmap::{IndexMap, IndexSet};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Amazing work! The main thing which is missing is to send PRUNE's to eager peers during graceful node shutdown. Imagine we run systemctl stop corrosion2 on an node which has a lot of links. Without graceful handling we would need to first wait for foca to decect the peer is down, then plumtree will remove that peer and only after a few missed rounds the tree will get rebalanced. What is the round interval?

@somtochiama somtochiama Jul 6, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

fair, Mostly left membership notifications to foca.

Because tree is not symmetric - we could have eager peers that don't have us an eager peer. So prune only saves them from sending us a message. We could maintain a separate set with this info though, although foca is quick enough that I don't think that it is worth it.

plumtree will remove that peer and only after a few missed rounds the tree will get rebalanced.

Any missed messages would cause grafts before foca even sends the notifications.

}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PlumtreeConfig {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

round interval?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Do you mean number of rounds when we keep broadcasting a message?

#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct PlumtreeStats {
/// Peers we push GOSSIP to directly (the spanning-tree branches).
pub eager_peers: Vec<ActorId>,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

OFFTOP: I'm tempted to vibe code a visualization of this :D Imagine we would query those edges every few seconds and we could lookup how the tree looks like

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ha, that's a very good idea. We could easily see the tree and how it is changing.

counter!("corro.plumtree.send.dropped").increment(1);
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

prune eager links to other peers or notify them that we're down?

Signed-off-by: Somtochi Onyekwere <somtochionyekwere@gmail.com>
Signed-off-by: Somtochi Onyekwere <somtochionyekwere@gmail.com>
Signed-off-by: Somtochi Onyekwere <somtochionyekwere@gmail.com>
Signed-off-by: Somtochi Onyekwere <somtochionyekwere@gmail.com>
Signed-off-by: Somtochi Onyekwere <somtochionyekwere@gmail.com>
Signed-off-by: Somtochi Onyekwere <somtochionyekwere@gmail.com>
Signed-off-by: Somtochi Onyekwere <somtochionyekwere@gmail.com>
Signed-off-by: Somtochi Onyekwere <somtochionyekwere@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.

2 participants