为何docker pull不能并行提取镜像层?是否可通过并行化提速?
问题解答:Docker拉取镜像时镜像层提取的并行支持情况
- 从Docker镜像层的设计原理来看,层提取(untarring)操作本身没有强顺序依赖,技术上完全可以并行执行,目前默认顺序执行的逻辑属于历史实现选择和存储介质适配的结果,不是不可突破的限制。镜像层虽然存在上下依赖关系,但这种依赖仅体现在最终联合挂载的顺序上,解压操作本身是将每个层的tar包写入独立的存储路径,不存在数据依赖,因此完全支持并行处理。
为什么默认是顺序执行?
主要有两方面原因:
- 历史实现限制
早期Docker以及底层依赖的containerd runtime的镜像拉取模块在设计时,将层的依赖校验和提取流程绑定,默认按层的依赖顺序从底到顶依次提取,最初没有实现并行处理的逻辑。 - 机械硬盘(HDD)的性能适配
HDD的随机IO性能极差,如果同时并行解压多个层,会导致磁盘大量随机寻道,反而比顺序解压的整体速度更慢,在SSD还未普及的阶段,顺序提取是更稳妥的默认选择。
并行提取的支持现状
目前主流的容器runtime已经支持并行提取:
- containerd从1.5版本开始正式支持并行提取镜像层,可通过配置参数调整并行解压的线程数
- Docker 20.10及以上版本,在开启containerd镜像存储功能后,即可启用并行提取能力
对于你提到的mirekphd/ml-cpu-r40-base这类有数十个层的大型镜像,在SSD环境下开启并行提取后,确实可以获得数倍到数十倍的提取速度提升,和你的预期完全吻合。
并行提取对Dockerfile编写逻辑的优化
正如你提到的,并行提取普及后,开发者完全不需要再为了减少层数量,把多个命令拼接成一行RUN指令:
- 拆分多层可以最大化利用构建缓存,大幅降低镜像构建的耗时
- 单条RUN指令对应单一操作,Dockerfile的可读性、可调试性都会显著提升
- 多层带来的少量元数据开销,和构建、拉取、运行的效率提升相比,完全可以忽略不计
内容的提问来源于stack exchange,提问作者mirekphd
相关产品推荐
相关产品推荐

