↓Skip to main content
  1. Docs/

Dragonfly(三):注意事项、性能验证与故障排查

·7 mins· ·
Owl Dawn
Author
Owl Dawn
Table of Contents

从“能下载”到“能长期运行”
#

前两篇介绍了 架构与原理 和 部署使用。实验能下载后,接下来要回答:数据能保留多久、谁能访问、哪里会成为瓶颈、失败时是否还有退路,以及如何证明节省了源站流量。

本文仍以 Chart 1.7.0、控制面 v2.5.0、客户端 v1.4.0 为学习基线。生产环境要使用经过自身验证的版本与配置,不能把实验中的单副本、临时存储和固定示例密码照搬过去。

一、先确认业务是否适合 P2P
#

P2P 比较适合多台节点在一段时间内下载相同的大文件。它以节点磁盘、上传带宽和调度开销,换取更少的源站及跨网络重复传输。

如果源站很近、客户端带宽很低,或者下载时间主要花在解压和应用初始化上,收益就可能有限。因此要先测瓶颈,而不是默认安装 Dragonfly 后 Pod 一定启动更快。

跨机房流量昂贵时,还要考虑 Peer 之间是否跨机房传输。减少源站出口不代表一定减少跨区费用,需要合理安排 P2P 集群、位置配置与 Seed。

二、缓存不是文件的唯一存储
#

普通缓存会因为 TTL、磁盘压力、Pod 重建或磁盘故障而消失。storage.keep 只影响相应的重启保留行为,并不能代替持久卷,也不能阻止正常 GC。

例如,数据目录挂在 emptyDir 上,重建 Pod 后即使配置 keep,也不能指望旧缓存还在。改用 hostPath 或 PVC 后,还需要确认权限、节点归属和元数据恢复是否正常。

容量可以先按下面的思路估算:

缓存容量 ≈ 希望保留的热点内容
         + 新版本或预热的临时占用
         + 并发下载中的数据
         + GC 和故障处理所需余量

要看的是去重后实际内容和访问周期,而不是把所有镜像的显示大小简单相加。磁盘已满后才触发处理往往太晚,应提前观察使用率、写入延迟、inode 和 GC 情况。

TTL 也不是磁盘配额。 即使配置保留 30 天,磁盘压力回收仍可能更早删除缓存;反过来,保留时间较短也不保证磁盘始终有足够空间。

三、任务标识决定缓存能不能复用
#

预热成功却仍然回源时,先检查两次请求是否被识别为同一个任务:

  1. URL、tag、application、分片相关参数是否一致?
  2. 是否启用了相同的 blob digest 识别方式?
  3. 临时签名参数的过滤方式是否相同?
  4. 两个客户端是否进入同一个 P2P 集群?
  5. 原缓存是否已被回收,或者持有它的节点是否不可达?

不要为了提高命中率就删除所有 query 参数。例如,?version=1 和 ?version=2 可能就是不同内容;把它们忽略后会错误共享缓存。

也不要因为换一个输出文件名就认为创建了新任务:输出路径与内容身份不是同一件事。验证冷下载时,应使用明确的新内容身份或隔离测试环境。

四、区分三层认证与两段 TLS
#

层次 控制什么 不能替代什么
Registry / 源站认证 是否有权读取原始镜像或文件 不等于 P2P 内部服务已经隔离
Manager 管理 API 认证 是否允许提交管理、预热等操作 不等于具有镜像仓库拉取权限
Peer / 代理访问控制 谁能调用本地代理或节点服务 不能单靠 Kubernetes namespace 自动实现

同一个 P2P 网络里的节点可能共享内容,因此要根据实际信任边界设计网络和任务隔离。内容摘要用于判断字节是否匹配,不用于证明请求方有权限读取。

TLS 也有不同路径:客户端到本地代理、dfdaemon 到上游仓库、Peer 之间以及管理控制连接。某一段信任了 CA,不代表其他连接也自动信任。

遇到私有 CA 错误,应把 CA 配置到实际发起那段连接的进程。不要把长期关闭证书验证当成通用修复。若使用 HTTPS 代理拦截能力,还要明确代理 CA 的信任与密钥管理;它与普通 Registry mirror 接入不是同一个配置问题。

五、网络通了,不代表地址配置正确
#

组件通常既有监听地址,也有向其他节点公告的地址。监听在 0.0.0.0 表示接收连接,不表示别人应该连接 0.0.0.0;公告为 127.0.0.1 则会让远端节点连到它自己。

以本文客户端基线为例,需要按启用功能检查这些通信方向:

方向 用途 常见端口
Client / Scheduler → Manager 发现、注册、配置 TCP 65003
Client → Scheduler 下载调度与状态报告 TCP 8002
Scheduler / Peer → Peer 或 Seed 上传控制、元数据及相应 RPC TCP 4000
Peer → Parent 分片字节传输 TCP 4005;启用 QUIC 时另有 UDP 4006
本机运行时 → 本机代理 Registry / HTTP 代理入口 TCP 4001
回源方 → 源站 获取原始内容和认证相关请求 按源站协议,常见 80/443

端口以实际配置和渲染清单为准,不是所有功能都必须开启。只检查 Scheduler 的 Service 可达,不能证明 Peer 之间的分片传输可达;只开放 TCP,也不能证明启用的 QUIC 可用。

网络策略还要允许必要的 DNS、Registry Token 服务和重定向目标。预热接受外部 URL 时,应限制调用权限及可访问目标,避免下载服务被用于访问不应开放的内部地址。

六、带宽、磁盘和并发要一起看
#

一个 dfdaemon 可能同时从其他节点下载、向多个节点上传,并服务本机 containerd。它会与业务共享 NIC、磁盘和 CPU。

把并发提高一倍,不代表速度提高一倍。磁盘已经饱和时,更多分片可能增加排队;上传不设限时,也可能挤占业务出口。

推荐按这个顺序调整:

  1. 先测当前网络和磁盘吞吐,找出真正限制。
  2. 分开考虑下载、上传、回源和预取的限制。
  3. 每次只调整少数参数,保留前后对照结果。
  4. 看整体耗时及失败率,不能只看短时峰值带宽。

Seed 需要特别关注冷启动高峰:新版本第一次发布时,热点缓存尚未扩散,压力更可能集中在 Seed 和源站。预热应安排在业务高峰之前,并限制后台流量,避免预热反而影响线上请求。

七、多副本解决哪些问题
#

组件 多副本的价值 仍需考虑的事情
Manager 减少单个管理实例故障影响 共享数据库、Redis、管理入口和数据备份
Scheduler 提高调度服务可用性与处理能力 客户端重连、任务归属和状态恢复,不是自动同步全部普通任务内存
Seed 分摊回源和首次扩散压力 缓存分布、磁盘、拓扑和源站容量
每节点 Client 服务本节点并参与内容交换 单节点磁盘和网络故障,本机代理故障对拉镜像的影响

Scheduler 的普通任务关系主要是实例内状态,故障后可能需要客户端重连和重新登记。不能把“三个副本”理解为每份任务状态都已经有三份同步副本。

同样,有回源配置也不等于任何故障都能无缝恢复:运行时直连回退和 Dragonfly 自身回源是两层机制,触发条件及超时不同。应该在测试环境实际演练,确认源站能否承受回退高峰。

八、怎样判断加速是否有效
#

至少分别测四种情况:

场景 测到什么
新任务、P2P 无缓存 首次获取和扩散成本
本机无缓存、其他节点有缓存 跨节点共享收益
本机已有 Dragonfly 缓存 本地缓存收益
containerd 已有镜像层 可能根本不发生下载,不能当成 P2P 收益

每组测试保持内容、节点数量、并发和网络条件尽量相同,记录:

  • 总耗时和尾部耗时,例如最慢一批节点需要多久完成。
  • 下载成功率、重试和超时数量。
  • 源站、Seed 和普通 Peer 的发送字节数。
  • 节点 NIC、CPU、磁盘吞吐与延迟。
  • 下载完成后的镜像解压时间和 Pod Ready 时间。

可以用“回源字节 / 总下载字节”帮助判断流量来源,但要统一统计窗口和口径:预热流量、历史缓存、重复尝试及控制请求都可能影响结果。

源站发出数据少了,但某些节点更慢,可能说明瓶颈转移到了 Peer 上传或磁盘;总拉取时间短了,但 Pod Ready 没变,则继续检查解压、init 容器和应用启动。

九、按请求阶段排障
#

从请求入口、调度、数据传输、存储到应用启动逐步定位故障

不要一开始就调并发或重启全部组件。先确定请求在哪个阶段失败,再找对应日志。

现象 优先检查
dfget 无法连接 dfdaemon 进程是否运行、socket 路径和权限、调用者是否能访问 socket
containerd 没有进入本地代理 生效的 CRI 配置、hosts.toml、代理地址,以及镜像是否已在 containerd 缓存
找不到 Scheduler Manager/本地动态配置、DNS、集群 ID、地址与证书
有候选父节点但读不到分片 公告地址、Peer 间端口、父节点状态、协议及防火墙
401 / 403 实际回源请求的凭据、权限与 Token 服务,不要只看管理 API 登录状态
404 URL、上游 Registry、镜像路径、digest 和重定向
429 源站或代理限流,是否遵守退避;避免用更多重试放大压力
摘要不匹配 内容是否变动、任务标识是否冲突、来源和磁盘;不要继续信任错误缓存
预热成功但真实拉取回源 任务标识、集群、GC、真实请求入口是否一致
一开始快,随后持续卡顿 某些慢分片、热点父节点、磁盘排队和上传限速
Pod Running 但应用未就绪 就绪探针和应用依赖,未必仍是 Dragonfly 下载问题

一条请求最好保留时间、URL(脱敏)、task ID、peer ID、节点、候选父节点和具体错误。不要把 Token、签名 URL、Authorization 头直接粘贴到公共日志或工单。

十、上线和升级时保留退路
#

先在少量节点验证,再扩大范围。保存运行时原配置、Chart 版本、镜像版本和实际 values,升级前检查发行说明与配置变更,不在同一次变更里同时改版本、拓扑、缓存策略和并发。

回退时不仅考虑 Helm release,还要考虑数据库迁移、客户端缓存格式和主机配置是否兼容。回退 Helm 不能保证回退已经执行的数据库或主机修改。

特别是 dfinit 接入后,应先验证如何恢复直接拉取,再进行全量推广。卸载前先解除运行时对本地代理的依赖,避免组件卸载后新的 Pod 反而无法拉镜像。

参考
#

Related

Dragonfly(一):入门、组件与工作原理
·8 mins
Dragonfly(二):从文件下载到 containerd 镜像加速
·7 mins
Kubernetes 高可用集群部署
·4 mins
go 1.24 新特性
·2 mins
分布式浅谈
·12 mins
分布式
Kubenetes 搭建(使用 debian12)
·4 mins