资讯动态

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据

发布时间:2026/9/10 1:55:00 来源:尧图企业网站定制
RustFS Scanner 数据用量发布权威性决策配额准入如何获得可用的权威依据【免费下载链接】rustfs2.3x faster than MinIO for 4KB object payloads. RustFS is an open-source, S3-compatible high-performance object storage system supporting migration and coexistence with other S3-compatible platforms such as MinIO and Ceph.项目地址: https://gitcode.com/GitHub_Trending/rus/rustfs本决策文档ADR记录了 RustFS 在2026-09-03做出的一项关键架构结论Scanner 后台扫描产生的数据用量data usage是硬配额hard quota准入的唯一权威数据源为此必须保留完整的发布协议与证明层fence而不是在扫描滞后时用 best-effort 数据将就。阅读本文后你将理解配额写路径为何需要可用性故事、七大围栏各自的排除对象、八个持久化对象各自的属主与生命周期以及升级窗口期内 quota 如何降级到用量底线usage floor并最终收敛回完整发布。决策概述保留 Scanner 发布协议作为配额权威scanner-usage-authority-decision.md给出的是结论性决策记录其完整论证与协议细节落在配套契约文档 scanner-usage-publication.md 中两者共同构成该主题的决策 契约体系RustFS keeps scanner data usage as authoritative for quota admission.该决策从 backlog 决策记录中选定了选项 A在配额准入消费 scanner 用量期间scanner 发布协议保持必要。决策明确把以下机制从可删除的兼容性杂物重新定性为协议不变式protocol invariants周期纪元cycle epoch发布 CASpublication CAS数据迁移围栏data-movement fence分层注册表围栏tier-registry fence观察快照层observed snapshot layer持久化用量底线persisted usage floor。换句话说这些证明层不是历史包袱而是让分布式后台扫描的结果可以被配额决策信任的机制本身。删除任何一个都需要先证明有替代机制能排除同样的陈旧输入。为什么配额准入不能接受 best-effort 用量决策理由Rationale直指问题本质配额是写路径上的准入决策write-path admission decision。如果配额以 best-effort 的 scanner 数据为准那么扫描临时滞后scanner lag就会直接转化为欠强制under-enforcement——扫描还没看到的新写入不会被计入用量配额形同虚设。因此设计上不能靠删掉证明层来简化反而需要一个权威用量的可用性故事availability story。可用性故事的主角是scanner usage floor用量底线当完整的权威快照不可用时冷启动、升级恢复、不完整周期的修复期间配额准入使用这个下界值。观察快照observed snapshot仍然服务于管理和可观测性但永远不成为配额权威。这一判断与 QuotaChecker 的实现 完全一致get_real_time_usage的查找顺序是——内存权威用量 → 持久化用量底线 → 失败关闭后两级正是决策文档中可用性故事的落地。发布所有权模型三个身份缺一不可一个 scanner 周期只有在同时满足两个条件后才拥有权威发布的资格持有集群 scanner 领导权声明leadership claim并证明存储发布纪元storage publication epoch没有移动。领导权声明持久化在 scanner 周期状态cycle state中源码对应 leadership.rs 中的 reconcile_scanner_leadership_claim它读取并对比.bloomcycle.bin的持久化修订数据用量发布的准入权归ECStore所有因为只有它知道 rebalance、decommission 等数据迁移操作是否改变了 scanner 结果允许描述的 generation。Scanner 可以无发布所有权地计算用量但绝不能把结果变成权威的、配额可见的状态。一次完整发布因此具有三个身份identity拥有该周期的scanner leader epoch围栏数据迁移的storage publication epoch被替换用量对象上的per-object CAS revision。任何一个身份在提交前发生变化结果就只能作为重试或观察候选而不是权威基线。PUT 扇出fanout的在途保护普通 PUT rename 扇出同样追踪实例级在途工作in-flight workquorum ACK 并不释放它——真正的磁盘任务保留所有权直到 rename 结束即使请求调用方已被取消。关键设计取舍是扫描准入保持仅限迁移movement-only持续的 PUT 不会停止命名空间遍历和 scanner 驱动的生命周期发现遍历后的本地发布检查和**远程发布租约publication lease**拒绝尚未结束的扇出begin/end 命名空间 generation使跨扇出的扫描与缓存计划失效协调者在获取远程租约后、发布权威聚合前会重查完整活动摘要activity digest以捕获扫描最后一次探测与租约获取之间才结束的尾部。该机制不增加命名空间或迁移锁。已通过验证的旧快照仍可能先于新开始的写入持续或停滞的 PUT 尾部会延迟权威用量发布延迟通过现有重试调度恢复而非新增即时唤醒协议。这个 PUT 尾部保护要求所有 writer 节点完成升级且不证明失败尾部副本已自愈也不把在途追踪扩展到 multipart 等其它命名空间变更路径。围栏体系七道独立证明协议使用独立的围栏fence因为它们排除的是不同的陈旧输入。除非替代方案能证明同样的排除效果否则不得合并围栏属主排除对象Scanner 领导权声明scanner竞争中的 scanner leader 与陈旧周期写入者存储发布纪元ECStore跨 rebalance、decommission 或其它数据迁移 generation 计算出的用量发布租约经 ECStore 面活动探针的 scanner 对端尚未确认候选的远程脏用量或维护状态CAS 修订底层配置对象存储对用量快照、scanner 缓存或周期状态对象的丢失更新Per-set 新鲜度scanner 聚合混入陈旧与当前 set 结果的合并用量快照分层注册表 generationscanner 分层核算依据不同暖分层注册表分类的字节数用量底线身份scanner 发布与 ECStore 配额回退空值或遗留值变成看似可信的权威配额输入无法为自身读取面证明所需围栏的读者必须**失败关闭fail closed**或走文档化的观察路径绝不允许为缺失或损坏的权威对象合成空用量快照。缓存执行身份防止慢扫描覆盖新结果结构扫描计划摘要structural scan-plan digest在普通 bucket 写入下可以保持稳定因此有范围扫描可以保留未受影响的基线 bucket。但它不足以证明同一周期内可复用已完成的结果。Bucket 工作使用结合了结构计划与完整活动快照的执行摘要execution digestbucket 的脏 generation 纳入其缓存身份已完成的 set 缓存与结构计划分开携带同一执行摘要。持久化 set-root 快速路径要求执行身份相等并叠加既有的 source、cycle、leader、tier 与缓存结构检查。Set 扫描还会捕获其起始缓存修订starting cache revisions当持久化执行结果不同、需要替换时这些修订必须保持不变否则慢扫描可能覆盖更新的已完成结果。既有缓存锁、条件保存与迁移准入仍然围栏提交。实现层面可选字段scan_execution_digest追加到 map 编码的缓存元数据中。遗留缓存仍可读但缺少该身份就无法满足同周期 set-root 复用旧版读者可以忽略新增的 map 键但旧版写入者不执行该围栏——可读性不构成混合版本发布安全的保证。持久化对象契约每个对象都有唯一属主持久化对象是兼容性契约的一部分移除任何一个都需要兼容窗口与专门的清理条目cleanup entry。下表对象路径均位于元数据桶的 bucket-metadata 前缀下对象属主生命周期.usage-cache.bin每个 bucket/set 下scanner 磁盘遍历由 scanner 依据对象元数据重建数据缺失触发该 bucket/set 重扫数据损坏不构成完整基线.bloomcycle.binscanner 周期状态由 leader CAS 更新状态缺失从未初始化周期开始损坏或未来状态在自动重试前先被隔离.usage.v2.json与.usage.jsonscanner 权威发布.usage.v2.json是主要完整用量快照.usage.json仅在携带有效持久化身份时作为遗留或伴随基线读取。两者都不能绕过 v2 纪元围栏仅当基线身份与完成字段通过校验时读者才可将其视为权威.usage.observed.jsonscanner 观察路径在权威发布无法被证明但诊断快照仍有用时写入永不是硬配额权威bucket-metadata/.usage.jsonscanner 用量底线携带降级权威用量窗口内配额使用的持久化 per-bucket 底线在下一次完整 scanner 发布前保持静态.bloomcycle.bin.recovery-required.jsonscanner 周期恢复隔离无效周期状态并携带重试证据仅 scanner 恢复代码可更新或清除.scanner-cycle.lockscanner 运行时锁序列化周期级工作锁对象缺失本身不是用量证据.scanner-pause-backlog.jsonscanner 暂停与追赶账本在权威发布被数据迁移围栏期间追踪脏用量、发现的周期工作与全量扫描追赶绝不授予发布准入对象路径常量在源码中有明确出处例如 data_usage_define.rs 中的路径定义 与 data_usage.rs 中的对象名常量DATA_USAGE_OBJECT_NAME .usage.v2.json、DATA_USAGE_OBSERVED_OBJECT_NAME .usage.observed.json、LEGACY_DATA_USAGE_OBJECT_NAME .usage.json恢复标记则派生为.recovery-pending.json/.recovery-required.json后缀。观察快照与用量底线降级路径的两层观察快照诊断与可用性层观察快照仅在快照明确声明自身为部分或观察性质时才能被提供且只提供给不会据此做出硬配额、持久性或删除决策的消费者。管理用量视图可以携带完整性标记completeness flags暴露该状态让运维在权威发布被阻塞时仍能看到进度。配额强制不得将观察快照当作当前用量权威。用量底线静态下界而非新鲜计数权威快照不可用时配额准入可使用持久化用量底线。这是一个可用性回退而非新鲜计数实时写入不会推进底线超限仅受下一次完整 scanner 发布前已接受的写入约束若连有效持久化底线都没有配额保持不可用并失败关闭。可用性决策契约四条款决策文档给出的可用性契约精确为四条权威快速路径读取完整的内存或持久化 scanner 用量升级或发布中断期间配额可依据持久化 per-bucket 用量底线准入底线在该中断窗口内是建议性的必须收敛回完整 scanner 发布既无权威用量、也无有效底线的 bucket失败关闭。把该决策改为软配额soft quota模型属于产品变更而非 scanner 重构需要分阶段移除权威特定层并为上述持久化对象做兼容性处理。删除与恢复规则属主隔离只有对象的属主才能删除或隔离它scanner 可在扫描证明替换内容后重建 per-set.usage-cache.binscanner 周期恢复可隔离无效的.bloomcycle.bin且仅在有效周期状态持久化后才能清除标记scanner 发布只能通过上述发布围栏替换.usage.v2.json或遗留伴随对象配额消费者可读取用量底线但不得删除或修复它运维只能通过受支持的 scanner 重置面重置用量状态——该面会记录重置路径并强制全量重建。缺失、不可解码或无身份的数据不会被转换为零而是按读者所属面分别报告为 uninitialized、recovery-required、observed-only 或 unavailable。源码中 cycle_state.rs 的恢复标记与重试预算 给出了实现细节MAX_SCANNER_CYCLE_RECOVERY_RETRIES 5恢复状态机healthy / blocked / paused / recovery-required / cleanup-pending / usage_floor_load_failed 等由 gauge 指标rustfs_scanner_cycle_recovery_required对外暴露此外还有幂等的恢复意图recovery intent机制.usage.v2.recovery-intents/前缀下的意图记录支持scanner-usage-full-rebuild动作与 full-rebuild 模式供运维在确认重置意图后强制重建。源码佐证从 QuotaChecker 到发布管线的实现细节配额检查的三级查找与回归测试QuotaChecker::get_real_time_usage 是决策可用性故事的直接实现先查内存权威用量get_bucket_usage_memory命中即返回权威快速路径降级窗口注释明确指向 issue #5716读取持久化 per-bucket 底线lookup_degraded_bucket_usage_baseline——该窗口最典型的触发场景是从 pre-v2 版本升级遗留.usage.json缺少完整性标记被降级为非权威而 scanner 首个完整周期写出.usage.v2.json可能还很遥远若此时失败关闭配额桶的每次写入都会在整个窗口内变成可重试 503两级都无结果才返回QuotaError::UsageUnavailable失败关闭。仓库测试 checker.rs 中的回归测试 精确验证了这一契约quota_admission_falls_back_to_legacy_snapshot_baseline构造遗留快照夹具验证回退基线值 1_234、验证未知 bucket 失败关闭、验证删除后端用量后重新创建的 bucket 不会继承旧 incarnation 的大小quota_usage_rejects_an_unknown_mutation_baseline则验证无权威基线时必须失败关闭。CAS 发布管线的证明与结果枚举usage_store.rs 的发布管线 展示了围栏如何落到代码发布保存走scanner_data_usage_publication_commit_scope_with_release_flag提交作用域根 ACK 确认要求提交状态为 Committed 且写入 ETag 非空root_ack_write_is_confirmedCAS 冲突触发有限重试PreconditionFailed分支并据最终结果产出DataUsagePersistOutcome枚举NoUpdate / Current / AlreadyDurable / PriorCycleDurable / Saved / Deferred(原因) / Failed——其中Deferred(ScannerCycleDeferReason::DataMovement)与PublicationLeaseDeadlineExceeded正是发布围栏把结果打回重试/观察候选的代码形态。观察快照写入.usage.observed.json目标路径且必须先确认权威基线身份存在usage_snapshot_authoritative_baseline才允许落盘呼应观察层永不作配额权威。暂停积压账本不授予准入的独立记账backlog.rs 的模块注释明确声明该账本复制在权威发布路径之外因此在发布被数据迁移围栏期间仍可推进但从不授予发布准入。它提供Idle / Paused / CatchingUp / RetryExhausted四个阶段与一组阈值常量24 小时暂停时长告警、3 个被延迟周期告警、10,000 条积压条目告警、5 分钟最小追赶间隔、1 小时追赶窗口、每窗口最多 4 次尝试、5 次连续失败上限。既有修复即不变式契约文档明确指出若干历史 scanner 修复是这份契约的推论而非独立补丁不完整的 scanner 用量不得成为完整的 admin 或配额基线——因为完整性与底线身份属于发布所有权的一部分脏用量与维护确认必须围栏发布——因为携带未确认工作的远程节点会使候选失效遗留或备份用量对象仅在携带有效基线身份、且不越过主纪元围栏时才可帮助恢复可用性。未来变更的影响与边界决策文档为后续工作划定了两条硬边界#2214是未来用量发布变更的硬性设计输入。未来的提案仍可选择软配额与 MinIO 式 best-effort 用量但那将是产品变更必须为持久化工件自带分阶段兼容计划#2219可在当前权威协议的基础上设计 scanner 存储边界storage boundary。其接口必须包含契约所需的 CAS 键值、周期锁、用量底线、观察快照与恢复标记能力不得把这些证明义务隐藏在一个通用对象存储 trait 之后。对正在演进 RustFS 或设计同类分布式后台扫描 配额系统的工程师这份决策记录的实际价值在于一个反直觉的结论当后台扫描的结果要支撑写路径准入决策时保留多余的证明层恰恰是最短路径——删除它们并不能让系统更简单只会把扫描滞后直接转化为配额欠强制。【免费下载链接】rustfs2.3x faster than MinIO for 4KB object payloads. RustFS is an open-source, S3-compatible high-performance object storage system supporting migration and coexistence with other S3-compatible platforms such as MinIO and Ceph.项目地址: https://gitcode.com/GitHub_Trending/rus/rustfs创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价