GeneralAndroid MinIO 传输增强完整方案
1. 目标
在当前 MinIO 大文件治理第一阶段已经完成的基础上,进一步增强上传/下载体验,使现有工作流支持:
- 多文件并发上传
- 多文件并发下载
- 中断后重新执行时自动跳过已完成文件
- 保持当前 manifest / sha256 / history / hook / CI / bootstrap 架构不被破坏
本方案强调:
- 不重造底层 MinIO / S3 传输协议
- 继续复用
mc作为传输引擎 - 由 Python 脚本负责任务调度、元数据更新与校验
2. 总体原则
2.1 继续复用 mc
不自己实现 S3/MinIO 分块协议。
原因:
mc已经成熟稳定mc cp已具备 multipart 能力- 传输可靠性远高于手写 Python 上传器
- 当前项目真正缺的是“调度和状态管理”,而不是传输协议本身
因此:
- Python 负责任务编排
mc负责真实传输
2.2 并发传输,串行落清单
这是整套方案最关键的设计约束。
可以并发的部分
- 多个文件同时上传
- 多个文件同时下载
不能并发的部分
以下文件必须统一串行写入:
assets/resource_manifest.jsonassets/resource_manifest.mdassets/assets_sha256.txtassets/asset_history.jsonl
原因:
- 避免 manifest 写坏
- 避免 history 顺序混乱
- 避免“部分成功 / 部分失败”时 Git 元数据和 MinIO 状态不一致
因此整个流程必须遵守:
- 并发传输文件
- 收集所有成功 / 失败结果
- 再由主线程统一写 manifest / sha / history
3. 上传增强方案
3.1 当前状态
当前 scripts/upload_assets.py 是:
- 单文件上传
- 上传完成后立即写 manifest / sha / history
这个模式适合单文件维护,但不适合大批量并发导入。
3.2 推荐方案
保留 scripts/upload_assets.py 作为单文件稳定入口,同时新增一个专门的批量脚本:
scripts/batch_upload_assets.py
角色划分
upload_assets.py- 继续负责单文件新增 / 登记
- 保持逻辑简单稳定
batch_upload_assets.py- 负责批量并发上传
- 负责统一收口 manifest / sha / history
3.3 batch_upload_assets.py 的职责
- 接收一组待上传文件
- 对每个文件做预检查
- 并发调用
mc cp - 收集每个文件的结果
- 成功项统一写:
resource_manifest.jsonresource_manifest.mdassets_sha256.txtasset_history.jsonl
3.4 建议参数
示例:
python3 scripts/batch_upload_assets.py --file-list assets/to_upload.txt --jobs 4或:
python3 scripts/batch_upload_assets.py --category media --file-list assets/top40_media.txt --jobs 8建议支持:
--jobs N--continue-on-error--dry-run--alias--overwrite--category--file-list
3.5 上传流程
第一步:预检查
对每个文件先做:
- 文件存在检查
- 大小读取
- SHA256 计算
- object name 生成
- 远端对象冲突检查
第二步:并发上传
线程池中的每个 worker 只负责:
- 执行
mc cp local -> remote - 上传返回成功后,再执行
mc stat <alias>/<bucket>/<object_key>做远端存在性确认 - 推荐默认至少做到:
mc stat成功- 远端 size 与本地 size 一致
- 只有通过远端确认的对象,才允许进入成功结果集合
- 返回成功 / 失败结果
第三步:统一收口
主线程统一:
- 只把“上传成功且远端确认成功”的条目写入 manifest
- 只把“上传成功且远端确认成功”的条目写入 sha 文件
- 只把“上传成功且远端确认成功”的条目写入 history
- 输出失败列表
这一点非常关键:
- 上传命令成功 ≠ 可以立即登记元数据
- 必须先确认对象在服务器端真实可见,才能把它纳入 Git 中的主清单和历史记录
3.6 上传侧“断点续传”的定义
这里不实现自定义字节级断点续传。
当前定义为:
中断后重新执行同一批上传
脚本会:
- 重新检查每个对象是否已存在
- 已成功对象跳过
- 未成功对象继续上传
对于当前仓库的大文件治理场景,这已经足够实用。
4. 下载增强方案
4.1 当前状态
当前 scripts/download_assets.py 是串行执行:
- 每次选一个文件
- 逐个执行
mc cp - 对大量文件恢复效率较低
4.2 推荐方案
在现有 scripts/download_assets.py 基础上增强,不额外拆脚本。
4.3 建议新增参数
--jobs N--continue-on-error--no-verify--check-size-first
4.4 下载流程
第一步:选取待恢复文件
保留现有模式:
--source--category--all
第二步:本地预检查
每个文件先判断:
- 本地不存在 → 需要下载
- 本地存在且 sha256 匹配 → 跳过
- 本地存在但不匹配 → 重新下载
第三步:并发下载
线程池中每个 worker 负责:
- 创建父目录
- 执行
mc cp remote -> local_target - 下载后校验 sha256
第四步:主线程汇总
输出汇总信息:
selectedskippeddownloadedfailedchecksum_failed
4.5 下载侧“断点续下”的定义
同样不做自定义 chunk checkpoint 文件管理。
当前定义为:
中断后重跑
- 已完成且校验通过的文件跳过
- 未完成或失败的文件继续
- 本地损坏文件重新拉取
这能够满足:
- bootstrap 中途失败后重跑
- 外网不稳定环境反复恢复
- 大批量下载恢复的断点继续能力
5. bootstrap 方案增强
5.1 当前状态
bootstrap_repo.sh 当前负责:
- alias 检查
download_assets.py --all- 规则检查
5.2 增强目标
保留其作为统一入口,但增加:
- 并发控制
- 校验策略控制
- continue-on-error 控制
- 远程环境变量入口
5.3 建议环境变量
GENERALANDROID_MC_ALIASGENERALANDROID_MC_ENDPOINTGENERALANDROID_MC_ACCESS_KEYGENERALANDROID_MC_SECRET_KEYGENERALANDROID_TRANSFER_JOBSGENERALANDROID_VERIFY_DOWNLOADSGENERALANDROID_CONTINUE_ON_ERROR
5.4 示例
GENERALANDROID_MC_ALIAS=uploadrw \
GENERALANDROID_MC_ENDPOINT=http://tx2.898311.xyz:9010 \
GENERALANDROID_MC_ACCESS_KEY=xxx \
GENERALANDROID_MC_SECRET_KEY=yyy \
GENERALANDROID_TRANSFER_JOBS=4 \
GENERALANDROID_CONTINUE_ON_ERROR=1 \
bash scripts/bootstrap_repo.sh5.5 bootstrap 应输出的信息
执行时建议显示:
- 当前 alias
- endpoint(如适合显示)
- jobs
- verify 开关
- continue-on-error 开关
让同事可以明确当前到底在用哪套恢复参数。
6. 外网 / 远程环境方案
6.1 当前事实
minio.898311.xyz当前不是 MinIO API endpoint- 外网恢复主路径已明确为:
http://tx2.898311.xyz:9010
6.2 方案
脚本统一只认 alias。bootstrap 负责:
- alias 已存在 → 直接使用
- alias 不存在 → 用环境变量自动创建
因此远程同事不需要提前手工执行 mc alias set,只要提供环境变量即可。
7. manifest / sha / history 规则
7.1 主清单
assets/resource_manifest.json- 唯一主数据源
7.2 阅读视图
assets/resource_manifest.md- 派生文件
- 不手工维护
7.3 校验文件
assets/assets_sha256.txt- 派生文件
- 不手工维护
7.4 生命周期历史
assets/asset_history.jsonl- 只追加
- 不回写旧记录
8. 历史记录策略
upload
记录:
action = uploadsource_pathobject_keysha256sizecategoryoperatortime
update
记录:
action = updatesource_pathprevious_object_keyprevious_sha256previous_size- 新对象信息
remove
记录:
action = removesource_pathobject_keysha256sizekeep_remoteremove_local
9. 明确不做的事情
9.1 不自己实现 S3 chunk protocol
不自己写:
- multipart init
- part upload
- part list
- part resume
- complete upload
原因:
- 复杂度高
- 风险大
- 当前项目收益不足以支撑这套自研成本
9.2 不把 manifest 并发写入
这是硬性禁止项。
9.3 不把单文件上传强行复杂化
upload_assets.py 继续保持稳定的单文件入口,不承担批量并发导入职责。
10. 需要改动的文件
核心脚本
scripts/download_assets.pyscripts/bootstrap_repo.shscripts/upload_assets.pyscripts/update_asset.py- 新增:
scripts/batch_upload_assets.py
复用库
scripts/asset_manifest_lib.py
文档
README.mdmain/blog/gitlab/minio_migration_plan.mdmain/blog/gitlab/minio_migration_progress.md- 必要时:
.claude/commands/clone-init.md
11. 验收标准
当前口径约束:
assets/resource_manifest.json是主清单assets/resource_manifest.md是阅读视图assets/assets_sha256.txt是派生校验文件assets/asset_history.jsonl是历史记录- 多线程 = 多文件并发
- 断点恢复 = 中断后重跑跳过已完成文件
11.1 单文件上传
upload_assets.py仍可用- manifest 写入正确
- history 写入正确
11.2 批量上传
batch_upload_assets.py --jobs 4- 多文件并发上传成功
- 失败项不会污染成功项元数据
- 成功项统一写入 manifest / sha / history
11.3 单文件下载
download_assets.py --source- 校验通过
11.4 并发下载
download_assets.py --all --jobs 4- 比串行快
- 结果一致
11.5 中断后重跑
- 中途 kill 掉
- 再执行同一命令
- 已完成文件跳过
- 剩余文件继续
11.6 bootstrap
- 本机 alias 成功
- 外网 env 自动建 alias 成功
- 下载链路成功
12. 详细验收步骤
12.1 单文件上传回归验收
目标:
- 证明现有单文件上传在传输增强后仍然可用
- 证明对象只有在远端确认存在后才会进入 manifest / sha / history
建议验证:
python3 scripts/upload_assets.py "assets/test_single_upload.txt" tools --alias local通过标准:
- MinIO 中对象存在
assets/resource_manifest.json中有对应条目assets/assets_sha256.txt中有对应记录assets/asset_history.jsonl中有upload记录- 上传后必须经过
mc stat确认远端对象存在,才允许落清单
12.2 批量上传验收
目标:
- 证明多文件并发上传可用
- 证明 manifest / sha / history 只会在远端确认成功后统一收口
建议验证:
python3 scripts/batch_upload_assets.py --file-list assets/test_upload_list.txt --jobs 4 --alias local通过标准:
- 成功项都能在 MinIO 中
mc stat查到 - manifest 中只出现“远端确认成功”的对象
asset_history.jsonl中有对应upload记录- 失败项不会污染 manifest / sha / history
12.3 多线程下载验收
目标:
- 证明
download_assets.py支持多文件并发恢复
建议验证:
python3 scripts/download_assets.py --all --jobs 4 --alias local
python3 scripts/download_assets.py --all --jobs 8 --alias local通过标准:
- 文件都能恢复
- SHA256 校验通过
- 并发下载结果与串行模式一致
12.4 断点恢复验收
目标:
- 证明下载中断后重新执行时会跳过已完成文件并继续剩余文件
建议验证:
- 执行批量恢复
- 中途手动终止
- 重新执行同一命令
通过标准:
- 已完成文件被跳过
- 未完成文件继续下载
- 最终所有文件恢复完成
- 不会重复全量重下已完成文件
12.5 bootstrap 验收
目标:
- 证明 clone 后统一入口仍然可用
- 证明远程 / 外网环境可以通过 env 自动建 alias 并恢复文件
本机验证:
bash scripts/bootstrap_repo.sh远程 / 外网验证示例:
GENERALANDROID_MC_ALIAS=uploadrw \
GENERALANDROID_MC_ENDPOINT=http://tx2.898311.xyz:9010 \
GENERALANDROID_MC_ACCESS_KEY=xxx \
GENERALANDROID_MC_SECRET_KEY=yyy \
GENERALANDROID_TRANSFER_JOBS=4 \
GENERALANDROID_CONTINUE_ON_ERROR=1 \
bash scripts/bootstrap_repo.sh通过标准:
- alias 不存在时能自动创建
- 下载脚本被正确调用
- 并发参数能透传
- 缺失文件能恢复
12.6 文档一致性验收
必须统一以下口径:
assets/resource_manifest.json是主清单assets/resource_manifest.md是阅读视图assets/assets_sha256.txt是派生校验文件assets/asset_history.jsonl是历史记录- 多线程 = 多文件并发
- 断点恢复 = 中断后重跑跳过已完成文件
- 远程机器通过 env + bootstrap 接入
minio.898311.xyz不是 MinIO API endpoint
通过标准:
- README 和迁移文档不再出现与当前实现冲突的旧说法
11.7 当前验收进展(截至当前)
目前已经完成的验收:
- Python 脚本语法检查通过:
scripts/download_assets.pyscripts/upload_assets.pyscripts/update_asset.pyscripts/asset_manifest_lib.pyscripts/batch_upload_assets.py
- CLI 帮助检查通过:
download_assets.py --helpupload_assets.py --helpbatch_upload_assets.py --help
- 失败路径检查通过:
download_assets.py --all --jobs 2 --continue-on-error --alias definitely-missing-alias- 已验证:
- 已完成文件会
skip verified existing - 失败项会进入 summary
continue-on-error行为成立
- 已完成文件会
- 真实单文件上传回归验收通过:
- 临时测试文件上传成功
mc stat确认对象存在- manifest / sha / history 正常写入
- 删除脚本清理成功
- 真实批量上传验收通过:
scripts/batch_upload_assets.py --batch-file ... --jobs 2 --alias local- 2 个测试文件并发上传成功
- 输出
confirmed并最终persisted 2 confirmed uploads - manifest 中出现对应测试条目,随后已清理
- 多线程下载验收通过:
- 对已迁移文件分别使用
--jobs 1 / 4 / 8恢复成功 - 不同并发参数下结果一致
- 对已迁移文件分别使用
- 断点恢复语义验收通过:
- 删除部分本地大文件后执行
download_assets.py --all --jobs 2 --continue-on-error --alias local - 已完成文件大量
skip verified existing - 缺失文件自动恢复
- 最终
summary: downloaded=3 skipped=59 failed=0
- 删除部分本地大文件后执行
当前尚待补完的验收:
- 真实远程 / 外网 bootstrap 验收(如需最终外网闭环确认)
- 全文档最终一致性核对(当前正在进行并已修正关键冲突项)
结论:
- 实现 Agent 已完成首轮落地并已合并到主工作区
- 上传后远端确认再记账、批量并发上传、多线程下载、重跑跳过已完成文件这四条主线都已在本地验收通过
- 当前处于“文档终验 + 远程最终验证收尾”阶段
11.8 最终通过条件
只有以下全部满足,才算本轮传输增强通过:
- 单文件上传回归通过
- 批量上传通过
- 多线程下载通过
- 断点恢复通过
- bootstrap 本机通过
- bootstrap 远程参数模式通过
- 文档一致性通过
12. 推荐实施顺序
第一步
先改:
scripts/download_assets.pyscripts/bootstrap_repo.sh
因为下载恢复是当前收益最大的。
第二步
新增:
scripts/batch_upload_assets.py
用于后续大批量上传。
第三步
补文档,统一写清:
- JSON 是主清单
- 多线程 = 多文件并发
- 断点恢复 = 中断后重跑跳过已完成文件
- 外网通过 env + bootstrap 接入
13. 最终结论
多线程上传下载可以做,而且是可靠的。
正确的方案不是自己重写协议,而是:
- 继续复用
mc做传输 - Python 做并发调度
- manifest / sha / history 串行收口
- 断点恢复按“重跑跳过已完成文件”实现
这套方案既能满足当前仓库的大文件治理需求,又不会把现有稳定链路推翻。