1. 程式人生 > 實用技巧 >伺服器buffer/cache 的產生原因和釋放buffer/cache

伺服器buffer/cache 的產生原因和釋放buffer/cache

一、什麼是buffer/cache?

buffer/cache 其實是作為伺服器系統的檔案資料快取使用的,尤其是針對程序對檔案存在 read/write 操作的時候,所以當你的服務程序在對檔案進行讀寫的時候,Linux核心為了提高服務的讀寫速度,則將會把檔案放在此處的 buffer/cache 中進行快取使用,由於 Linux服務的特點便是任何事物都會以檔案的形式進行存在,所以你會發現不管你是否對檔案做了大規模的讀寫,機器的 buffer/cache 是一直都存在的,並且持續的增高不下,這是因為伺服器所產生的網路連線也好,使用者協議的(UDP)套接字也好,這部分的資料系統都會為應用程式建立對應的檔案描述符,而這些檔案描述符的使用,則又都會重新進入 buffer/cache 中做讀寫使用,所以這也是你的機器始終都會存在較高 buffer/cache 的原因!(因為所有的檔案讀寫都會用到 buffer/cache,在記憶體合理的情況下)

二、什麼是page cache?

Page cache主要用來作為檔案系統上的檔案資料的快取來用,尤其是針對當程序對檔案有read/write操作的時候。如果你仔細想想的話,作為可以對映檔案到記憶體的系統呼叫:mmap是不是很自然的也應該用到page cache?在當前的系統實現裡,page cache也被作為其它檔案型別的快取裝置來用,所以事實上page cache也負責了大部分的塊裝置檔案的快取工作。

三、buffer/cache 需要注意的一些特點

在服務記憶體夠用的情況下,Linux核心為了加快對檔案的讀寫效率會將檔案放入之 buffer/cache 中 以保證讀寫效率,但其實,儘管當你的應用程式對檔案的讀寫執行結束後,buffer/cache 也不會自動釋放該部分記憶體,而是作為緩衝進行保留,等到你的服務程序在下一次進行相同檔案的讀寫時就可以直接使用,省去了各種重新進行記憶體初始化的操作;所以這將會導致,當你的應用程序頻繁對不同的檔案進行讀寫時,你會發現服務所可以直接使用的free記憶體將會越來越少的一個重要原因;難道 buffer/cache 在這樣無休止的快取當中就不會自動釋放?當然不是,當伺服器在記憶體壓力較大的情況下時,則將會自動進行記憶體的回收,作為free空間分給其它程序使用,這其中主要回收的一個記憶體則是 buffer/cache 的緩衝區記憶體塊;

四、如何進行手動 buffer/cache 回收?

除了在系統程序記憶體使用較大壓力的情況下進行記憶體的回收外,我們也可以進行手動的buffer/cache回收,但由於buffer/cache主要是用於檔案的讀寫使用,所以進行檔案回收時,一般常伴隨系統的IO彪高,因為系統核心也對比cache中的資料與硬碟中的資料是否一致,如果不一致需要寫入,然後才能進行記憶體的回收;

$ sync
# 將記憶體中資料強制先重新整理到磁碟中

清理Buffer快取區域
$ echo 1 > /proc/sys/vm/drop_caches  # 表示清除pagecache。
$ echo 2 > /proc/sys/vm/drop_caches  # 表示清除回收slab分配器中的物件(包括目錄項快取和inode快取)。slab分配器是核心中管理記憶體的一種機制,其中很多快取資料實現都是用的pagecache。
$ echo 3 > /proc/sys/vm/drop_caches  # 表示清除pagecache和slab分配器中的快取物件

五、buffer/cache 過高如何排查是由那幾個程序引起的

5.1 hcache安裝

$ wget https://silenceshell-1255345740.cos.ap-shanghai.myqcloud.com/hcache -O /usr/local/bin/hcache ;\
chmod +x /usr/local/bin/hcache

5.2 hcache常用命令

$ hcache --top 10           # 全域性顯示10個最大的被快取檔案
$ lsof /usr/lib/vmware-tools/lib64/libxerces-c-3.1.so/libxerces-c-3.1.so
# 根據檔案找到對應的程序、pid
$ hcache -pid 1070   # 獲取當前程序號所開啟的所有檔案資訊
$ lsof -p 1070     # 獲取當前程序號所開啟的所有檔案資訊(二選一)

lsof命令使用參考網址:https://man.linuxde.net/lsof