容器改动镜像里的一个大文件,第一次写入为什么会卡一下?这篇用 128 MiB 的文件实测 copy-up:读、追加、只改权限各要多久,upperdir 里多了什么,以及数据放在 volume 里有什么不同。
读 big1.bin 的 1 字节:0.1 / 0.1 / 0.1 ms(3 个新容器各跑一次;中位数 0.1 ms) 第 1 次往 big1.bin 追加 1 字节:2174.1 / 242.7 / 155.0 ms(3 个新容器各跑一次;中位数 242.7 ms) 第 2 次往 big1.bin 追加 1 字节:0.1 / 0.0 / 0.0 ms(3 个新容器各跑一次;中位数 0.0 ms) 第 3 次往 big1.bin 追加 1 字节:0.6 / 0.0 / 0.0 ms(3 个新容器各跑一次;中位数 0.0 ms) 对没碰过的 big2.bin 只做 chmod:862.0 / 309.0 / 179.6 ms(3 个新容器各跑一次;中位数 309.0 ms) 往 small.txt(1 KB)追加 1 字节:8.7 / 4.1 / 3.7 ms(3 个新容器各跑一次;中位数 4.1 ms) 新建并写入 128 MiB 的新文件(含 fsync):3744.2 / 999.6 / 935.1 ms(3 个新容器各跑一次;中位数 999.6 ms)
读文件不会触发复制(0.1 ms)。第一次往 128 MiB 的文件追加 1 字节,三个新容器分别花了 2174.1、242.7、155.0 ms;随后再追加只要约 0 ms。三次数字差别很大,这台机器上同时还跑着别的容器,我没有隔离干扰,所以别把某个绝对值当成基准,看量级和“只有第一次慢”这个现象。
只对 big2.bin 做 chmod,也要 179.6~862.0 ms;往 1 KB 的小文件追加只要几毫秒。这个版本的 overlay 在元数据改动时也复制整个文件(见 upperdir 里 big2.bin 是完整的 134217728 字节);是否有 metacopy 之类的选项能避免,我没有测。
upperdir 里的文件(最后一个容器):134217731 ./data/big1.bin ; 134217728 ./data/big2.bin ; 1025 ./data/small.txt ; 134217728 ./new.bin ; 5781 ./usr/local/lib/python3.12/encodings/__pycache__/__init__.cpython-312.pyc ; 12414 ./usr/local/lib/python3.12/encodings/__pycache__/aliases.cpython-312.pyc ; 2153 ./usr/local/lib/python3.12/encodings/__pycache__/utf_8.cpython-312.pyc big1.bin 在 upperdir 里的大小 = 134217731 字节(原来 134217728,追加了 3 字节);big2.bin 做了 chmod 后 = 134217728 字节
big1.bin 的大小是 134217731 字节,整个文件都在 upperdir 里;改动 1 字节占用了 128 MiB 的可写层空间。镜像里有大文件又要频繁改的程序(比如数据库文件)不要放在镜像层里。
volume 里的 big1.bin 第 1 次追加 1 字节: 0.0 ms
把大文件放在 volume 里,追加 1 字节是 0.0 ms,因为 volume 不是镜像的层。这个对比没有测 volume 的读写吞吐,只说明没有 copy-up。