5. 为什么有这么多fs@overlay
Last updated
Was this helpful?
Last updated
Was this helpful?
overlay 整体思路跟 aufs 非常接近, 也是搞的 以文件为最小单元+CoW 的那一套, 镜像作为只读层, 用的时候再贴上一层读写层形成容器. 如上图所示, 在 overlay 中, 我们把镜像层叫做 lowerdir , 把读写层叫做 upperdir , 它俩合并出来的我们叫它 merged, merged 也是容器直接访问的点.
那么还是那个经典的问题, 我们已经有 aufs 了, 为什么还需要 overlay? 思考一个问题, 在 aufs 中如果我们访问一个文件, 我们应该怎样找到它? aufs 没有任何办法指明这个文件到底存在哪儿, 它可能来自镜像中的任何一层, 所以为了找到这个文件, 我们需要遍历镜像中的每一层, 用一种 O(n)
的效率遍历文件.
但是 overlay 只有两层, 只要这个文件不在读写层(upper), 它就一定在只读层里(lower), 因此效率高.
overlay 支持页缓存共享, 因此如果有好几个容器一起访问同一个文件, 他们一起用这个页缓存就好了
... 你不觉得上面的说法很奇怪吗? 是, 你overlay会合并诸多镜像层我知道, 但如果合并镜像层真的有这么好, 那为什么 aufs 不去合并呢? 为什么这么多年了, aufs 还没把这个特性抄过来呢? 这只能说明, 这种做法同样带来了一大堆问题, 严重到已经不值得抄了.
想一个问题, 我们有镜像层, 也有读写层, 最后我们还有一个merge好了的 merged 层, 那这是不是代表说, 同一个文件, 被存储了两次? 一次存在镜像层里, 另一次存在 merged 层里?
你是不是都明白了? merged路径下的所有文件, 都只是源文件的一个硬链接而已, 两者指向磁盘的同一个位置, 同样一个文件并没有被存储两次, 但这个inode, 也是同样是它问题的根源
除此之外, 另一个毛病也还是没有解决, 那就是overlay也是以文件为最小粒度的, 我们每次修改一下镜像层的文件, 都要先将它复制到读写层里, 哪怕是改动再小, 文件再大, 这些该做的事都得做, 我们后面会介绍一种方法不用复制整个文件的.
虽然文件使用的是同一个inode号, 但文件夹却单独搞了一个inode号, 光是这一个容器, 我们已经消耗了如此之多的inode号, 如果在大型服务器上起一大堆容器, 是真的蛮伤的.