浅谈 DSec 的镜像分发与按需加载
文章目录
本文通过“一个任务只读取部分镜像数据”的例子,浅谈 DSec 的 Scalable Image Distribution and On-Demand Loading(可扩展的镜像分发与按需加载)。
为便于理解,下面以容器的 EROFS 镜像路径为例,不展开 microVM 的块设备实现、配置参数和性能测试。DSec 的设计依据论文 §4.4、§5.3;文末的组件资料用于补充基础概念。
What

先把最容易混淆的一点说清楚:
1 | 沙箱已经可以开始运行 |
DSec 将镜像存放在 3FS(Fire-Flyer File System) 中,让运行节点按需获取镜像数据,而不是先完整下载再启动。
3FS 是共享的分布式文件系统,可以汇聚多台存储节点的容量与带宽。DSec 复用这套已有基础设施,不再单独部署一套镜像分发系统。
可以把两个部分分开理解:
1 | 镜像分发: |
所以:
不必先把整套环境搬到本地,才能开始使用其中的一部分。
Why
论文观察到,沙箱需要的镜像种类很多,但单个任务往往只访问镜像中的一小部分内容。
假设每个节点都先下载完整镜像,就可能发生:
1 | 大量传输 → 本地保存完整镜像 → 实际只用其中一部分 |
这里浪费的不只是启动等待时间,还有传输、写盘和本地存储空间。
提前把完整镜像下载好,只是把这笔开销提前支付,并没有消除它。
因此,这套方案的目的可以概括为:
不仅让沙箱更早开始运行,也减少为未用到的镜像内容付出的代价。
这里少占的是运行节点上的完整镜像副本空间,不是从 3FS 中删除暂时没有访问的原始数据。
基础 Example
假设把一个镜像的数据部分简化成 8 个区域:
1 | A B C D E F G H |
任务启动需要 A、B,后续运行还会读取 E,其他区域不会主动访问。
下面只说明加载顺序,暂不考虑预读;字母与数量均为示意,不是论文中的测试数据。
先完整下载
1 | 下载 A、B、C、D、E、F、G、H |
即使 C、D、F、G、H 最后没有用到,也已经先传输了。
按需加载
1 | 先准备镜像元数据 |
在这个简化例子中,没有必要把其余区域全部拉到本地。
区别就在于:
不是把“下载整个镜像”挪到启动之后,而是不再要求整个镜像都必须下载。
实际系统会按块读取,并可能预读附近的数据,因此不能把“按需”理解为只传输应用明确读取的那几个字节。
How
只看三个配合的动作。
1. 镜像元数据先放本地
先区分两类信息:
1 | 元数据: |
EROFS 的多设备模式允许将文件数据放到独立的后端中。
DSec 利用这一能力,先把镜像元数据下载到运行节点,把文件数据留在 3FS。
可以把它类比为一本书:
1 | 目录与索引 → 先拿到手 |
这样,查找镜像里的文件,不必每走一级目录都去远端读取相应的目录信息。
2. 文件数据按需读取,尽量批量传输
读取只读层的文件内容时,已经缓存在本地的数据可以复用;需要的镜像数据尚未就绪时,再从 3FS 获取。
论文指出,3FS 更适合较大的 I/O。因此,这条路径还利用内核的 readahead(预读),把相邻数据块组织成较大的读取请求。
1 | 需要某段文件内容 |
这里两个动作并不矛盾:
1 | 按需:不要求先下载整个镜像 |
可以简单理解为:
不搬整本书,但也不必每次只取一个字。
3. 运行时写入留在本地
DSec 将容器的可写上层放在节点本地磁盘,避免把写日志等细碎操作都交给 3FS。
这与前面介绍的 OverlayFS 配合:
1 | 只读镜像层:提供初始内容 |
需要修改下层文件时,OverlayFS 按需执行 copy-up,再修改上层副本;不会直接改写共享的只读镜像。
因此,这里不是“所有读写都走远端”,而是将只读镜像数据的获取与运行时写入分开。
一个简单的取舍
按需加载不等于读取没有等待。
根据前面的流程,如果需要的数据还不在本地,当前读取仍然要等数据取回来。
1 | 先完整下载: |
省掉的是不必要的完整准备,不是所有的数据访问开销。
记忆图
1 | 运行节点 |
可以简单记成:
1 | 镜像:共享存放 |
一句话概括:
镜像保存在共享存储中,运行节点不必先搬来全部内容:先准备查找信息,再按需读取,把自己的改动留在本地。
参考资料: