闲话缓存:概述

每当我们讨论缓存时,总是会对如下几个词比较熟悉,

Write-back,  write-through, write-around

似乎,缓存主要是为“写”设计的,其实这是错误的理解,写从缓存中获得的好处是非常有限的,缓存主要是为“读”服务的。

之所以我们要顺带提一下,在一个缓存系统中,如何处理写的顺序,是因为,在写的过程中,需要动态的更新缓存(否则就会产生数据不一致性的问题),以及后端主存。这三个词都是用来表示如何处理写更新的。就是用什么方式来处理写。

在一个有缓存的层次结构中,如何理解缓存是为“读”服务的?这涉及到读请求的处理序列。对于每一个读请求,我们都会用如下的操作序列去处理它:

1.      在缓存中查找请求对应的数据

a.      如果找到,则直接返回给客户

b.      如果没找到,则把请求的数据读入缓存(更新缓存),然后把数据返回给客户

既然缓存主要是为读服务的(后面的文章,我们会讨论,用什么方式来改善写的性能),那么为了提高读的性能,或者说减少读的响应时间,我们就要提高缓存的命中率,减少缓存的miss 率。这也是我们缓存算法设计的目标。

那么我们来想想,在设计缓存时,我们应该从哪几方面考虑来达到这个缓存的设计目标呢?根据我们上面提到的读请求的操作序列,我们可以从如下几个方面来思考:

1.      我们应该尽量多的用有用的数据填满缓存。也就是说,我们要充分利用缓存。

a.      这是缓存模块和其它模块不同的地方,并不是说缓存中的数据越少越好,而是有用的数据越多越好。

b.      这里有个非常好的列子,就是Windows的内存占用率总是非常高,很多人都表示过不满。其实这是一个非常好的设计。Windows总是试图尽量利用那些空闲的内存,用来缓存磁盘上的数据,以此来提高系统的整体性能。否则你那么大的内存,就为了拿来好看?

2.      如何获取“有用”的数据。这里,“有用”的数据的定义就是可能在不久的将来会被client用到的数据。为了得到有用的数据,我们需要预估客户端应用的I/O 模式,比如顺序读写,随机读写等等。这里就涉及到了“pre-fetch”算法。

a.      Pre-fetch(预取算法):是一种预测客户端应用下次读写的数据在哪里的算法,并且把客户要用的数据提前放入缓存中,以此来提高读的响应速度。

3.      问题来了,如果缓存已经满了,那么如何存放新的需要缓存的单元呢?这就牵涉到缓存设计的另一端:淘汰算法。

a.      相比于pre-fetch,淘汰算法(replacement policy)更加重要。因为对于随机的I/O, 预取算法是无能为力的。

b.      淘汰算法的关键是如何判断一个单元的数据比另一个单元的数据更加重要。但需要淘汰一个数据单元时,丢弃掉最不重要的那个数据单元,并且用它来存放新的数据。

4.      缓存算法设计的另外一个重要的考虑因素是算法的复杂度。或者说是实现或运行算法带来的额外开销。我们希望算法容易实现,并且额外开销不随着缓存大小的改变而改变。包括容量的额外开销和计算的额外开销。

接下来的文章,我们会详细讨论预取算法和淘汰算法。

闲话缓存:概述

时间: 2024-11-05 20:43:28

闲话缓存:概述的相关文章

闲话缓存:ZFS 读缓存深入研究-ARC(二)

Solaris ZFS ARC的改动(相对于IBM ARC) 如我前面所说,ZFS实现的ARC和IBM提出的ARC淘汰算法并不是完全一致的.在某些方面,它做了一些扩展: ·         ZFS ARC是一个缓存容量可变的缓存算法,它的容量可以根据系统可用内存的状态进行调整.当系统内存比较充裕的时候,它的容量可以自动增加.当系统内存比较紧张(其它事情需要内存)的时候,它的容量可以自动减少. ·         ZFS ARC可以同时支持多种块大小.原始的实现假设所有的块都是相同大小的. ·  

闲话缓存:ZFS 读缓存深入研究-ARC(一)

在Solaris ZFS 中实现的ARC(Adjustable Replacement Cache)读缓存淘汰算法真是很有意义的一块软件代码.它是基于IBM的Megiddo和Modha提出的ARC(Adaptive Replacement Cache)淘汰算法演化而来的.但是ZFS的开发者们对IBM 的ARC算法做了一些扩展,以更适用于ZFS的应用场景.ZFS ARC的最早实现展现在FAST 2003的会议上,并在杂志<;Login:>的一篇文章中被详细描述. 注:关于杂志<:Login

闲话缓存:算法

从前面的文章中,我们已经了解到了缓存设计的目标,缓存设计应该考虑的因素.今天我们来看看一系列缓存算法以及它们如何去解决问题的.同时,我们也会涉及到各种缓存算法的优缺点. 这里我并不想讨论与预取(pre-fetch)相关的算法,主要是考虑各种淘汰算法.因为相比于预取算法,淘汰算法具有更大的通用性,对缓存好坏影响更大. 1.      时间(完全从最近使用的时间角度考虑) a.      LRU(least recently used):这种策略就是永远替换掉最近最少使用的缓存单元.它是最古老,应用

缓存概述

缓存从分布来说有两种: 一.客户端缓存 客户端缓存其实是浏览器的事情,当我们去访问一个新的网站的时候,第一次可能要花一阵子时间才能载入整个页面.然而以后再去时间就会大大缩短,原因就在于客户端缓存.现在浏览器都非常智能,它会在客户机器的硬盘上保留许多静态的文件,比如各种gif,jpeg等等.等以后再去的时候,它会尽量使用本地缓存里的文件,只有服务器端的文件更新了,或是缓存里面的文件过期了,它才会再次从服务器端下载这些东西.很多时候是浏览器替我们做了这件事情. 二.服务器缓存 有些东西没有办法或者说

缓存概述[1]

Java缓存机制概述-1 一.    概述 所谓缓存就是把程序经常使用的对象读到内存中,以后使用直接从内存中读取即可.一般针对的是:数据库.硬盘中的资源读取耗费大量时间.缓存是一种典型的空间换时间的方案. Java中使用最多的思想:key-value缓存,一般用Map实现. 1.0 缓存需要解决的问题 缓存数据的存放时间问题,比如Session会设置在timeout时间: 缓存数据和真实数据的同步问题,缓存中的数据可能会随着应用程序变化,那么缓存的数据就要同步会数据库中,以保持一致性: 多线程并

ATS缓存概述

在volume.config里面可以配置多个volume,比如说有4块磁盘,配了3个volume.每块磁盘都有3个volume,一个磁盘的一个volume是一个stripe,stripe是磁盘级别的最小单位.stripe存着若干个存储对象,默认每个对象最小占8000字节(proxy.config.cache.min_average_object_size),每个存储对象标示为一个fragment,默认大小是1M(proxy.config.cache.target_fragment_size),每

MemCached配置与缓存知识概述

先看看百度百科里面对缓存的介绍: 缓存(Cache memory)是硬盘控制器上的一块内存芯片,具有极快的存取速度,它是硬盘内部存储和外界接口之间的缓冲器.由于硬盘的内部数据传输速度和外界介面传输速度不同,缓存在其中起到一个缓冲的作用.缓存的大小与速度是直接关系到硬盘的传输速度的重要因素,能够大幅度地提高硬盘整体性能.当硬盘存取零碎数据时需要不断地在硬盘与内存之间交换数据,有大缓存,则可以将那些零碎数据暂存在缓存中,减小系统的负荷,也提高了数据的传输速度. 这个是介绍了电脑的硬盘缓存..当然,电

Hibernate缓存

一.Hibernate缓存概述 Hibernate中提供两个级别的缓存,一级缓存和二级缓存. 1.一级缓存是Session级别的缓存,它属于事物范围的缓存,一级缓存有hibernate进行管理. 2.二级缓存是sessionFactory级别的缓存,它属于进程范围的缓存,二级缓存又可分为"内置缓存"和"外置缓存",内置缓存:是hibernate在创建sessionFactory时会加载.hbn.xml文件并会在内存中初始化一些默认的sql语句,该内置缓存是只读的:外

iOS网络缓存扫盲篇--使用两行代码就能完成80%的缓存需求

iOS网络缓存扫盲篇 --使用两行代码就能完成80%的缓存需求 下篇预告:使用80%的代码来完成剩下的20%的缓存需求 .敬请 star (右上角)持续关注. 目录 当我们在谈论缓存的时候,我们在谈论什么? GET网络请求缓存 80%的缓存需求:两行代码就可满足 控制缓存的有效性 文件缓存:借助ETag或Last-Modified判断文件缓存是否有效 Last-Modified ETag 总结 一般数据类型借助 Last-Modified 与 ETag 进行缓存 剩下20%的网络缓存需求--真的