2021-05-12 14:32:11
Linux下設定最大檔案開啟數nofile及nr_open、file-max說明
在開發運維的時候我們常常會遇到類似“Socket/File: Can’t open so many files”,“無法開啟更多進程”,或是coredump過大等問題,這些都可以設定資源限制來解決。今天在教某位客戶設定最大檔案數方法時,搜尋網上的方法時發現各家說法並不一致,便寫了這篇文件。
通常對Linux某個使用者設定系統資源,我們都已經知道可以用ulimit命令來檢視和設定。
表 1. ulimit 引數說明
選項 [options] | 含義 | 例子 |
-H | 設定硬資源限制,一旦設定不能增加。 | ulimit – Hs 64;限制硬資源,執行緒棧大小為 64K。 |
-S | 設定軟資源限制,設定後可以增加,但是不能超過硬資源設定。 | ulimit – Sn 32;限制軟資源,32 個檔案描述符。 |
-a | 顯示當前所有的 limit 資訊。 | ulimit – a;顯示當前所有的 limit 資訊。 |
-c | 最大的 core 檔案的大小, 以 blocks 為單位。 | ulimit – c unlimited; 對生成的 core 檔案的大小不進行限制。 |
-d | 進程最大的資料段的大小,以 Kbytes 為單位。 | ulimit -d unlimited;對進程的資料段大小不進行限制。 |
-f | 進程可以建立檔案的最大值,以 blocks 為單位。 | ulimit – f 2048;限制進程可以建立的最大檔案大小為 2048 blocks。 |
-l | 最大可加鎖記憶體大小,以 Kbytes 為單位。 | ulimit – l 32;限制最大可加鎖記憶體大小為 32 Kbytes。 |
-m | 最大記憶體大小,以 Kbytes 為單位。 | ulimit – m unlimited;對最大記憶體不進行限制。 |
-n | 可以開啟最大檔案描述符的數量。 | ulimit – n 128;限制最大可以使用 128 個檔案描述符。 |
-p | 管道緩衝區的大小,以 Kbytes 為單位。 | ulimit – p 512;限制管道緩衝區的大小為 512 Kbytes。 |
-s | 執行緒棧大小,以 Kbytes 為單位。 | ulimit – s 512;限制執行緒棧的大小為 512 Kbytes。 |
-t | 最大的 CPU 占用時間,以秒為單位。 | ulimit – t unlimited;對最大的 CPU 占用時間不進行限制。 |
-u | 使用者最大可用的進程數。 | ulimit – u 64;限制使用者最多可以使用 64 個進程。 |
-v | 進程最大可用的虛擬記憶體,以 Kbytes 為單位。 | ulimit – v 200000;限制最大可用的虛擬記憶體為 200000 Kbytes。 |
當然我們都知道Linux大部分的命令設定都是臨時生效,而且ulimit命令只對當前終端生效,如果需要永久生效的話,我們有兩種方法,一種是將命令寫至profile和bashrc中,在有些網頁中說寫到rc.local,其實是不對的;還有一種就是在limits.conf中新增記錄(需重新啟動生效,並且在/etc/pam.d/中的seesion有使用到limit模組)。接下來討論的就是在limits.conf使用者最大檔案開啟數限制的相關內容。
針對使用者開啟最大檔案數的限制, 在limits.conf對應的nofile,不管是man手冊還是檔案中說明都只是一句話“maximum number of open files",它其實對應是單個進程能開啟的最大檔案數,通常為了省事,我們想取消它的限制,根據man手冊中,“values -1, unlimited or infinity indicating no limit”,-1、unlimited、infinity都是表明不做限制,可是當你實際給nofile設定成這個值,等你重新啟動就會發現無法登入系統了。
由此可見,nofile是有一個上限的,同時用ulimit測試:
#ulimit -n unlimited
bash: ulimit: open files: cannot modify limit: 不允許的操作
寫一個簡單的for迴圈得出:
#for V in `seq 100000 10000000`;do ulimit -n $V;[[ $? != 0 ]]&&break;done
再執行ulimit -n ,可以看到1048576就是nofile的最大值了,但為什麼是這個值?1048576是1024*1024,當然這並沒有什麼卵用。。。再跟蹤一下我們就會發現這個值其實是由核心引數nr_open定義的:
# cat /proc/sys/fs/nr_open
1048576
到此我們就要說起nr_open,與file-max了,網上在說到設定最大檔案數時偶爾有些貼文也說到要修改file-max,字面上看file-max確實像是對應最大檔案數,而在Linux核心文件中它們兩的解釋是:
file-max:
The value in file-max denotes the maximum number of file-
handles that the Linux kernel will allocate. When you get lots
of error messages about running out of file handles, you might
want to increase this limit
執行:grep -r MemTotal /proc/meminfo | awk '{printf("%d",$2/10)}',可以看到與file-max是相近的;
nr_open:
This denotes the maximum number of file-handles a process can
allocate. Default value is 1024*1024 (1048576) which should be
enough for most machines. Actual limit depends on RLIMIT_NOFILE
resource limit.
額,到此筆者有點暈了,file-handles(即檔案控制代碼),然後相比而言在UNIX/LINUX中我們接觸更多是file discriptor(FD,即檔案描述符),通過百度搜尋,似乎file-handle在windows中是一個類似file discrptor的東東,但是我們討論的是linux,再google一下,我們可以精確到c語言中這兩個概念的區別,據他們的討論file-handle應該是一個高層的物件,使用fopen,fread等函數來呼叫,而FD是底層的一個物件,可以通過open,read等函數來呼叫。
到此,我們應該可以下一個大致的結論了,file-max是核心可分配的最大檔案數,nr_open是單個進程可分配的最大檔案數,所以在我們使用ulimit或limits.conf來設定時,如果要超過預設的1048576值時需要先增大nr_open值(sysctl -w fs.nr_open=100000000或者直接寫入sysctl.conf檔案)。當然百萬級別的單進程最大file-handle開啟數應該也夠用了吧。。
由於筆者水平有限,內容難免有錯漏之處,還有file-max的預設值為何會比nr_open值要小也沒有再深入追究,歡迎大家來討論交流。
本文永久更新連結地址:http://www.linuxidc.com/Linux/2015-10/124223.htm
相關文章