Buffer(缓冲)
Buffer(缓冲)是为了提高内存和硬盘(或者其他I/O设备)之间的数据交换的速度而设计的。根据磁盘的读写设计的。把分散的写操作集中进行,减少磁盘碎片和硬盘的反复寻道,提高性能。
主要目的进行流量整形,把突发的大数量较小规模的 I/O 整理成平稳的小数量较大规模的 I/O,以*减少响应次数*,通常其中的数据在操作完成之后,buffer不会被继续使用;(比如从网上下电影,你不能下一点点数据就写一下硬盘,而是积攒一定量的数据以后一整块一起写,不然硬盘都要被你玩坏了)缓和冲击嘛。再比如你每秒要写100次硬盘,对系统冲击很大,浪费了大量时间在忙着处理开始写和结束写这两件事嘛。用个buffer暂存起来,变成每10秒写一次硬盘,对系统的冲击就很小,写入效率高了,日子过得爽了。极大缓和了冲击。linux有一个守护进程定期清空缓冲内容(即写入磁盘),也可以通过sync命令手动清空缓存。
Cache(缓存)
Cache(缓存)是为了提高CPU和内存之间的数据交换速度而设计的。也就是平常见到的一、二、三级缓存。CPU在执行程序所用的指令和读取数据都是针对内存的,速度比内存块,造价高,且CPU内不能集成太多集成电路,所以一般cache会比较小。为提高速度,增加了二、三级cache,根据程序的局部性原理而设计的,就是CPU执行的指令和访问的数据往往在集中的某一块,所以把这块内容放入cache后,CPU就不用再访问内存了。若cache中没有CPU所需要的内容,还要访问内存。
主要作用在于更好地利用局部性原理,减少不必要的I/O,避免代价。加快取用的速度。比如你一个很复杂的计算做完了,下次还要用结果,就把结果放手边一个好拿的地方存着,下次不用再算了。加快了数据取用的速度。
对比
如果你注意关心过存储系统的话,你会发现硬盘的读写缓冲/缓存名称是不一样的,叫write-buffer和read-cache。很明显地说出了两者的区别。
但是很多时候宏观上说两者可能是混用的。比如实际上memcached很多人就是拿来读写都用的。不少时候Non-SQL数据库也是。严格来说,CPU里的L2和L3 Cache也都是读写兼用——因为你没法简单地定义CPU用它们的方法是读还是写。硬盘里也是个典型例子,buffer和cache都在一块空间上,到底是buffer还是cache?
不要被这类理念所禁锢,拿cache做buffer用行不行?当然行,只要能控制cache淘汰逻辑就没有任何问题。那么拿buffer做cache用呢?貌似在很特殊的情况下,能确定访问顺序的时候,也是可以的。简单想一下就明白——buffer根据定义,需要随机存储吗?一般是不需要的。但cache一定要。所以大多数时候用cache代替buffer可以,反之就比较局限。这也是技术上说cache和buffer的关键区别。
结论
Buffer和Cache都只是相对的概念
不要误解Buffer就是用来写的,Cache就是用来读的。读当然也可以用Buffer,比如你想一批一批地处理读取而非有啥处理啥的时候,就可以用读buffer。写当然也可以用cache,比如你的写入有很高的随机性的时候。具体什么场景用Buffer什么场景用Cache要根据场景的具体需要决定。
Cache或Buffer也不一定就是内存或者存在什么高速媒介上的东西。只要相对高速即可。我完全可以在硬盘上存Cache,比如有些游戏会在运行时建立预编译的shader,这本质上就是一种cache,它存在速度缓慢的硬盘上,因为读硬盘依旧比重新编译要快。Buffer也同理。