Add stemedb-cluster crate implementing horizontal scaling: - SWIM-based membership protocol for node discovery and failure detection - Consistent hashing (jump hash) for subject-to-shard routing - Range management with dynamic split (>64MB) and merge (<20MB) operations - Stateless HTTP gateway for client request routing via axum - Meta-range gossip merge for cluster-wide metadata propagation Includes restrictive CORS policy, proper error propagation from routing, replica cache invalidation on node failure, and 84 tests (57 unit + 27 integration). Raft MV coordination deferred per design decision. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
74 lines
2.3 KiB
Rust
74 lines
2.3 KiB
Rust
//! Multi-node cluster coordination for StemeDB.
|
|
//!
|
|
//! This crate implements the cluster layer for StemeDB, enabling horizontal
|
|
//! scaling across multiple nodes:
|
|
//!
|
|
//! - **Membership**: SWIM-based protocol for node discovery and failure detection
|
|
//! - **Sharding**: Consistent hashing for data distribution across nodes
|
|
//! - **Gateway**: Stateless HTTP router for client request routing
|
|
//!
|
|
//! # Architecture
|
|
//!
|
|
//! ```text
|
|
//! [Client]
|
|
//! |
|
|
//! v
|
|
//! [Gateway] -----> [Node 1] <---> [SWIM Gossip] <---> [Node 2]
|
|
//! | | |
|
|
//! v v v
|
|
//! [RangeRouter] [Shard 0,2] [Shard 1,3]
|
|
//! ```
|
|
//!
|
|
//! # Node Discovery
|
|
//!
|
|
//! Nodes discover each other using the SWIM protocol:
|
|
//!
|
|
//! 1. New node contacts seed nodes from configuration
|
|
//! 2. Seed nodes share their membership list
|
|
//! 3. SWIM gossip propagates membership changes
|
|
//! 4. Failed nodes detected via ping/indirect-probe
|
|
//!
|
|
//! # Data Sharding
|
|
//!
|
|
//! Assertions are distributed across shards using consistent hashing:
|
|
//!
|
|
//! 1. Subject string is hashed using BLAKE3
|
|
//! 2. Jump hash maps hash to shard ID
|
|
//! 3. Each shard has N replicas for fault tolerance
|
|
//! 4. Ranges can split (>64MB) or merge (<20MB combined)
|
|
//!
|
|
//! # Usage
|
|
//!
|
|
//! ```ignore
|
|
//! use stemedb_cluster::{ClusterConfig, SwimMembership, Gateway};
|
|
//!
|
|
//! // Configure cluster
|
|
//! let config = ClusterConfig::builder()
|
|
//! .with_seed_node("node1.example.com:9090")
|
|
//! .with_replication_factor(3)
|
|
//! .build()?;
|
|
//!
|
|
//! // Start membership protocol
|
|
//! let membership = SwimMembership::new(config.swim.clone()).await?;
|
|
//! membership.join(config.seed_nodes.clone()).await?;
|
|
//!
|
|
//! // Start gateway (if this is a gateway node)
|
|
//! let gateway = Gateway::new(membership.clone(), router);
|
|
//! gateway.serve("0.0.0.0:8080").await?;
|
|
//! ```
|
|
|
|
#![forbid(unsafe_code)]
|
|
#![warn(missing_docs)]
|
|
|
|
pub mod config;
|
|
pub mod error;
|
|
pub mod gateway;
|
|
pub mod membership;
|
|
pub mod sharding;
|
|
|
|
pub use config::{ClusterConfig, ShardingConfig, SwimConfig};
|
|
pub use error::{ClusterError, Result};
|
|
pub use gateway::{Gateway, GatewayBuilder};
|
|
pub use membership::{MembershipEvent, NodeId, NodeInfo, NodeState, SwimMembership};
|
|
pub use sharding::{MetaRange, RangeDescriptor, RangeManager, RangeRouter, ShardId};
|