首页 / 资讯中心 / 文章详情

把 LSM 引擎直接架在对象存储上:slatedb 能不能跑在 RustFS 上?

把 LSM 引擎直接架在对象存储上:slatedb 能不能跑在 RustFS 上? ★ FEATURED ARTICLE
RocksDB 这类嵌入式 KV 天生绑定一块本地 SSD副本和跨区复制都得自己补。slatedb 反过来把 WAL写前日志和 SST排序字符串表全部写进 S3 兼容对象存储本地盘只做缓存。它能不能直接架在 RustFS 上配置层面能slatedb 用的是 object_store 那套抽象官方口径支持任何实现 ObjectStore trait 的存储。但官方 Compatibility 页的测试目标里没有 RustFS双方集成清单也没互相收录这个组合没有任何一方背书该自己测的还是得自己测。这篇文章把接法、桶里的布局、以及几个必须自己测的点一次讲清。为什么有人想把 LSM 搬上对象存储传统 LSM 引擎RocksDB 为其一把 SST 落本地 SSD靠副本拿耐久度云上就得配一块 EBS 或本地 NVMe再自己做跨区复制耐久度才摸得到对象存储的水平。slatedb 把持久层和容量直接交给对象存储耐久度白拿容量跟着桶走没有上限数据本来就在对象存储里没有跨区复制流量。代价是对象存储的延迟和每次 PUT/GET 的成本比本地盘高slatedb 用写批处理MemTable 攒一批再刷成 SST很多写合成一次 PUT和读缓存来摊薄定位和 RocksDB 的延迟竞争从一开始就没打算赢。所以 slatedb 不是 RocksDB 的平替它赌的是另一头需求那些状态不算大、但要无限容量和对象存储耐久、还要节点随时可丢弃的云原生服务。你为它放弃的是微秒级本地延迟换回来的是再也不用养一套带盘的有状态基础设施。slatedb 在 RustFS 桶里长什么样slatedb 在桶下开五个前缀manifest/记录有哪些 SST 的清单、wal/写前日志、compacted/压实后的 SST、compactions/压实状态快照、gc/GC 协调用的 boundary 文件让废弃对象只被安全地删一次。一次db.put先写进内存里的 WAL 和 MemTableWAL 按flush_interval周期性刷进桶里MemTable 满了再冻结刷成 SST。有个容易踩的坑put().await返回只代表写进了内存官方把落桶确认拆在返回的WriteHandle上要强耐久就在句柄上调await_durable()或者显式db.flush()不等它就是低延迟优先代价是崩溃可能丢掉还没刷进桶的那一段写入。这个模型决定了它不适合 OLTP 写路径服务的对象是那些本来就能容忍几十毫秒、但想要无限容量和对象存储耐久的工作负载。读的时候 slatedb 先查本地块缓存和 MemTable未命中才去 RustFS 拉 SST所以热点数据几乎不打对象存储冷数据完全躺在桶里随用随取。这个分层把 PUT 成本和 GET 延迟都压在可控范围。接 RustFS 要改的那几行slatedb 通过object_storecrate 的AmazonS3Builder指定后端把端点指向 RustFS 即可。RustFS 1.0.02026-09-16 GAApache 2.0是 100% S3 兼容的分布式对象存储S3 端点在 9000 端口、走路径风格寻址useobject_store::aws::{AmazonS3Builder,S3ConditionalPut};useslatedb::Db;usestd::sync::Arc;#[tokio::main]asyncfnmain()-anyhow::Result(){letobject_storeArc::new(AmazonS3Builder::new().with_endpoint(http://rustfs:9000).with_allow_http(true).with_force_path_style(true).with_access_key_id(slatedb-usr).with_secret_access_key(secret).with_bucket_name(slatedb).with_region(us-east-1).with_conditional_put(S3ConditionalPut::ETagMatch).build()?,);letdbDb::open(/slatedb/ns1,object_store.clone()).await?;db.put(bk1,bv1).await?;db.flush().await?;// 显式刷桶内存里的写入落对象存储再退出db.close().await?;Ok(())}slatedb 对条件写CASCompare-And-Swap比较并交换的依赖是官方明文不是猜测Files 页写明gc/目录下的 boundary 文件就用基于 ETag 的条件更新来保证单调推进、防止并发 GC 互踩官网首页对 manifest fencing 协议的描述是 “formally verified”同样建立在条件写可用之上。示例里with_conditional_put(ETagMatch)是 object_store 提供这套语义的开关这个枚举只有ETagMatch和Disabled两个变体。RustFS 支持 S3 条件写但这个组合没有官方背书条件写语义建议单独实测一次万一兼容实现有缺口slatedb 的 fencing 会跟着失效两个写者直接脑裂别只看端点能连上就放心。完整接入步骤见 slatedb 官方的 Connect SlateDB to S3。桶和受限用户记得先在 RustFS 建好用法见官方 身份与访问管理 文档。这套接法对局域网内的 RustFS 尤其合适开发者笔记本或 CI 里跑一段 slatedb数据落在本地 RustFS 实例换机器不用搬盘。另外这段示例只是 PoC 演示slatedb 默认开着块缓存生产上还得按自己的负载调缓存、flush_interval这类参数。成熟度与几个要自己测的点slatedb 截至 2026 年 10 月最新是 v0.17.02026-09-29 发布按官方节奏约每两个月、在偶数月末发一版还没到 1.0。官方只承诺相邻版本间存储格式前后兼容API 兼容性不在保证范围内Compatibility 页还给了两条更硬的约束共享部署一次只升一个版本多个进程读写同一路径时彼此不能超过一个版本步长引擎对持久化格式做版本校验遇到不认识的版本直接 fail fast压缩 codec 也必须编译进二进制才能读。它的 Adopters 列表里已经能见到 Dropbox、Prisma 这些名字但这是个仍在快速演进的 0.x 引擎别拿成熟数据库的预期去套它。它是单写者模型多写者得自己用 fencing写者围栏防止脑裂协调所有权两个写者指向同一 namespace 会出乱子。对象存储单次 PUT 的延迟和本地盘不在一个量级写入路径要围绕批处理和缓存来设计RustFS 上的具体数字得自己量。性能这层公开基准里没有 RustFS 的数字跑出来的吞吐和延迟得你自己在本机实测不能拿 AWS S3 或 MinIO 的数据直接外推。真要上生产先在 RustFS 单节点上量一组你自己的读写混合负载再谈容量规划。slatedb 适合什么工作负载几个典型落点持久化执行引擎durable execution把流程状态存进 slatedbworker 挂了从桶里恢复流处理器的中间状态、去重表还有那些本来想用 Redis 但怕内存贵的计数器和元数据。它不适合做需要次级索引、事务跨 key 强一致、或者每秒上万次小写入的 OLTP 主库那是别的技术的活。桶里那几个前缀正好接上 RustFS 的 IAM 和生命周期把 slatedb 架在 RustFS 上价值不只是找了个 S3 端点。slatedb 写进桶的那几个前缀可以直接套 RustFS 的 IAM 做访问控制、套站点复制做异地冗余、套生命周期规则做冷数据沉降不用在 slatedb 外面再包一层存储管理。一次写入对象存储那套企业级能力全都接得上。在 RustFS 上跑 slatedb 的几个实操提醒单写者这条约束会直接落到部署形态上一个 slatedb namespace前面代码里的/slatedb/ns1同一时刻只能有一个写者多实例并行时各用各的前缀别让两个进程指向同一个 ns1否则要靠 fencing 去抢所有权平白多一层复杂度。写者只有一个读者不受限官方提供只读句柄DbReader多个读者可以并发打开同一个 namespace。它从 checkpoint 过的 manifest 读取默认启用 WAL replay——把更新的 WAL SST 重放进 reader 本地的不可变 memtable所以最新写入对读者可见的速度取决于 checkpoint 轮换和 WAL replay 设置不是简单等刷成 L0。IAM 账号按桶、按前缀发最小权限就行写者拿wal/compacted/的读写只读副本只拿s3:GetObject这条和前面 K8s 多租户的思路一脉相承。耐久度这层要讲清楚slatedb 把耐久交给对象存储但对象存储这层自己得站得住。AWS S3 标称的 11 个 9 是它自家的宣传数字slatedb 文档没背书这个数RustFS 也没有对外承诺过具体的耐久指标。RustFS 单节点靠挂的磁盘、靠 RAID 扛单盘故障想往上靠耐久得是分布式 EC 部署、数据打散到多节点单块盘不够。开发期在笔记本上跑单节点 RustFS 完全没问题真上生产再把底层换成多节点 EC应用侧代码一行都不用改。还有一点容易被忽略slatedb 会持续往wal/compacted/写新对象桶里对象总数只增不减。废弃对象的清理由 slatedb 内置 GC 负责配置在Settings::garbage_collector_options默认跟着每个 Db 实例跑也能拆成独立进程用官方 CLI 的run-garbage-collection或schedule-garbage-collection单独执行多个 GC 还可以并行它只删不再被 manifest 或 checkpoint 引用的对象。对象存储的 lifecycle 规则只能做兜底而且要放得足够保守万一 lifecycle 把仍被 manifest 引用的对象提前删了数据库直接损坏这不是 slatedb 能补救的错。所以在 RustFS 上要盯两件事桶的对象总数会不会涨到影响ListBucket的返回速度以及 GC 有没有正常在删、冷数据有没有悄悄堆成账单。一组可直接跑的动作装依赖照官方教程来cargo add slatedb tokio --features tokio/macros,tokio/rt-multi-thread、cargo add object-store --features object-store/aws、cargo add anyhow再按上面改AmazonS3Builder指向 RustFS 9000 端口。object_store 不开 aws feature 编译不过版本要和 slatedb 依赖的 object_store 对齐或者直接用slatedb::object_store的 re-export免得出现两份对不上的类型。在 RustFS 建slatedb桶并开一个只对该桶有读写权的 IAM 用户。要强耐久就在返回的WriteHandle上await_durable()或显式db.flush()上多写者前先解决 fencing。压测别信别人的数字自己在本机量一遍 RustFS 上的 PUT/GET 延迟。官方入口slatedb 仓库 github.com/slatedb/slatedb、文档 slatedb.ioRustFS 文档 docs.rustfs.com、源码 GitHub。
阅读完成 · 觉得有帮助?
咨询建站