[Feature Request] ov get 支持可恢复的目录逐文件下载 #4004
KCHENPENGFEI
started this conversation in
Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
背景
当前
ov get <uri> <local-path>只支持下载单个文件。需要下载目录时,用户只能先枚举文件,再逐个执行ov get,或者使用语义不同的.ovpack导入导出流程。更重要的是,当前单文件下载链路本身还不是端到端流式的:服务端会把文件完整读取为
bytes,CLI 也会把整个响应读取为Vec<u8>后再写入本地。因此,即使只下载一个超大文件,也存在服务端或客户端 OOM 的风险。目录可能达到 TB 级,并包含数百万个文件。将目录动态打包成一个流式 ZIP 虽然能降低内存和临时磁盘占用,但无法可靠解决断点续传、单文件重试、长连接超时、服务重启以及下载期间目录变化等问题,不适合作为目录下载的默认方案。
本提案建议:
viking://引用改写为本地相对路径,确保下载结果可在本地直接使用。建议的命令形式
--recursive;ov get自动识别远端目标是文件还是目录。为什么不采用目录默认 ZIP
对于 1TB 目录,即使 ZIP 是真正流式生成的,仍有以下风险:
.zip.part通常不可正常使用;viking://引用改写需要知道完整导出集合,会进一步增加状态和一致性复杂度。因此,ZIP 可以作为未来针对中小目录的显式便利功能,或由后台任务生成稳定对象后通过 Range 下载,但不作为本提案的默认模式或首期范围。
第一阶段:单文件端到端流式下载
服务端
扩展现有单文件下载接口,使其具备:
Range请求;Accept-Ranges: bytes、Content-Length、ETag;206 Partial Content和正确的Content-Range;If-Match,当文件版本变化时返回412 Precondition Failed;底层 AGFS 已支持
offset、size和流式读取,可作为实现基础,但 HTTP 层和 CLI 目前尚未暴露这条能力。CLI
video.mp4.part;.part当前长度继续;第二阶段:Manifest 驱动的目录下载
可分页 Manifest
目录下载开始时,CLI 调用 Manifest 接口,按稳定 cursor 分页取得目录内容。每个条目至少包含:
relative_path;Manifest 必须绑定稳定的目录视图或 snapshot token。后续分页和文件下载都应引用同一个 snapshot,避免目录变化造成文件重复、遗漏或内容版本不一致。
如果某个后端暂时无法提供目录快照,只能降级为明确标记的 best-effort 模式:每个文件仍使用 ETag/
If-Match校验,发生变化时报告具体文件,不能静默下载不同版本。Manifest 只返回调用方有权访问且对调用方可见的内容,不包含
.path.ovlock、临时锁和其他运行时内部文件。CLI 编排
viking://引用改写后,才提交目录下载完成状态。对于百万级小文件,可以在后续评估 HTTP/2 连接复用、小文件批次或可恢复分片对象,但不使用一个不可恢复的超长
multipart/mixed响应承载整个目录。本地路径安全
目录下载必须在写入前验证每个 Manifest 相对路径,包括:
..、绝对路径、反斜杠逃逸和空路径;.part和原子 rename,不直接覆盖最终路径。下载前应汇总预期总大小和文件数,并在本地磁盘容量明显不足时尽早失败;实际下载仍需处理配额变化和写盘失败。
viking://引用改写单文件下载保持原始内容,不要求改写引用;目录下载则必须改写。目录已经脱离 OpenViking 运行环境,本地文件中的
viking://URI 无法直接使用,只有指向同一下载集合的本地相对路径才有意义。因此,引用改写是目录下载的完成条件,而不是可选增强。改写在所有原始文件下载并通过源 checksum 校验后执行:
viking_uri -> relative_path映射;viking://URI,避免生成无效本地链接;#fragment;downloaded_verified和references_rewritten状态,因为改写后的本地内容不再匹配源 checksum;完整映射应保存在 SQLite 等可增量查询的本地状态中,不能要求百万级 URI 全部驻留内存。只有所有支持文本文件完成改写后,目录任务才能进入
completed状态。与
ov export的关系ov get面向用户可直接使用的普通文件和目录;ov export/.ovpack面向 OpenViking 数据迁移和恢复,两者语义保持独立。当前
.ovpack下载同样存在完整响应缓冲问题。在完成流式生成、稳定对象和 Range/续传能力之前,不应把ov export视为 TB 级目录下载的替代方案。非目标
首期不包含:
--recursive;multipart/mixed响应中连续传输整个目录;.ovpack作为普通目录下载格式。建议的实施顺序
.part、checkpoint、断点续传、校验和原子提交;viking://引用改写,并支持从 checkpoint 恢复;验收标准
单文件下载
.part,校验成功后原子提交;目录下载
ov get自动识别目录,不需要--recursive;viking://引用必须改写为正确的本地相对路径;All reactions