buffer和cache怎么让你们解释的那么难理解?
對(duì)于一個(gè)即將踏上“系統(tǒng)運(yùn)維”或者更加高大尚的工作“系統(tǒng)調(diào)優(yōu)”,如果這不跟這兩哥們搞好關(guān)系了,坑的不只有內(nèi)存,更坑的是你拿著調(diào)優(yōu)的錢卻干著隨時(shí)被調(diào)的活。因?yàn)樽鳛橐粋€(gè)系統(tǒng)運(yùn)維人員來(lái)說(shuō)監(jiān)控和優(yōu)化IO性能這是最有可能你生存下來(lái)的技能,為啥呢?因?yàn)槟悴粌H給老板省了錢,還提高了機(jī)器的工作效率。。雖然錢都進(jìn)了老板兜里,但你漸漸地植入了他深深地腦海里,總有一天你比錢重要!好了閑話少扯,接下來(lái)說(shuō)說(shuō)這兩個(gè)哥們到底是什么?
之前我自己也對(duì)到底buffer和cache是什么,有什么不同,什么時(shí)候用buffer,什么時(shí)候用cache存在疑惑,不能說(shuō)不知道,只是別人問(wèn)起來(lái)說(shuō)起來(lái),我知道,但是講講他們的區(qū)別,還真是說(shuō)不出來(lái)。無(wú)奈查了好多資料,要么太底層要么含糊不清,學(xué)術(shù)再權(quán)威再有見(jiàn)地,讓讀者理解不了也白搭,這就跟一個(gè)牛逼的程序,你再怎么運(yùn)行在內(nèi)核空間,但如果你不提供一個(gè)用戶空間的接口,用的人不能通過(guò)一種調(diào)用接口認(rèn)識(shí)你,那說(shuō)明你確實(shí)牛,牛到使用的人不知道你是什么。服務(wù)的最終是面向用戶的,你天天說(shuō)些機(jī)器語(yǔ)言,你真的快樂(lè)嗎?所以我談?wù)勎易约簩?duì)buffer和cache的理解 ,希望能幫到一部分人,當(dāng)然有不恰當(dāng)?shù)牡胤竭€請(qǐng)各位老師給予指出。你的指出就是對(duì)我最好的評(píng)價(jià),謝謝!
從字面上和語(yǔ)義來(lái)看,buffer名為緩沖,cache名為緩存。我們知道各種硬件存在制作工藝上的差別,所以當(dāng)兩種硬件需要交互的時(shí)候,肯定會(huì)存在速度上的差異,而且只有交互雙方都完成才可以各自處理別的其他事務(wù)。假如現(xiàn)在有兩個(gè)需要交互的設(shè)備A和B,A設(shè)備用來(lái)交互的接口速率為1000M/s,B設(shè)備用來(lái)交互的接口速率為500M/s,那他們彼此訪問(wèn)的時(shí)候都會(huì)出現(xiàn)以下兩種情況:(以A來(lái)說(shuō))
一.A從B取一個(gè)1000M的文件結(jié)果需要2s,本來(lái)需要1s就可以完成的工作,卻還需要額外等待1s,B設(shè)備把剩余的500M找出來(lái),這等待B取出剩下500M的空閑時(shí)間內(nèi)(1s)其他的事務(wù)還干不了
二.A給B一個(gè)1000M的文件結(jié)果也需要2s,本來(lái)需要也就1s就可以完成的工作,卻由于B,1s內(nèi)只能拿500M,剩下的500M還得等下一個(gè)1sB來(lái)取,這等待下1s的時(shí)間還做不了其他事務(wù)。
那有什么方法既可以讓A在‘取’或‘給’B的時(shí)候既能完成目標(biāo)任務(wù)又不浪費(fèi)那1s空閑等待時(shí)間去處理其他事務(wù)呢?我們知道產(chǎn)生這種結(jié)果主要是因?yàn)锽跟不上A的節(jié)奏,但即使這樣A也得必須等B處理完本次事務(wù)才能干其他活(單核cpu來(lái)說(shuō)),除非你有三頭六臂。那有小伙伴可能會(huì)問(wèn)了,能不能在A和B之間加一層區(qū)域比如說(shuō)ab,讓ab既能跟上A的頻率也會(huì)照顧B的感受,沒(méi)錯(cuò)我們確實(shí)可以這樣設(shè)計(jì)來(lái)磨合接口速率上的差異,你可以這樣想象,在區(qū)域ab提供了兩個(gè)交互接口一個(gè)是a接口另一個(gè)是b接口,a接口的速率接近A,b接口的速率最少等于B,然后我們把a(bǔ)b的a和A相連,ab的b和B相連,ab就像一座橋把A和B鏈接起來(lái),并告知A和B通過(guò)他都能轉(zhuǎn)發(fā)給對(duì)方,文件可以暫時(shí)存儲(chǔ),最終拓?fù)浯蟾湃缦?#xff1a;
現(xiàn)在我們?cè)賮?lái)看上述兩種情況:
對(duì)于第一種情況A要B:當(dāng)A從B取一個(gè)1000M的文件,他把需求告訴了ab,接下來(lái)ab通過(guò)b和B進(jìn)行文件傳送,由于B本身的速率,傳送第一次ab并沒(méi)有什么卵用,對(duì)A來(lái)說(shuō)不僅浪費(fèi)了時(shí)間還浪費(fèi)了感情,ab這家伙很快感受到了A的不滿,所以在第二次傳送的時(shí)候,ab背著B(niǎo)偷偷緩存了一個(gè)一模一樣的文件,而且只要從B取東西,ab都會(huì)緩存一個(gè)拷貝下來(lái)放在自己的大本營(yíng),如果下次A或者其他C來(lái)取B的東西,ab直接就給A或C一個(gè)貨真價(jià)實(shí)的贗品,然后把它通過(guò)a接口給了A或C,由于a的速率相對(duì)接近A的接口速率,所以A覺(jué)得不錯(cuò)為他省了時(shí)間,最終和ab的a成了好基友,說(shuō)白了此時(shí)的ab提供的就是一種緩存能力,即cache,絕對(duì)的走私!因?yàn)镃取的是A執(zhí)行的結(jié)果。所以在這種工作模式下,怎么取得的東西是最新的也是我們需要考慮的,一般就是清cache。例如cpu讀取內(nèi)存數(shù)據(jù),硬盤一般都提供一個(gè)內(nèi)存作為緩存來(lái)增加系統(tǒng)的讀取性能
對(duì)于第二種情況A給B:當(dāng)A發(fā)給B一個(gè)1000M的文件,因?yàn)锳知道通過(guò)ab的a接口就可以轉(zhuǎn)交給B,而且通過(guò)a接口要比通過(guò)B接口傳送文件需要等待的時(shí)間更短,所以1000M通過(guò)a接口給了ab ,站在A視圖上他認(rèn)為已經(jīng)把1000M的文件給了B,但對(duì)于ab并不立即交給B,而是先緩存下來(lái),除非B執(zhí)行sync命令,即使B馬上要,但由于b的接口速率最少大于B接口速率,所以也不會(huì)存在漏洞時(shí)間,但最終的結(jié)果是A節(jié)約了時(shí)間就可以干其他的事務(wù),說(shuō)白了就是推卸責(zé)任,哈哈而ab此時(shí)提供的就是一種緩沖的能力,即buffer,它存在的目的適用于當(dāng)速度快的往速度慢的輸出東西。例如內(nèi)存的數(shù)據(jù)要寫(xiě)到磁盤,cpu寄存器里的數(shù)據(jù)寫(xiě)到內(nèi)存。
看了上面這個(gè)例子,那我們現(xiàn)在看一下在計(jì)算機(jī)領(lǐng)域,在處理磁盤IO讀寫(xiě)的時(shí)候,cpu,memory,disk基于這種模型給出的一個(gè)實(shí)例。我們先來(lái)一幅圖:(我從別家當(dāng)來(lái)的,我覺(jué)得,看N篇文檔 不如瞄此一圖)
page cache:文件系統(tǒng)層級(jí)的緩存,從磁盤里讀取的內(nèi)容是存儲(chǔ)到這里,這樣程序讀取磁盤內(nèi)容就會(huì)非常快,比如使用grep和find等命令查找內(nèi)容和文件時(shí),第一次會(huì)慢很多,再次執(zhí)行就快好多倍,幾乎是瞬間。但如上所說(shuō),如果對(duì)文件的更新不關(guān)心,就沒(méi)必要清cache,否則如果要實(shí)施同步,必須要把內(nèi)存空間中的cache clean下
buffer cache:磁盤等塊設(shè)備的緩沖,內(nèi)存的這一部分是要寫(xiě)入到磁盤里的。這種情況需要注意,位于內(nèi)存buffer中的數(shù)據(jù)不是即時(shí)寫(xiě)入磁盤,而是系統(tǒng)空閑或者buffer達(dá)到一定大小統(tǒng)一寫(xiě)到磁盤中,所以斷電易失,為了防止數(shù)據(jù)丟失所以我們最好正常關(guān)機(jī)或者多執(zhí)行幾次sync命令,讓位于buffer上的數(shù)據(jù)立刻寫(xiě)到磁盤里。
接下來(lái)說(shuō)一下Linux上怎么查看buffer/cache,怎么flush...cache ?
?[root@localhost ~]# free -m
? ? ? ? ? ? ? ? ??total ? used ? free ?shared ?buffers ?cached
Mem:? ?727 ? ?359 ? ? 367 ? ? 0 ? ? ? ? ?36 ? ? ? 171
-/+ buffers/cache: ? ? 152 ? ? 575?
Swap: ? ? ? ? ?2047 ? ? 0 ? ? ?2047
第一部分Mem行:
total:內(nèi)存總數(shù)
used:已經(jīng)使用的內(nèi)存數(shù)
free:空閑的內(nèi)存數(shù)
shared:可用的共享內(nèi)存
buffers:內(nèi)存緩沖數(shù)
cached:內(nèi)存緩存數(shù)
第二部分:(-/+ buffers/cache)
used:除去被用作buffers和cache內(nèi)存后已用的內(nèi)存
free:用作buffers和cache的內(nèi)存加上Mem部分空閑的內(nèi)存數(shù)
第三部分:(Swap)
用一部分磁盤當(dāng)做內(nèi)存用的“內(nèi)存”
現(xiàn)在我們來(lái)做一下數(shù)據(jù)統(tǒng)計(jì)
total=Mem_used+Mem_free
Mem_used=Mem_buffers+Mem_cached+(-/+ buffers/cache)_used
Mem_free=(-/+ buffers/cache)_free-Mem_buffers-Mem_cached
通過(guò)以上等式,我們可以知道:
1.buffers和cache也是RAM劃分出來(lái)的一部分地址空間
2.buffers和cache的地址空間也可作為空閑內(nèi)存的組成部分,這意味著我們可以通過(guò)向內(nèi)核傳參釋放一部分內(nèi)存給其他進(jìn)程
3.由于buffers/cache 是一種動(dòng)態(tài)的內(nèi)存地址空間,所以已用空間和空余空間有絕對(duì)使用,絕對(duì)空余空間,算上buffers/cache的相對(duì)已用空間和相對(duì)空余空間四個(gè)概念。
如何釋放緩存嗎?我們知道Linux的一個(gè)重要思想是一切皆文件,比如各種輸入輸出設(shè)備:鍵盤,鼠標(biāo),網(wǎng)卡,顯示器,打印機(jī),U盤,console口,在linux的國(guó)度里都可為其創(chuàng)建一個(gè)文件作為訪問(wèn)設(shè)備的入口,而內(nèi)核的各種參數(shù)也被映射成了文件,不過(guò)內(nèi)核參數(shù)這種文件比較特殊,在linux上有兩個(gè)偽文件系統(tǒng):/proc,/sys。
/proc:內(nèi)核狀態(tài)和統(tǒng)計(jì)信息的輸出接口:同時(shí)還提供一個(gè)配置接口,/proc/sys/ 一些文件可接受用戶指定一個(gè)新的value來(lái)實(shí)現(xiàn)對(duì)內(nèi)核某功能或特性的配置:切記不能用文本編輯器去打開(kāi),我們可以通過(guò)以下三種方式可以去修改:
? ? ? 1).sysctl [options] [var=[value]]
var格式 x.x.x... 命令默認(rèn)的根目錄是 /proc/sys
sysctl -a :查看所有根目錄下的內(nèi)核參數(shù)(可以送給grep來(lái)檢索需要的內(nèi)核參數(shù))
sysctl ?var: 查看指定內(nèi)核參數(shù)的值(如果你很熟悉這個(gè)目錄你可以直接指所要改的內(nèi)核選項(xiàng))
sysctl -w var=value:設(shè)定內(nèi)核參數(shù)var等于value的值
2).cat /proc/sys/Path/var_file
echo "value" > /proc/sys/Path/var_file ?(通過(guò)重定向)
注意!以上兩種方式的設(shè)定僅即時(shí)生效,內(nèi)核重新加載就會(huì)失效,如果想讓永久生效需要修改其配置文件
3) 配置文件:/etc/sysctl.conf,/etc/sysctl.d/*.conf (*是代表所有)這個(gè)可以vim,比如我們通過(guò)vim 打開(kāi)并讓其有數(shù)據(jù)包轉(zhuǎn)發(fā)功能,我們可以修改以下這個(gè)參數(shù)
?
# Controls IP packet forwardin
? ? ? ? ? ? net.ipv4.ip_forward = 1
修改完我們可以通過(guò)sysctl -p [/etc/sysctl.conf] 讓其內(nèi)核重讀配置文件使其修改的value立即生效。
?
知道了怎么修改內(nèi)核參數(shù),接下來(lái)我們清理下buffers/cache
[root@localhost ~]# echo 1 > /proc/sys/vm/drop_caches?
[root@localhost ~]# free -m
? ? ? ? ? ? ? ? ??total ? used ? free ? shared ? buffers ? ? cached
Mem: ? ? ? ? ?727 ? ?177 ? ? 549 ? ? ?0 ? ? ? ? 0 ? ? ? ? ? ? 27
-/+ buffers/cache: 150 ? ? 577?
Swap: ? ? ? ?2047 ? ?0 ? ? 2047
?
我們看到命令執(zhí)行后buffers為0,cached也只有27M。
總結(jié):
? ? 1.buffer和cache都是為了解決互訪的兩種設(shè)備存在速率差異,使磁盤的IO的讀寫(xiě)性能或cpu更加高效,減少進(jìn)程間通信等待的時(shí)間
? ? 2.buffer:緩沖區(qū)-用于存儲(chǔ)速度不同步的設(shè)備或優(yōu)先級(jí)不同的設(shè)備之間傳輸數(shù)據(jù),通過(guò)buffer可以減少進(jìn)程間通信需要等待的時(shí)間,當(dāng)存儲(chǔ)速度快的設(shè)備與存儲(chǔ)速度慢的設(shè)備進(jìn)行通信時(shí),存儲(chǔ)快的設(shè)備先把數(shù)據(jù)緩存到buffer上,等到系統(tǒng)統(tǒng)一把buffer上的數(shù)據(jù)寫(xiě)到速度慢的設(shè)備上。常見(jiàn)的有把內(nèi)存的數(shù)據(jù)往磁盤進(jìn)行寫(xiě)操作,這時(shí)你可以查看一下buffers
? ? 3.cache:緩存區(qū)-用于對(duì)讀取速度比較嚴(yán)格,卻因?yàn)樵O(shè)備間因?yàn)榇鎯?chǔ)設(shè)備存在速度差異,而不能立刻獲取數(shù)據(jù),這時(shí)cache就會(huì)為了加速緩存一部分?jǐn)?shù)據(jù)。常見(jiàn)的是CPU和內(nèi)存之間的數(shù)據(jù)通信,因?yàn)镃PU的速度遠(yuǎn)遠(yuǎn)高于主內(nèi)存的速度,CPU從內(nèi)存中讀取數(shù)據(jù)需等待很長(zhǎng)的時(shí)間,而Cache保存著CPU剛用過(guò)的數(shù)據(jù)或循環(huán)使用的部分?jǐn)?shù)據(jù),這時(shí)Cache中讀取數(shù)據(jù)會(huì)更快,減少了CPU等待的時(shí)間,提高了系統(tǒng)的性能。
問(wèn)題:
? ? ?1.buffers和cache是必須的嗎?
?2. 怎么清除buffers和cache?
?3. 當(dāng)buffers值一段時(shí)間增長(zhǎng)很快說(shuō)明什么?cache一段時(shí)間增長(zhǎng)很快說(shuō)明什么?
?
總結(jié)
以上是生活随笔為你收集整理的buffer和cache怎么让你们解释的那么难理解?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 为什么要学习C++,它到底能做什么?
- 下一篇: centos7.4 U盘安装卡在 sta