starshard

Starshard

Build crates.io docs.rs License Downloads

English 简体中文

Starshard 是一个高性能、延迟初始化分片的并发 HashMap。

它面向真实生产场景,重点解决:

当前状态

当前 crate 版本为 2.4.0。发布变更记录在 CHANGELOG.md。

截至 v2.4.0 已交付的 Roadmap 主能力:

从 2.3.x 升级时,快照版本改为标识已提交数据,无效复制拓扑会被拒绝。使用高级 API 前请阅读 2.4 升级说明。本轮优化有操作次数与分配次数证据,具体负载的吞吐和 p99 仍需实测。

安装

[dependencies]
starshard = { version = "2.4.0", features = ["async", "rayon", "serde", "lifecycle", "advanced"] }
# 最小依赖:
# starshard = "2.4.0"

5 分钟上手路径

  1. 先用默认同步 map:ShardedHashMap::new(64)。
  2. 如果在 Tokio 运行时内,切换到 AsyncShardedHashMap。
  3. 如果快照调用频繁,先尝试 SnapshotMode::Cached,再评估 SnapshotMode::Cow。
  4. 如果分片数量来自用户输入或外部配置,优先用严格构造器(try_with_*)。

迁移说明:

特性开关

Feature 能力 典型场景
async AsyncShardedHashMap(Tokio RwLock) 异步服务与任务系统
rayon 大型同步快照;启用 lifecycle 时支持 IterBuilder 并行过滤 大规模扫描和较重的过滤计算
serde 同步版序列化/反序列化 + 异步快照序列化辅助 持久化与数据导出
lifecycle per_shard_load、memory_stats、drain 等 运维观测与维护
advanced 事务/CAS/复制/诊断 API 高级并发控制与控制面

快速上手(同步)

use starshard::ShardedHashMap;

let m: ShardedHashMap<String, i32> = ShardedHashMap::new(64);
m.insert("k1".into(), 10);
assert_eq!(m.get_borrowed("k1"), Some(10));
assert_eq!(m.len(), 1);

快速上手(异步)

#[cfg(feature = "async")]
#[tokio::main]
async fn main() {
    use starshard::AsyncShardedHashMap;

    let m: AsyncShardedHashMap<String, i32> = AsyncShardedHashMap::new(64);
    m.insert("k1".into(), 10).await;
    assert_eq!(m.get_borrowed("k1").await, Some(10));
}

常用操作速查

目标 同步 API 异步 API
插入/更新 insert(k, v) insert(k, v).await
读取 get(&k) get(&k).await
借用键读取 get_borrowed(q) get_borrowed(q).await
删除 remove(&k) remove(&k).await
entry 插入/更新 entry(k).or_insert_with(f) entry(k).await.or_insert_with(f).await
获取或插入 get_or_insert_with(k, f) get_or_insert_with(k, f).await
批量插入 batch_insert(items) batch_insert(items).await
批量读取 batch_get(&keys) batch_get(&keys).await
条件更新 compute_if_present(&k, f) compute_if_present(&k, f).await
条件插入 compute_if_absent(k, f) compute_if_absent(k, f).await
指标/内省 shard_stats() / memory_stats() shard_stats().await / memory_stats().await

使用 get_borrowed、contains_borrowed、remove_borrowed 可传入借用键,例如用 &str 查询 String 键。原有 get、contains、remove 保留 &K 签名;读取仍返回克隆后的值。

Entry 风格插入/更新:

use starshard::ShardedHashMap;

let map: ShardedHashMap<String, usize> = ShardedHashMap::new(16);
let value = map
    .entry("read-version".to_string())
    .and_modify(|count| *count += 1)
    .or_insert_with(|| 1);
assert_eq!(value, 1);

原子 get-or-create 辅助方法:

use starshard::ShardedHashMap;

let map: ShardedHashMap<String, Vec<u64>> = ShardedHashMap::new(16);
let lane = map.get_or_insert_with("read-version".to_string(), Vec::new);
assert!(lane.is_empty());

构造器选型

按“安全边界 + 控制度”选择:

自适应重平衡(v2.2.1)

停顿式重平衡

use starshard::{RebalanceOptions, ShardedHashMap};

let m: ShardedHashMap<String, i32> = ShardedHashMap::new(8);
let report = m.rebalance_to(32, RebalanceOptions::default()).unwrap();
assert_eq!(report.from_shards, 8);
assert_eq!(report.to_shards, 32);

在线渐进迁移

use starshard::ShardedHashMap;

let m: ShardedHashMap<String, i32> = ShardedHashMap::new(8);
m.start_rebalance_online(32).unwrap();

while m.rebalance_status().state == "migrating" {
    m.advance_rebalance(2);
}

assert_eq!(m.rebalance_status().state, "idle");

语义说明:

快照模式(v2.2.1)

SnapshotMode 支持按负载选择:

有效的 Cached/Cow 缓存命中只在短暂的缓存锁下校验数据版本,不获取路由锁;缓存缺失或过期时使用独立构建锁,并按固定顺序取得分片读锁。这会合并并发重建请求并允许普通读取,写入和拓扑切换则需要等待。因此有效缓存可在仅调整拓扑的迁移期间返回,但该路径并非无锁。异步缓存读取保留 Tokio 的协作式任务预算。

iter() 返回拥有所有权的条目,因此命中共享缓存后仍会复制条目,但复制发生在释放路由锁之后;旧缓存的析构也移到路由锁外。使用 shared_snapshot() 获取 Arc<Vec<(K, V)>>,可重复读取快照而不复制条目。后续写入不会改变已有快照句柄的数据。启用 advanced 后,cow_snapshot() 还提供共享视图及其数据版本。

use starshard::{ShardedHashMap, SnapshotMode};

let clone_map: ShardedHashMap<String, i32> =
    ShardedHashMap::with_snapshot_mode(64, SnapshotMode::Clone);
let cached_map: ShardedHashMap<String, i32> =
    ShardedHashMap::with_snapshot_mode(64, SnapshotMode::Cached);
let cow_map: ShardedHashMap<String, i32> =
    ShardedHashMap::with_snapshot_mode(64, SnapshotMode::Cow);

模式选择建议

负载画像 推荐模式
高写入 + 低快照频率 Clone
中写入 + 中快照频率 Cached
低写入 + 高频快照读取 Cow 或 Cached

一致性模型

性能建议

Serde 语义

示例与基准

示例:

基准入口:

基准提前生成键并复用并发工作线程。计时批次包含屏障同步,每个线程执行 1000 次操作以摊薄同步成本。按维度抽样覆盖 1/2/4/8/16 线程、90% 热点键、16 字节/4 KiB 值、10%/50% 写入以及全部快照模式,避免执行完整笛卡尔积。拥有所有权的迭代与共享快照句柄分别测量。

cargo bench --bench bench_main -- concurrent_mixed
cargo bench --bench bench_main -- snapshot_modes
cargo bench --bench bench_main -- shared_snapshot
cargo bench --bench bench_main -- concurrent_read_paths
cargo bench --bench bench_main -- concurrent_cached_snapshot
cargo bench --all-features --bench bench_main -- snapshot_rebuild
cargo bench --all-features --bench bench_main -- batch_mutations

这些 Criterion 基准报告批次耗时和吞吐,不测量单次操作 p99 延迟、分配次数、内存峰值或迁移暂停上界;上述指标需要单独的负载观测。

验证建议

发布前或升级后建议执行:

cargo fmt --all
cargo test --all-features
cargo check --all-features

当前边界

License

双许可证:

你可以任选其一。

免责声明