天天看點

Linux Memory Buffer&Cache

從字面上和語義來看,buffer名為緩沖,cache名為緩存。我們知道各種硬體存在制作工藝上的差别,是以當兩種硬體需要互動的時候,肯定會存在速度上的差異,而且隻有互動雙方都完成才可以各自處理别的其他事務。假如現在有兩個需要互動的裝置A和B,A裝置用來互動的接口速率為1000M/s,B裝置用來互動的接口速率為500M/s,那他們彼此通路的時候都會出現以下兩種情況:(以A來說)

一.A從B取一個1000M的檔案結果需要2s,本來需要1s就可以完成的工作,卻還需要額外等待1s,B裝置把剩餘的500M找出來,這等待B取出剩下500M的空閑時間内(1s)其他的事務還幹不了

二.A給B一個1000M的檔案結果也需要2s,本來需要也就1s就可以完成的工作,卻由于B,1s内隻能拿500M,剩下的500M還得等下一個1sB來取,這等待下1s的時間還做不了其他事務。

那有什麼方法既可以讓A在‘取’或‘給’B的時候既能完成目标任務又不浪費那1s空閑等待時間去處理其他事務呢?我們知道産生這種結果主要是因為B跟不上A的節奏,但即使這樣A也得必須等B處理完本次事務才能幹其他活(單核cpu來說),除非你有三頭六臂。那有小夥伴可能會問了,能不能在A和B之間加一層區域比如說ab,讓ab既能跟上A的頻率也會照顧B的感受,沒錯我們确實可以這樣設計來磨合接口速率上的差異,你可以這樣想象,在區域ab提供了兩個互動接口一個是a接口另一個是b接口,a接口的速率接近A,b接口的速率最少等于B,然後我們把ab的a和A相連,ab的b和B相連,ab就像一座橋把A和B連結起來,并告知A和B通過他都能轉發給對方,檔案可以暫時存儲,最終拓撲大概如下:

Linux Memory Buffer&Cache

  現在我們再來看上述兩種情況:

對于第一種情況A要B:當A從B取一個1000M的檔案,他把需求告訴了ab,接下來ab通過b和B進行檔案傳送,由于B本身的速率,傳送第一次ab并沒有什麼卵用,對A來說不僅浪費了時間還浪費了感情,ab這家夥很快感受到了A的不滿,是以在第二次傳送的時候,ab背着B偷偷緩存了一個一模一樣的檔案,而且隻要從B取東西,ab都會緩存一個拷貝下來放在自己的大學營,如果下次A或者其他C來取B的東西,ab直接就給A或C一個貨真價實的赝品,然後把它通過a接口給了A或C,由于a的速率相對接近A的接口速率,是以A覺得不錯為他省了時間,最終和ab的a成了好基友,說白了此時的ab提供的就是一種緩存能力,即cache,絕對的走私!因為C取的是A執行的結果。是以在這種工作模式下,怎麼取得的東西是最新的也是我們需要考慮的,一般就是清cache。例如cpu讀取記憶體資料,硬碟一般都提供一個記憶體作為緩存來增加系統的讀取性能

對于第二種情況A給B:當A發給B一個1000M的檔案,因為A知道通過ab的a接口就可以轉交給B,而且通過a接口要比通過B接口傳送檔案需要等待的時間更短,是以1000M通過a接口給了ab ,站在A視圖上他認為已經把1000M的檔案給了B,但對于ab并不立即交給B,而是先緩存下來,除非B執行sync指令,即使B馬上要,但由于b的接口速率最少大于B接口速率,是以也不會存在漏洞時間,但最終的結果是A節約了時間就可以幹其他的事務,說白了就是推卸責任,哈哈而ab此時提供的就是一種緩沖的能力,即buffer,它存在的目的适用于當速度快的往速度慢的輸出東西。例如記憶體的資料要寫到磁盤,cpu寄存器裡的資料寫到記憶體。

看了上面這個例子,那我們現在看一下在計算機領域,在處理磁盤IO讀寫的時候,cpu,memory,disk基于這種模型給出的一個執行個體。我們先來一幅圖:(我從别家當來的,我覺得,看N篇文檔 不如瞄此一圖)

Linux Memory Buffer&Cache

page cache:檔案系統層級的緩存,從磁盤裡讀取的内容是存儲到這裡,這樣程式讀取磁盤内容就會非常快,比如使用grep和find等指令查找内容和檔案時,第一次會慢很多,再次執行就快好多倍,幾乎是瞬間。但如上所說,如果對檔案的更新不關心,就沒必要清cache,否則如果要實施同步,必須要把記憶體空間中的cache clean下

buffer cache:磁盤等塊裝置的緩沖,記憶體的這一部分是要寫入到磁盤裡的。這種情況需要注意,位于記憶體buffer中的資料不是即時寫入磁盤,而是系統空閑或者buffer達到一定大小統一寫到磁盤中,是以斷電易失,為了防止資料丢失是以我們最好正常關機或者多執行幾次sync指令,讓位于buffer上的資料立刻寫到磁盤裡。

接下來說一下Linux上怎麼檢視buffer/cache,怎麼flush…cache ?

[[email protected] ~]# 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:記憶體總數

used:已經使用的記憶體數

free:空閑的記憶體數

shared:可用的共享記憶體

buffers:記憶體緩沖數

cached:記憶體緩存數

第二部分:(-/+ buffers/cache)

used:除去被用作buffers和cache記憶體後已用的記憶體

free:用作buffers和cache的記憶體加上Mem部分空閑的記憶體數

第三部分:(Swap)

用一部分磁盤當做記憶體用的“記憶體”

現在我們來做一下資料統計

total=Mem_used+Mem_free

Mem_used=Mem_buffers+Mem_cached+(-/+ buffers/cache)_used

Mem_free=(-/+ buffers/cache)_free-Mem_buffers-Mem_cached

通過以上等式,我們可以知道:

1.buffers和cache也是RAM劃分出來的一部分位址空間

2.buffers和cache的位址空間也可作為空閑記憶體的組成部分,這意味着我們可以通過向核心傳參釋放一部分記憶體給其他程序

3.由于buffers/cache 是一種動态的記憶體位址空間,是以已用空間和空餘空間有絕對使用,絕對空餘空間,算上buffers/cache的相對已用空間和相對空餘空間四個概念。

如何釋放緩存嗎?我們知道Linux的一個重要思想是一切皆檔案,比如各種輸入輸出裝置:鍵盤,滑鼠,網卡,顯示器,列印機,U盤,console口,在linux的國度裡都可為其建立一個檔案作為通路裝置的入口,而核心的各種參數也被映射成了檔案,不過核心參數這種檔案比較特殊,在linux上有兩個僞檔案系統:/proc,/sys。

/proc:核心狀态和統計資訊的輸出接口:同時還提供一個配置接口,/proc/sys/ 一些檔案可接受使用者指定一個新的value來實作對核心某功能或特性的配置:切記不能用文本編輯器去打開,我們可以通過以下三種方式可以去修改:

1).sysctl [options] [var=[value]]
           

var格式 x.x.x… 指令預設的根目錄是 /proc/sys

sysctl -a :檢視所有根目錄下的核心參數(可以送給grep來檢索需要的核心參數)

sysctl var: 檢視指定核心參數的值(如果你很熟悉這個目錄你可以直接指所要改的核心選項)

sysctl -w var=value:設定核心參數var等于value的值

2).cat /proc/sys/Path/var_file

echo “value” > /proc/sys/Path/var_file (通過重定向)

注意!以上兩種方式的設定僅即時生效,核心重新加載就會失效,如果想讓永久生效需要修改其配置檔案

  3) 配置檔案:/etc/sysctl.conf,/etc/sysctl.d/*.conf (*是代表所有)這個可以vim,比如我們通過vim 打開并讓其有資料包轉發功能,我們可以修改以下這個參數

# Controls IP packet forwardin

  net.ipv4.ip_forward = 1

   修改完我們可以通過sysctl -p [/etc/sysctl.conf] 讓其核心重讀配置檔案使其修改的value立即生效。

知道了怎麼修改核心參數,接下來我們清理下buffers/cache

[[email protected] ~]# echo 1 > /proc/sys/vm/drop_caches

[[email protected] ~]# free -m

total used free shared buffers cached

Mem: 727 177 549 0 0 27

-/+ buffers/cache: 150 577

Swap: 2047 0 2047

我們看到指令執行後buffers為0,cached也隻有27M。

總結:

1.buffer和cache都是為了解決互訪的兩種裝置存在速率差異,使磁盤的IO的讀寫性能或cpu更加高效,減少程序間通信等待的時間

2.buffer:緩沖區-用于存儲速度不同步的裝置或優先級不同的裝置之間傳輸資料,通過buffer可以減少程序間通信需要等待的時間,當存儲速度快的裝置與存儲速度慢的裝置進行通信時,存儲快的裝置先把資料緩存到buffer上,等到系統統一把buffer上的資料寫到速度慢的裝置上。常見的有把記憶體的資料往磁盤進行寫操作,這時你可以檢視一下buffers

3.cache:緩存區-用于對讀取速度比較嚴格,卻因為裝置間因為儲存設備存在速度差異,而不能立刻擷取資料,這時cache就會為了加速緩存一部分資料。常見的是CPU和記憶體之間的資料通信,因為CPU的速度遠遠高于主記憶體的速度,CPU從記憶體中讀取資料需等待很長的時間,而Cache儲存着CPU剛用過的資料或循環使用的部分資料,這時Cache中讀取資料會更快,減少了CPU等待的時間,提高了系統的性能。

問題:

  1. buffers和cache是必須的嗎?
  2. 怎麼清除buffers和cache?
  3. 當buffers值一段時間增長很快說明什麼?cache一段時間增長很快說明什麼?

繼續閱讀