ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Lance `__manifest` 提交基准:复制即写入目录目录在规模与并发下的性能剖析

Lance `__manifest` 提交基准:复制即写入目录目录在规模与并发下的性能剖析 Lance__manifest提交基准复制即写入目录目录在规模与并发下的性能剖析【免费下载链接】lanceOpen Lakehouse Format for Multimodal AI. Convert from Parquet in 2 lines of code for 100x faster random access, vector index, and data versioning. Compatible with Pandas, DuckDB, Polars, Pyarrow, and PyTorch with more integrations coming..项目地址: https://gitcode.com/GitHub_Trending/la/lance导读Lance 的目录命名空间Directory Namespace把“表与嵌套命名空间”的目录状态持久化在一张名为__manifest的特殊 Lance 数据集中。每一次元数据变更建库、建表、声明表等都会触发一次复制即写入Copy-on-Write, CoW的整表重写并原子提交一个新版本因此__manifest的提交延迟与吞吐决定了整个命名空间层在规模增长与多进程并发写入下的天花板。本文以仓库中的 rust/lance-namespace-impls/BENCHMARK.md 为主线结合manifest_bench基准二进制与manifest_commit_sweep.sh扫描脚本系统讲解该基准的测量方法、命令行用法、全量扫描面板配置、源码级实现原理以及作者给出的代表性结果与结论。读完本文你将掌握如何复现“连续提交continuous commit”与“并发提交concurrent commit”两类场景、如何解析 JSONL/CSV 结果并理解内联标量索引inline scalar indices开关对提交成本的真实影响。一、为什么需要测量__manifest的提交性能__manifest目录目录把每个命名空间与表抽象成一张单表的行。参照 目录清单实现其内部常量为表名固定为__manifest数据目录data、索引目录_indices三个内置索引object_id_btreeBTree 索引、object_type_bitmapBitmap 索引、base_objects_label_listLabelList 索引重写提交的默认重试预算DEFAULT_MANIFEST_REWRITE_COMMIT_RETRIES 20与普通 Lance 提交重试对齐保证多进程写可以推进索引构建的批大小MANIFEST_INDEX_BATCH_SIZE 8192。__manifest的每一行包含object_id、object_type、location、metadataUtf8以及base_objectsListUtf8该模式与 基准二进制中构造的 schema 完全一致。关键事实目录目录采用“提交即整表重写”的 CoW 策略。每提交一次变更都会重新扫描全量 manifest、生成新的数据文件以及可选的替换索引再通过对象存储的原子 put-if-not-exists 提交一个新版本见commit_manifest_overwrite的实现思路。因此单次提交的成本近似与 manifest 行数成正比约O(rows)吞吐并不随并发度提升而提升——每一次提交都是串行化的__manifest版本号递增这是单写者吞吐single-writer-throughput系统并发只能制造竞争与重试不能放大 TPS。基准文档正是围绕“manifest 越大、提交越慢”这一核心矛盾量化连续提交延迟与并发争用下的稳态 TPS。二、基准工具examples/manifest_bench.rs2.1 三种模式manifest_bench.rs 提供三种模式模式作用seed-large引导bootstrap一个包含count行的__manifest先直接写 Lance 数据集一次性O(rows)再触发一次 CoW 重写使磁盘状态与稳态目录形态一致单 fragment开启内联索引时含索引。run协调者coordinator派生--concurrency个 worker 子进程提交变更通过--operations固定提交预算连续模式或通过--duration-secs让每个 worker 持续提交到截止时间稳态 TPS。每个并发级别打印一行 JSONBenchResult包含吞吐与 p50/p90/p99 延迟。worker内部模式由run派生的单个提交进程一般情况下无需直接调用。run内部会把固定操作预算按并发度均分给 workeroperations / concurrency而稳态模式下每个 worker 独立跑满整个时长run_workers。2.2 命令行用法连续提交单进程、固定次数manifest_bench run --root uri --operation write-create-namespace \ --concurrency 1 --operations 100 --initial-entries rows --inline-optimization bool并发提交C 个进程、固定时长稳态 TPSmanifest_bench run --root uri --operation write-create-namespace \ --concurrency 50 --duration-secs 30 --initial-entries rows --inline-optimization bool引导大规模 manifestmanifest_bench seed-large --root uri --count rows --inline-optimization true|false \ [--storage-option aws_regionus-east-1]参数要点--root uri命名空间根路径本地路径或s3://bucket/path--operation默认write-create-namespace是最廉价的纯__manifest变更不涉及表数据。另有write-create-table、write-declare-table可用在run_operation中实现manifest_bench.rs此外还支持只读操作cold-read-list-namespaces、warm-read-list-namespaces、cold-read-list-tables、warm-read-list-tables、cold-read-describe-table、warm-read-describe-table--initial-entries rows记录 manifest 起始行数用于标记结果扫描脚本用它和实际提交数区分基准形态--inline-optimization bool开启/关闭内联标量索引构建下文详解--concurrency支持逗号分隔的列表如--concurrency 10,50,100run会逐个并发级别跑一轮--storage-option aws_regionregionS3 场景必传。2.3 运行前提S3 场景需要默认的dir-awsfeature默认开启见 Cargo.toml 中default [dir-aws, ...]且环境中需具备 AWS 凭证本地文件系统路径无需额外凭证worker 通过stdout输出 JSON 延迟记录、stderr输出进度二者分离便于管道解析源码中有相应注释说明该设计。2.4 输出格式每个并发级别输出一个 JSONBenchResultBenchResult 结构定义字段包括variant、operation、concurrency、initial_entries、duration_secs、total_operations、total_duration_ms、throughput_ops_per_sec、avg_latency_ms、p50_latency_ms、p90_latency_ms、p99_latency_ms、min_latency_ms、max_latency_ms、errors。worker 逐条输出LatencyRecord { operation, latency_ms, error }协调者汇总排序后按分位数计算percentile采用排序后线性插值取整见 manifest_bench.rs。三、全量扫描面板benches/manifest_commit_sweep.shmanifest_commit_sweep.sh 把整个测量矩阵自动化manifest 规模 × {内联索引, 无索引} × {连续, 并发×C}。3.1 运行方式cargo build --release --example manifest_bench -p lance-namespace-impls S3_BASEs3://bucket/manifest-cow-bench/$(date -u %Y%m%dT%H%M%SZ) \ rust/lance-namespace-impls/benches/manifest_commit_sweep.sh3.2 默认面板可用环境变量覆盖环境变量默认值含义SIZES1000 2000 5000 10000 20000 50000 100000 200000 500000 1000000引导的 manifest 行数CONCURRENCY10 20 50 100 120 150 200并发进程数INLINE_VARIANTStrue false是否构建内联索引CONT_OPS100连续模式每轮提交次数CONC_DURATION_SECS30并发模式每轮时长秒AWS_REGIONus-east-1S3 区域OUT_DIR~/manifest_cow_bench_RUN_ID结果输出目录RUN_TIMEOUT1200单次运行超时兜底秒3.3 工程化设计要点S3 复制隔离per-run isolation每个(size, index)组合只引导一次“黄金”manifestgolden/inline_b_rows_n之后每次运行都通过aws s3 cp --recursive服务端复制到独立前缀run/tag保证每一轮都精确从引导规模起步不受上一轮写入污染可恢复resume结果写入results.jsonl时附带bench_tagdone_already()检测已完成标签即跳过中断后可重跑补齐缺口单点容错某轮引导失败只跳过该规模某轮运行失败会记录后继续不中断整个扫描孤儿进程兜底协调者被杀死可能遗留 worker 子进程clear_stragglers()会在每轮前清理examples/manifest_bench worker结果汇总脚本末尾用内嵌 Python 把 JSONL 规约为summary.csv含mode/variant/initial_entries/concurrency/ops/errors/tps/avg/p50/p90/p99并清理golden与run前缀。四、seed-large如何把一个 manifest 引导到百万行seed-large是保证测量可重复的关键环节seed_large 实现按SEED_LARGE_BATCH_SIZE 50_000生成批次数据前count/3行是namespace类型object_id 形如ns_i无 location/metadata其余是table类型object_id 形如table_ilocation 指向自身、metadata 为{bench:true}base_objects全部为空通过InsertBuilder以WriteMode::Create直接写入__manifestLance 数据集O(rows)一次完成远快于逐条提交若开启内联优化再以命名空间 API 触发一次create_namespaceid 为__seed_trigger__强制一次 CoW 重写构建替换索引并使磁盘形态与稳态一致无索引变体则在第一次真实提交时才执行该重写。引导完成后后续每轮run都在其副本上执行纯write-create-namespace变更这正是“只测量提交路径”的干净基线。五、--inline-optimization开关背后的源码逻辑inline_optimization_enabled控制 CoW 重写是否重建替换索引builder 默认关闭而 benchmark 中显式传入。在 rewrite_manifest 主循环 中build_indices self.inline_optimization_enabled开启时重写会为新写入的数据构建三个索引object_id上的 BTree、object_type上的 Bitmap、base_objects上的 LabelList见 build_manifest_indices 相关调用并以Overwrite模式嵌入事务提交关闭时indices None重写只替换数据文件、不构建索引为保证替换索引的行寻址有效(0 32) | offset重写将max_rows_per_file与max_bytes_per_file分别设为u32::MAX与usize::MAX把整表约束为单 fragmentManifestIndexAccumulator::next_row_id同时限制单 fragment 行数不超过u32::MAX。由此可以推导出两者的权衡开启内联索引会让每次提交额外付出索引构建成本但换取无索引扫描时的快速查询关闭则提交更快约 1.52×代价是读取未索引的__manifest需要全表扫描。基准文档的结论是“No-index commits run ~1.5–2× faster (no per-commit index build) at the cost of unindexed reads”。六、代表性结果与结论作者环境实测基准文档给出的代表数据来自 EC2c7i.48xlarge、S3us-east-1、操作write-create-namespace。注意这些数字属于特定环境下的作者实测仅用于展示趋势不应直接外推为通用性能承诺。连续提交1 进程、100 次提交单位 ops/s内联索引 vs 无索引rowsinlineno index1,0002.03.5100,0001.12.11,000,0000.340.53可读出的核心趋势提交吞吐随 manifest 规模增大而单调下降1M 行时约为 1K 行的 1/6 左右印证单次提交约O(rows)的成本模型并发稳态 TPS 在C10..200之间基本持平如 inline 100k 在所有并发级别都约为 1.4–1.5 ops/s1M 约为 0.3 ops/s——这是单写者版本递增的必然结果超过重试预算的冲突会以错误形式暴露且错误率随C增长C≤20时约 0C≥100时爬升这是争用天花板contention ceiling不是数据丢失无索引提交快约 1.52×省去了每提交一次的索引构建代价是未索引读取。七、如何解读与复现先执行cargo build --release --example manifest_bench -p lance-namespace-impls用seed-large引导目标规模的 manifest本地路径可快速验证S3 需--storage-option aws_region...与 AWS 凭证用run分别跑连续与并发两种模式观察每行 JSON 的throughput_ops_per_sec与errors需要完整矩阵时直接跑manifest_commit_sweep.sh最终读取summary.csv做横向对比判断争用风险时重点看errors列错误从 0 开始爬升的并发级别就是该规模下推荐的写入并发上限。若希望在线上目录目录中开启内联索引以换取读取性能可在构造DirectoryNamespaceBuilder时调用 inline_optimization_enabled(true)注意默认是关闭的见 builder 默认值并在部署前用上述基准面板评估其提交成本增量。八、小结__manifest提交基准是评估 Lance 目录命名空间在规模与并发下行为的重要工具它把“整表 CoW 重写 原子版本提交”这一核心机制量化成了吞吐、延迟与错误率三组可对比的指标并借由seed-large引导、S3 复制隔离、JSONL 记录与 CSV 汇总形成了可重复、可恢复的测量面板。对使用者而言最关键的两条结论是提交成本随 manifest 规模近似线性增长、吞吐不随并发扩展内联索引以每提交一次的构建开销换取读取性能需按读写比例权衡。【免费下载链接】lanceOpen Lakehouse Format for Multimodal AI. Convert from Parquet in 2 lines of code for 100x faster random access, vector index, and data versioning. Compatible with Pandas, DuckDB, Polars, Pyarrow, and PyTorch with more integrations coming..项目地址: https://gitcode.com/GitHub_Trending/la/lance创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表