Cache和Buffer都是缓存,主要的区别是什么?

更新时间:2023-07-13 12:39:52 阅读: 评论:0

Cache和Buffer都是缓存,主要的区别是什么?
Cache和Buffer都是缓存,主要的区别是什么?
什么是buffer/cache?
buffer和cache是两个在计算机技术中被⽤滥的名词,放在不通语境下会有不同的意义。在Linux的内存管理中,这⾥的buffer指Linux内存的:Buffer cache。这⾥的cache指Linux内存中的:Page cache。
毛笔作品图片
翻译成中⽂可以叫做缓冲区缓存和页⾯缓存。在历史上,它们⼀个(buffer)被⽤来当成对io设备写的缓存,⽽另⼀个(cache)被⽤来当作对io设备的读缓存,这⾥的io设备,主要指的是块设备⽂件和⽂件系统上的普通⽂件。
但是现在,它们的意义已经不⼀样了。在当前的内核中,page cache顾名思义就是针对内存页的缓存,说⽩了就是,如果有内存是以page进⾏分配管理的,都可以使⽤page cache作为其缓存来管理使⽤。
阿拉的海当然,不是所有的内存都是以页(page)进⾏管理的,也有很多是针对块(block)进⾏管理的,这部分内存使⽤如果要⽤到cache功能,则都集中到buffer cache中来使⽤。
(从这个⾓度出发,是不是buffer cache改名叫做block cache更好?)然⽽,也不是所有块(block)都
有固定长度,系统上块的长度主要是根据所使⽤的块设备决定的,⽽页长度在X86上⽆论是32位还是64位都是4k。
明⽩了这两套缓存系统的区别,就可以理解它们究竟都可以⽤来做什么了。
什么是page cache?
Page cache主要⽤来作为⽂件系统上的⽂件数据的缓存来⽤,尤其是针对当进程对⽂件有read/write操作的时候。
如果你仔细想想的话,作为可以映射⽂件到内存的系统调⽤:mmap是不是很⾃然的也应该⽤到page cache?在当前的系统实现⾥,page cache也被作为其它⽂件类型的缓存设备来⽤,所以事实上page cache也负责了⼤部分的块设备⽂件的缓存⼯作。
什么是buffer cache
Buffer cache则主要是设计⽤来在系统对块设备进⾏读写的时候,对块进⾏数据缓存的系统来使⽤。这意味着某些对块的操作会使⽤buffer cache进⾏缓存,⽐如我们在格式化⽂件系统的时候。
总t淋巴细胞偏高
⼀般情况下两个缓存系统是⼀起配合使⽤的,⽐如当我们对⼀个⽂件进⾏写操作的时候,page cache
的内容会被改变,⽽buffer cache则可以⽤来将page标记为不同的缓冲区,并记录是哪⼀个缓冲区被修改了。
这样,内核在后续执⾏脏数据的回写(writeback)时,就不⽤将整个page写回,⽽只需要写回修改的部分即可。
知乎讨论话题链接:
cache是为了弥补⾼速设备和低速设备的鸿沟⽽引⼊的中间层,最终起到加快访问速度的作⽤。
⽽buffer的主要⽬的是进⾏流量整形,把突发的⼤数据较⼩规模的I/O整理成平稳的⼩数量较⼤规模的 I/O,以减少响应次数(⽐如从⽹上下电影,你不能下⼀点点数据就写⼀下硬盘,⽽是积攒⼀定量的数据以后⼀整块⼀起写,不然硬盘都要被你玩坏了)。
这两者还是有相关性的。⾸先cache是缓存,buffer是缓冲,虽然翻译有那么⼀个字的不同,但这不是重点。
为了说明这个问题,让我将他们分开来说:read cache(读缓存),read buffer(读缓冲),write cache(写缓存),write buffer(写缓冲)。
⽆论缓存还是缓冲,其实本质上解决的都是读写速度不匹配的问题,从这个⾓度,他们⾮常相似。
⾸先讨论读缓存跟读缓冲。读缓存跟读缓冲的最⼤区别在于,读缓存的⽬标数据是始终有效的,如果不从缓存中读取,也可以直接读取实际数据,只不过实际数据读取会慢⼀些,当这个数据在缓存中,读取速度将会变快。当⼀个缓存中的数据被多次读取,实际上就减少了该数据从慢速设备中读取的量,这就存在某种算法去选择「什么数据需要保存在cache中」,因为尽可能多的让cache命中能提⾼性能。先进⼊cache的数据不⼀定先被读取,甚⾄说进⼊cache的数据有可能永远不被读取就被清除了,因此read cache呈现出⾮常明显的随机访问特性。
⽽读缓冲buffer的数据则不是始终有效,⽽是实时⽣成的数据流,每当buffer满或者主动flush buffer的时候触发⼀次读取,对于⼩数据,这样可以减少读取次数,对于⼤数据,这可以控制单次读取的数据量。换句话说,⽆论数据量⼤还是⼩,单次读取数据量都按照buffer尺⼨进⾏归⼀化了。通常来说,先喂给buffer 的数据⼀定会先被读取,所有buffer的数据⼏乎⼀定会被读取,这是很明显的顺序访问特性。
【注】从上⾯的情况看到,读缓存以及读缓冲很明确的反应出了我所说的表⾯特性。⽽其本质特性在于cache的⽬标是减少读取总量每次cache命中都减⼩了读取总量。⽽buffer并不能减少读取总量,只能规整化每次读取数据的尺⼨⼤⼩。
说到write cache跟write buffer?
我们先说write buffer,write buffer是read buffer的对应,对于⼩数据的写⼊,它需要填满write buffer再进⾏⼀次写⼊,对于⼤数据,⼤数据会被分割到buffer尺⼨的⼤⼩分批写⼊。因此,write buffer 的⽤处在于使得每次写⼊的数据量相对固定。如果⼀次写⼊4k对某个设备来说效率最⾼,那么把buffer定为4k,⼩数据积攒到4k写⼀次,⼤数据分割到每个碎⽚4k多次写⼊,这样就是write buffer的⽤处。最后我们来说write cache。所谓write cache,就是要设法减少写⼊次数。也就是说,如果某些数据需要产⽣多次写⼊,那么使⽤cache就可以只将最终数据写⼊,导致最终写⼊数据减少。在实际应⽤中,我们有时会使⽤到write buffer 跟write cache的合体形态。buffer本⾝需要规整尺⼨,与此同时,buffer还允许多次随机写⼊,使得多次写⼊的数据只⽤写⼊最后⼀次,这属于cache的特性。BT软件使⽤的写缓存往往具有类似特性,因⽽这种形态它同时既是buffer⼜是cache。正因为在写⼊场合buffer跟cache没有那么明显的分界,所以才会有产⽣buffer跟cache究竟有啥区别的疑问。
简单结论:
Buffer不是缓存,国内常⽤的翻译是缓冲区。
其次,⼤部分场景中,Buffer是特指内存中临时存放的IO设备数据——包括读取和写⼊;⽽Cache的⽤处很多——很多IO设备(例如硬盘、RAID卡)上都有Cache,CPU内部也有Cache,浏览器也有Cache。
Buffer并⾮⽤于提⾼性能,⽽Cache的⽬的则是提⾼性能。
涉及到IO设备读写的场景中,Cache的⼀部分本⾝就是Buffer的⼀种。如果说某些场合Buffer可以提升IO设备的读写性能,只不过是因为Buffer本⾝是Cache系统的⼀部分,性能提升来⾃于Cache机制。
Buffer占⽤的内存不能回收,如果被强⾏回收会出现IO错误。Cache占⽤的内存,除实现Buffer的部分外都可以回收,代价则是下⼀次读取需要从数据的原始位置(通常是性能更低的设备)读取。
在IO读写过程中,任何数据的读写都必然会产⽣Buffer,但根据Cache算法,可能会有相当部分数据不会被Cache。
以硬盘读写操作为例的完整解释
背景知识⼀:我们现在的计算机、⼿机都是冯诺依曼架构,CPU只能操作内存中的数据,⽆法直接操作硬盘上的数据。
背景知识⼆:硬盘上的数据,最⼩读写单位是扇区(Sector)。⽼式硬盘上⼀个扇区是512字节,现代硬盘上⼀个扇区是4K字节。计算机不能以单个字节为单位访问硬盘上的数据。现在很常见的固态硬盘,物理上最⼩读写单位是页(Page),但⼤部分固态硬盘通过主控芯⽚模拟传统硬盘的扇区来进⾏读写。现代硬盘常⽤的LBA(Logical Block Addressing,逻辑块寻址)寻址⽅式,是把硬盘上的扇区
分配从0~N-1的编号(N为硬盘上所有可⽤扇区数量)。肯定的英文
介绍完背景,假设某个应⽤现在需要读取⼀个⼤⼩为15K字节的⽂件A。操作系统和⽂件系统会把⽂件路径转换为具体的LBA地址,可能最终转换为读取硬盘上从B扇区开始的4个扇区(按照每个扇区4KB计算)。然⽽,前⾯我们说了,CPU并不能直接访问硬盘,因此需要先把这四个扇区的数据,传输到内存中。存放这四个扇区数据的内存,就是Buffer。忽略CPU内部的Cache机制,CPU现在可以对这⼀段内存以字节为单位进⾏操作,在所有操作完成后,Buffer所占⽤的内存会被回收。
写⼊则是相反,应⽤程序需要先在内存中准备好这四个扇区的数据,然后硬盘控制器会把这些数据原样写⼊到硬盘对应的扇区上。同样的,写⼊完成后Buffer所占⽤的内存也会被回收。
除了⽤于临时存放IO设备上的数据,Buffer通常还有其它⼏种⽤途:
把多次⼩量数据传输合并为更少次数的批量数据传输,减少传输过程本⾝的额外开销;
为两个不能直接交换数据的传输进程的提供临时中介存储;
成单次传输规定的最⼩单位;
对⼤块数据进⾏组装或者分解。
如果这个应⽤需要频繁读取⽂件A,每次都从硬盘读取显然会很慢。如果第⼀次读取完成后,不直接清空Buffer所占⽤的内存,⽽是把这段内存保留下来或者先复制到其它内存地址,以后对这个⽂件的读取就可以直接从内存访问,⽆需再次从硬盘读取,应⽤程序的性能就会快很多。这才是Cache,严谨点来说,这是Read Cache,所以台湾把Cache翻译为“快取”,更多的是指Read Cache。但是,并不是所有从硬盘上读取到Buffer的数据都会被Cache的,例如复制⼀个包含多个数GB的视频⽂件的⽂件夹,通常只有这个⽂件夹的数据会被Cache,⽽每个具体的视频⽂件的数据都不会进⼊Cache。
有Read Cache⾃然也有Write Cache。还是这个占⽤四个扇区的⽂件,假如应⽤程序需要先更改第⼀个扇区的内容并写⼊硬盘,过⼀段时间再更改第三个扇区
的内容并写⼊硬盘。这样需要对硬盘进⾏两次写⼊。但如果第⼀次应⽤要求写⼊的时候,操作系统只是把这个⽂件的数据写⼊到内存中并返回写⼊完成的响应,但数据并没有真正写⼊硬盘。等收到后续写⼊请求的时候才真正写⼊硬盘,则只需要进⾏⼀次写⼊。通过这样的⽅式,根据实际情况可能实现:
应⽤程序⽆需等待真正的写⼊完成即可继续后续操作,提⾼应⽤程序性能;
减少写⼊次数;
把多个⼩数据量的写⼊合并成⼀个⼤数据量的写⼊;
把多个随机写⼊转换为持续写⼊.二八佳人
这⼏种情况中的⼀种或者多种,从⽽提⾼IO性能。但是,对于⾸次写⼊来说,这个性能是必然更低的——假设直接写⼊需要0.02秒,因为要等待后续的写⼊请求,可能从发起⾸次写⼊请求,到数据真正写⼊硬盘⽤了0.5秒。这就是国内把Cache翻译为“缓存”的原因——暂缓存储。所以其实“缓存”和“快取”都只是表达了⼀半的意思,不存在说“快取”⽐“缓存”翻译的更好——虽然⼤部分时候Read Cache⽐Write Cache更常见。
快与慢需要另外提⼀下的是,Write Cache同时也是Buffer的⼀种形式,在数据写⼊到硬盘前,是不能被回收的。
最后,Read Cache和Write Cache并不是严格分离的。很多时候Write Cache同时也可以作为Read Cache使⽤,但在分布式系统中,则需要考虑Cache⼀致性的问题。
在Linux上如何清除内存的Cache、Buffer和Swap
如何在Linux中清除缓存Cache?
每个Linux系统中有三种选项来清除缓存⽽不需要中断任何进程或服务
Cache:缓存,指CPU和内存之间⾼速缓存
Buffer:缓冲区,指在写⼊磁盘前的存储在内存中的内容
仅清除页⾯缓存(PageCache)
sync;echo 1 > /proc/sys/vm/drop_caches
清除⽬录和inode
sync;echo 2 > /proc/sys/vm/drop_caches
清除页⾯缓存,⽬录项和inode
sync;echo 3 > /proc/sys/vm/drop_caches
说明:
sync 将刷新⽂件系统缓冲区(buffer),命令通过“;”分隔,顺序执⾏,shell在执⾏序列中的下⼀个命令之前会等待命令的终⽌。正如内核⽂档中提到的,写⼊到drop_cache将清空缓存⽽不会杀死任何应⽤程序/服务,echo命令做写⼊⽂件的⼯作。
如果你必须清除磁盘⾼速缓存,第⼀个命令在企业和⽣产环境中是最安全,
"...echo 1> ..."
只会清除页⾯缓存。在⽣产环境中不建议使⽤上⾯的第三个选项
"...echo 3 > ..."
,除⾮你明确⾃⼰在做什么,因为它会清除缓存页,⽬录项和inodes。
在Linux上释放也许被内核所使⽤的缓冲区(Buffer)和缓存(Cache)是否是个好主意?
当你设置许多设定想要检查效果时,如果它实际上是专门针对 I/O 范围的基准测试,那么你可能需要清除缓冲区和缓存。你可以如上所⽰删除缓存,⽆需重新启动系统(即⽆需停机)。
Linux被设计成它在寻找磁盘之前到磁盘缓存寻找的⽅式。如果它发现该资源在缓存中,则该请求不会发送到磁盘。如果我们清理缓存,磁盘缓存就起不到作⽤了,系统会到磁盘上寻找资源。
此外,当清除缓存后它也将减慢系统运⾏速度,系统会将每⼀个被请求的资源再次加载到磁盘缓存中。
关于人的好句现在,我们将创建⼀个 shell 脚本,通过⼀个 cron 调度任务在每天下午2点⾃动清除RAM缓存。如下创建⼀个 shell 脚本 clearcache.sh 并在其中添加以下⾏
#!/bin/bash
# 注意,我们这⾥使⽤了 "echo 3",但是不推荐使⽤在产品环境中,应该使⽤ "echo 1"
echo "echo 3 > /proc/sys/vm/drop_caches"
给clearcache.sh⽂件设置执⾏权限
# chmod 755 clearcache.sh
现在,当你需要清除内存缓存时只需要调⽤脚本。
现在设置⼀个每天下午2点的定时任务来清除RAM缓存,打开crontab进⾏编辑。六年级英语手抄报
crontab -e
添加以下⾏,保存并退出。
0 3 * * * /path/to/clearcache.sh
在⽣产环境的服务器上⾃动清除RAM是否是⼀个好主意?
不!它不是。想想⼀个情况,当你已经预定脚本在每天下午2点来清除内存缓存。那么其时该脚本会执⾏并刷新你的内存缓存。在某⼀天由于某些原因,可能您的⽹站的在线⽤户会超过预期地从你的服务器请求资源。
⽽在这时,按计划调度的脚本运⾏了,并清除了缓存中的⼀切。当所有的⽤户都从磁盘读取数据时,这将导致服务器崩溃并损坏数据库。因此,清除缓存仅在必要时并且在你的预料之中,否则你就是个呆⽠系统管理员。
如何清除Linux的交换空间
swapoff -a && swapon -a
此外,了解有关风险后,您可以将上⾯的命令添加到cron中。
现在,我们将上⾯两种命令结合成⼀个命令,写成正确的脚本来同时清除RAM缓存和交换空间。
echo 3 > /proc/sys/vm/drop_caches && swapoff -a && swapon -a && printf '\n%s\n' 'Ram-cache and Swap Cleared'
su -c 'echo 3 > /proc/sys/vm/drop_caches' && swapoff -a && swapon -a && printf '\n%s\n' 'Ram-cache and Swap Cleared'

本文发布于:2023-07-13 12:39:52,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/1079842.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:数据   缓存   硬盘   读取
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图