Dragonfly 成为 CNCF 孵化项目我们与基金会首位华人 TOC 聊了聊( 二 )

  • Registry:容器镜像的存储仓库 , 每个镜像由多个镜像层组成 , 而每个镜像层又表现为一个普通文件;
  • SuperNode:Dragonfly的服务端 , 它主要负责种子块的生命周期管理以及构造 P2P 网络并调度客户端互传指定分块;
  • Block:当通过 Dragonfly下载某层镜像文件时 , SuperNode 会把整个文件拆分成一个个的块 , SuperNode 中的分块称为种子块 , 种子块由若干初始客户端下载并迅速在所有客户端之间传播 , 其中分块大小通过动态计算而来;
  • DFget:Dragonfly 的客户端 , 安装在每台主机上 , 主要负责分块的上传与下载以及与容器 Daemon 的命令交互;
  • Peer:下载同一个文件的 Host 彼此之间称为 Peer 。
  • 处理步骤如下:
    1.首先由 Pouch Container 发起 Pull 镜像命令 , 该命令会被 DFget 代理截获;2.然后由 DFget 向 SuperNode 发送调度请求;3.SuperNode 在收到请求后会检查对应的文件是否已经被缓存到本地 , 如果没有被缓存 , 则会从 Registry 中下载对应的文件并生成种子块数据(种子块一旦生成就可以立即传播 , 而并不需要等到 SuperNode 下载完成整个文件后才开始分发) , 如果已经被缓存 , 则直接生成分块任务;4.客户端解析相应的任务并从其他 Peer 或者 SuperNode 中下载分块数据 , 当某个 Layer 的所有分块下载完成后 , 一个 Layer 也就下载完毕 , 此时会传递给容器引擎使用 , 而当所有的 Layer 下载完成后 , 整个镜像也就下载完成了 。
    通过上述 P2P 技术 , Dragonfly 可以彻底解决镜像仓库的带宽瓶颈问题 , 充分利用各个 Peer 的硬件资源和网络传输能力 , 达到规模越大传输越快的效果 。 值得一提的是 , Dragonfly 的系统架构不涉及对容器技术体系的任何改动 , 完全可以无缝支持容器使其拥有 P2P 镜像分发能力 , 以大幅提升文件分发效率 。
    2. 远距离传输
    Dragonfly 通过 CDN 缓存技术 , 使每个客户端可以就近从 SuperNode 中下载种子块 , 而无需跨地域进行网络传输 。 CDN 缓存原理大致如下:

    Dragonfly 成为 CNCF 孵化项目我们与基金会首位华人 TOC 聊了聊
    本文插图
    同一个文件的第一个请求者会触发检查机制 , 根据请求信息计算出缓存位置 , 如果缓存不存在 , 则触发回源同步操作生成种子块;否则向源站发送 HEAD 请求并带上 If-Modified-Since 字段 , 该字段的值为上次服务器返回的文件最后修改时间 , 如果响应码为 304 , 则表示源站中的文件目前还未被修改过 , 缓存文件是有效的 , 然后再根据缓存文件的元信息确定文件是否是完整的 , 如果完整 , 则缓存完全命中;否则需要通过断点续传方式把剩下的文件分段下载过来 , 断点续传的前提是源站必须支持分段下载 , 否则还是要同步整个文件 。 如果 HEAD 请求的响应码为 200 , 则表示源站文件已被修改过 , 缓存无效 , 此时需要进行回源同步操作;如果响应码既不是 304 也不是 200 , 则表示源站异常或地址无效 , 下载任务直接失败 。
    通过 CDN 缓存技术可以解决客户端回源下载以及就近下载的问题 , 但是如果缓存不命中 , 针对跨域远距离传输的场景 , SuperNode 回源同步的效率将会非常低 , 这会直接影响到整体的分发效率 , 为了解决该问题 , Dragonfly 采用了一种自动化层级预热机制来最大程度的提升缓存命中率 , 其大致原理如下:

    Dragonfly 成为 CNCF 孵化项目我们与基金会首位华人 TOC 聊了聊
    本文插图
    通过 Push 命令把镜像文件推送到 Registry 的过程中 , 每推送完一层镜像就会立即触发 SuperNode 以 P2P 方式把该层镜像同步到 SuperNode 本地 , 通过这种方式 , 可以充分利用用户执行 Push 和 Pull 操作的时间间隙(大概 10 分钟左右) , 把镜像的各层文件同步到 SuperNode 中 , 这样当用户执行 Pull 命令时 , 就可以直接利用 SuperNode 中的缓存文件 , 自然而然也就没有远距离传输的问题了 。


    推荐阅读