ZFS 文件系统 ( 9 ) -- ARC 可调替换缓存

第四章    可调替换缓存(ARC)

传统缓存    

在Linux或者其他的操作系统中采用的缓存机制一般是所谓的最近最少使用的缓存算法(LRU)。LRU的工作原理就是当一个程序获取数据块时,他们也会被丢进缓存,缓存就是越积越多,这时候由于缓存采用的是先进先出的算法,那么那些老一些的数据会被踢出缓存,就算他使用非常的频繁,你可以把他想象成一条传送带,块被放进高速缓存最近使用的部分,越来越多的数据的读取并放入缓存,那些数据会被慢慢的推向最近最少使用的告诉缓存部分,然后会被逐出,换句话说,会掉出传送带。

ZFS 文件系统 ( 9 ) -- ARC 可调替换缓存_第1张图片


图片显示LRU算法和FIFO调度

大量连续从磁盘读取数据并放入缓存中时,他会有一种将之前频繁请求的页驱逐出缓存,然后放入新数据,尽管这样的数据只需要使用一次,他导致的最终结果就是缓存中保留大量的无价值,无意义,不再需要的数据。当然,他最终也会被驱逐出缓存。

还有只用最近最不常用缓存算法(LFU),不过他却遭受着一些问题,比如新的数据只要不被频繁读取就会被驱逐。所以,显而易见最好方式就是结合这两种方式,LFU和LRU。


ZFS的缓存机制ARC

ZFS的可调缓存机制ARC是一种同时缓存数据块请求以及频繁的数据块请求的缓存机制。这是IBM专利自适应替换缓存的基础上的一些修改和扩展。

术语

可调替换缓存驻留与物理的RAM,他采用了高速缓存中最常使用的LRU和LFU算法集法。

  • Cache Directory    一个包含MFU、MRU、影像MFU、影像MRU的目录索引。
  • MRU Cache           最近使用的告诉缓存ARC,最近请求数据块从文件系统缓存。
  • MFU Cache            最频繁使用的高速缓存ARC,最频繁使用的数据块从文件系统缓存。
  • Ghost MRU             将数据页驱逐返回磁盘以节省空间的MRU,指针仍然可以追踪到被赶回磁盘的页的位置。
  • Ghost MFU              将数据页驱逐返回磁盘以节省空间的MFU,指针仍然可以追踪到被赶回磁盘的页的位置。

二级可高速缓存,或L2ARC-A, 不存在与物理RAM的告诉缓存,一般驻留在SSD上。

ARC算法

这里简单介绍一下IBM ARC是如何工作的,他可以了解如何优先防止在MRU和MFU。首先,让我们假设你有8页缓存,四页缓存将用MRU,四页将采用MFU,另外,也将有4个影像MRU和4个影像MFU指针。因此,这个缓存目录将会影响这16页的激活或者驱逐状态。

ZFS 文件系统 ( 9 ) -- ARC 可调替换缓存_第2张图片

图片设定算法启动之前的状态

1. 正如所料,块A才能够文件系统读取,他会被缓存到MRU中。在缓存目录的索引指针也将指向将引用的MRU页。

ZFS 文件系统 ( 9 ) -- ARC 可调替换缓存_第3张图片

图片表示ARC启动第一步

2. 假设现在另外一块数据(B)从文件系统读取,他也会被缓存到MRU中,在缓存目录中的索引指针也将指向第二个MRU页。由于块B读取时间更近于块A,那么在缓存中他会比A得到更高的优先级,下面就是存在于缓存的两个页。

ZFS 文件系统 ( 9 ) -- ARC 可调替换缓存_第4张图片

图片表示ARC第二步

3. 现在我们的块A将要被重新从文件系统中读取,这将会导致读取2次块A,那么这就是频繁的读取,块A将会被存储在MFU之中,(一个块至少需要读取2次以上,并且要是最近请求的数据,才会被存储在MFU中)。于是,块A不不仅仅只保存在了MRU的缓存目录中,也将保存到MFU中,因此,虽然只有2个页面驻留于高速缓存中,在高速缓存的目录会存在三个指向这两个块的索引指针。

ZFS 文件系统 ( 9 ) -- ARC 可调替换缓存_第5张图片

图片表示ARC第三步

4. 最终,通过之前的步骤,会将MRU和MFU的高速缓存目录指针填满。

ZFS 文件系统 ( 9 ) -- ARC 可调替换缓存_第6张图片

图片表示ARC第四步

5. 接下来的会变得很有意思。假设我们需要从文件系统中读取一个新块(没有被缓存过),由于鸽子洞原理,我们需要缓存的页面比缓存还多。因此,我们需要从缓存中驱逐一个页面,MRU的最古老的页面会收到驱逐通知,然后影像MRU将会把该块加入之中。于是空出的新块现在可以缓存数据。

ZFS 文件系统 ( 9 ) -- ARC 可调替换缓存_第7张图片

图片表示ARC第五步

6. 当从文件系统读取一个新块时,正如所料,它会被存储在MRU中,同时,会填充缓存以及影像MRU(Ghost MRU)。

ZFS 文件系统 ( 9 ) -- ARC 可调替换缓存_第8张图片

图片表示ARC第六步

7. 在某一个时刻,我们设想一下,最近被驱逐的页面重新从文件系统读取,这时侯Ghost MRU(影像MRU)知道这是最近从缓存中剔除的,我们称之为“一个Ghost  缓存命中”。 由于ZFS知道这是近日缓存,我们需要把他放回到MRU缓存。(当然不是MFU缓存,因此他不是从Ghost MFU之中而来)。

ZFS 文件系统 ( 9 ) -- ARC 可调替换缓存_第9张图片

图片表示ARC第7步

8. 不幸的是,我们的缓存太小,无法存储更多的页,因此我们必须让他扩大一个页来存储一个新的命中页,由于缓存就只有这么大,那么只能调整MRU和MFU的大小来腾出空间给新的页面。算法的原理类似于Ghost MRU和Ghost MFU。

ZFS 文件系统 ( 9 ) -- ARC 可调替换缓存_第10张图片

图片表示ARC第八步

想象一下两个不同场景的工作负荷,一个工作负荷读取大量的随机数据,而且很少会有重复,MRU将有可能缓存大多数的数据,而MFU则会很少缓存。这时候缓存会调整为MRU提供更多的空间。另外一种情况则正好相反,虽然连续读取大量数据,不过大多数为重复数据,而很少会有新的数据,MFU在这样的情况下会占用多一些的空间,MRU则会少占用一些。

还记得我们之前提到的传统的缓存方案吗?Linux内核就是才从的LRU缓存机制,以交换磁盘和缓存页面。因此他总是垂青于最近的缓存命中率超过了频繁的高速缓存命中。这有时候会有严重的问题,如果你需要读取大量的块却只需要一次,他还是会不断的缓存到Cache中。最后,缓存中存在着需要没有意义的数据,需要频繁读取的被交换回了磁盘交换区。ARC缓存将不会存在这样的问题,他会自动的适应负荷。(这就是他被称之为自适应预读缓存缓存的原因)


你可能感兴趣的:(ZFS文件系统)