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

SlotMap refactor: Added NodesMap, sharing shard addresses between shard nodes and slot map values. #185

Merged

Conversation

barshaul
Copy link

@barshaul barshaul commented Aug 27, 2024

This PR lays the foundation for supporting topology changes triggered by MOVED errors.

Slot Map Design

Currently, our slot map contains only a tree structure representing the slots and their associated ShardAddr, which holds the primary and replica addresses. For non-consecutive slots owned by the same shard, a new ShardAddr is created. The proposed design introduces the following enhancements:

  1. Addition of a NodesMap: This map will store node identifiers (host:port) as keys, with their corresponding ShardAddrs as values. This allows primary and replicas of the same shard to share the same ShardAddr, reducing redundancy.
  2. Read/Write Lock on ShardAddr: The ShardAddr will be wrapped in a read/write lock. The write lock will only be used when changes to the shard addresses are necessary due to MOVED errors (for example when a MOVED error suggests a failover, or in scenarios when a replica is removed from existing ShardAddr as it is promoted to a primary in a different shard).

This design allows for fast address retrieval for routing while enabling synchronized updates across multiple slots, even if they are non-consecutive. In the SlotMap’s binary tree, non-consecutive slots owned by the same shard are represented by different tree nodes for each range. In the proposed design, all these tree nodes will share the same ShardAddrs. As a result, when a ShardAddrs is updated due to a MOVED error for one slot, the change will automatically apply to all other slots owned by the same shard.

The diagram on the left represents the current design of SlotMap, while the diagram on the right illustrates the new design.
image

Full example:
image

Comment on lines -1391 to -1394
} else if moved_redirect.is_some() {
// Update relevant slots in the slots map based on the moved_redirect address,
// rather than refreshing all slots by querying the cluster nodes for their topology view.
Self::update_slots_for_redirect_change(inner.clone(), moved_redirect).await?;
Copy link
Author

@barshaul barshaul Aug 27, 2024

Choose a reason for hiding this comment

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

Removed as per the design decision, updates based on MOVED errors will be done synchronously and not as part of refresh_slots.

…hard between shard nodes and slot map values
redis/src/cluster_async/connections_container.rs Outdated Show resolved Hide resolved
redis/src/cluster_async/connections_container.rs Outdated Show resolved Hide resolved
redis/src/cluster_routing.rs Show resolved Hide resolved
redis/src/cluster_routing.rs Outdated Show resolved Hide resolved
redis/src/cluster_slotmap.rs Outdated Show resolved Hide resolved
let mut shard_id = 0;
for slot in slots {
let primary = Arc::new(slot.master);
let replicas: Vec<Arc<String>> = slot.replicas.into_iter().map(Arc::new).collect();

Choose a reason for hiding this comment

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

nit: I would make here slot.replicas_vec() method (we might be needing this one-liner elsewhere, so it makes sense to make it a function)

Copy link
Author

Choose a reason for hiding this comment

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

we don't use it elsewhere, and using this function partially moves slot so we can't consume other properties of this struct (e.g. master)

redis/src/cluster_slotmap.rs Outdated Show resolved Hide resolved
redis/src/cluster_slotmap.rs Outdated Show resolved Hide resolved
redis/src/cluster_slotmap.rs Outdated Show resolved Hide resolved

use crate::cluster_routing::{Route, ShardAddrs, Slot, SlotAddr};

pub(crate) type NodesMap = DashMap<Arc<String>, Arc<RwLock<ShardAddrs>>>;

Choose a reason for hiding this comment

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

Question:

I don't have the entire context (GitHub folds existing code etc). But from what I have seen, we don't use .write() I have only seen .read() calls. Do we need this lock?

Copy link
Author

Choose a reason for hiding this comment

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

You're correct, it hasn't been used in this PR - the write lock will be used in the next PR where i'll add support in topology updates based on MOVED errors. Then we will need to do modifications on the ShardAddrs object - for example when a MOVED error suggests a failover, or in scenarios when a replica is removed from existing ShardAddr as it is promoted to a primary in a different shard.

},
);
}

slot_map
}

#[allow(dead_code)] // used in tests

Choose a reason for hiding this comment

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

nit: "tests" (when placed on the same file) are allowed to access private members, so the test can access the property member directly

Copy link
Author

Choose a reason for hiding this comment

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

It's being used in other file, however i'm going to use it in the next PR then i'll remove the dead_code

@barshaul barshaul merged commit 8d05984 into amazon-contributing:update_slotmap_moved Aug 28, 2024
10 checks passed
barshaul added a commit that referenced this pull request Sep 12, 2024
…rd nodes and slot map values. (#185)

* SlotMap refactor: Added new NodesMap, changed shard addresses to be shard between shard nodes and slot map values
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