RustFS 按需迁移桶返回 424 SourceUnavailable 怎么排查?
【免费下载链接】rustfs🚀2.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
当你把一个既有 S3 兼容桶通过按需迁移(On-Demand Migration,ODM)挂到 RustFS 桶上后,客户端 GET/HEAD 一个本地不存在的对象时,RustFS 会从外部源桶拉取数据;如果源请求失败、而桶的policy.source_error保持默认值propagate,请求就会返回 HTTP 424、错误码SourceUnavailable。这篇文章按"读错误分类 → 查节点状态 → 按分类修复 → 验证"的顺序给出排查路径,完整行为表见 docs/operations/on-demand-migration.md。
适用前提:本地桶已配置 ODM(桶元数据中存在on-demand-migration.json),且全局开关RUSTFS_ON_DEMAND_MIGRATION_ENABLED为true(默认开启)。如果读取根本没有走到源上(miss 时什么也不发生),那是另一条排查线,不是 424 问题。
哪些请求会返回 424
424SourceUnavailable出现在两类情况:
propagate策略下的源失败。GET/HEAD miss 后源请求失败,错误消息里只携带失败分类(class):timeout、connect、server_error、throttled、access_denied、other、breaker_open(GET 命中已打开的熔断器)、client_build(源客户端未能构建,含无凭据的源)。- SSE-C 源对象。无论
source_error怎么配置都固定返回 424,class 为unsupported;SSE-C 对象不支持迁移。
另外,policy.list_through = true时,合并ListObjectsV2的源列表失败或 v2 续读预算耗尽,也会按source_error处理:propagate返回 424,class 为invalid_pagination。
注意源端错误消息不会原样跨边界返回——SDK 消息可能内嵌签名请求与密钥,客户端只能拿到稳定的 class 标签。要判断真实原因,需要对照源自身的访问日志。
第一步:读错误消息中的分类
先记下 424 响应体里的那个 class,再按下面判断方向:
| class | 含义 | 是否瞬态 |
|---|---|---|
access_denied | 源返回 403:键存在,但缺s3:GetObject权限或凭据已轮换 | 否,属配置错误 |
connect | 到源的 DNS、TLS 或路由问题 | 环境类 |
timeout | 源未在connect_ms/first_byte_ms/idle_ms窗口内响应 | 瞬态 |
server_error | 源返回 5xx | 瞬态 |
throttled | 源限流 | 瞬态 |
breaker_open | GET 命中已打开的熔断器 | 取决于源恢复时间 |
unsupported | 源对象是 SSE-C | 固定,无法迁移 |
client_build | 源客户端未能构建(含无凭据源) | 配置问题 |
invalid_pagination | 合并列表的源列表失败或 v2 预算耗尽 | 视源列表而定 |
熔断器的行为是判断的关键背景:30 秒窗口内连续 5 次可计数的传输失败会把它打开,保持打开 30 秒后放一个探针请求;源 404 是健康应答、会重置连续计数,403 与unsupported是中性的、不计数。所以反复出现server_error/timeout/connect五次后会进入breaker_open,此后该桶的 GET 全部 424;而access_denied则基本可以排除熔断器因素。
第二步:查节点状态端点
状态端点返回应答请求的那个节点的运行时状态。计数器、队列深度与熔断器状态都是每节点运行时状态,分布式部署下要逐个节点查询;保存的配置与updated_at是集群级的。
管理请求与 S3 请求一样做 SigV4 签名。下面沿用项目文档的awscurl示例:<host>替换为你要检查的节点地址,photos是文档示例的桶名、替换成你的实际桶名,$RUSTFS_ACCESS_KEY/$RUSTFS_SECRET_KEY是部署的管理凭据:
# Per-node runtime status (breaker, counters, queue, last source error) awscurl --service s3 --region us-east-1 \ --access_key "$RUSTFS_ACCESS_KEY" --secret_key "$RUSTFS_SECRET_KEY" \ "http://<host>:9000/rustfs/admin/v3/on-demand-migration/photos/status"用返回内容确认三点:
last_source_error(含class与at)是否与 424 消息中的分类一致;breaker.state:若已打开,先修源——打开期间该节点不会发出任何源流量,这是设计意图;module_enabled与enabled:进程开关与配置自身开关。节点没有该桶的存活状态(模块关闭或尚未有读取)时运行时字段为null,但provider与endpoint_host仍反映保存的配置。
如果接了 Prometheus,同一状态也有指标可用,所有序列按桶聚合、带bucket标签:
# 熔断器告警:0 closed, 1 half-open, 2 open max by (bucket) (rustfs_on_demand_migration_breaker_state) >= 2 # 按原因看拉取失败 sum by (bucket, reason) (rate(rustfs_on_demand_migration_pull_failures_total[5m]))第三步:按分类修复
access_denied:源返回 403。核对凭据是否对<bucket>/*有s3:GetObject、是否已轮换;列表路径还需要s3:ListBucket。如果凭据按前缀授权,确认被读的键落在授权范围内。这类错误不会打开熔断器。
connect/timeout:检查到源的 DNS、TLS 与路由。源使用自签名证书时,把签发证书的 PEM 文本放入source.tls.ca_cert_pem;source.tls.skip_verify只适合实验环境,不要对走不可信网络的源使用。源访问日志里如果出现NoSuchBucket或 301/307 重定向,通常是寻址风格问题,显式设置source.path_style,不要依赖auto。
server_error/throttled:瞬态失败,单次会自动重试,连续 5 次后熔断器打开。确认源侧健康与限流配置。
breaker_open:熔断器 30 秒后重新探针,探针成功即关闭。这个 30 秒打开窗口是编译期常量,没有环境变量可以调短,只能在源恢复后等探针通过。
unsupported:源对象是 SSE-C 加密,RustFS 固定拒绝,需通过其他途径迁移这类对象。
client_build:该桶的源客户端未能构建。常见原因:source.credentials为null(匿名 S3 尚不支持,adminPUT会直接拒绝),或构建未包含gcsfeature 的原生 GCS 源。用GET /rustfs/admin/v3/on-demand-migration/{bucket}读回保存的配置核对(返回的是脱敏配置,secret_key与session_token显示为REDACTED)。
invalid_pagination(合并列表):list_through = true下源列表失败或 v2 续读预算耗尽。先确认源列表可用、源凭据有s3:ListBucket。
可选:修复期间降级为 404
如果想在修源期间让客户端看到普通 404 而不是 424,把policy.source_error改为not_found:源失败降级为 404,合并列表降级为仅本地并带x-rustfs-on-demand-migration-list: local_only响应头。文档明确提示了这个取舍:同步客户端会把 404 读成"对象已删除",按需选用。
验证修复
- 重新发起原先 424 的 GET。由源应答的读取返回 200 并携带响应头
x-rustfs-on-demand-migration: source;对象已落到本地后的读取不再带这个头,这是区分迁移读与本地读最直接的办法。 - 逐节点复查状态端点:
breaker.state回到关闭状态。 - 如有指标,确认
rustfs_on_demand_migration_breaker_state回到 0,并用pull_failures_total的reason分布确认原失败分类已停止增长。
两个需要记住的限制:源的具体错误文本不会返回给客户端,只有 class 标签,细节要去源自己的访问日志里找;熔断器 30 秒打开窗口是编译期常量,无法通过配置缩短。
【免费下载链接】rustfs🚀2.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),仅供参考