1. 程式人生 > 實用技巧 >Linux下設定最大檔案開啟數nofile及nr_open、file-max(OK)

Linux下設定最大檔案開啟數nofile及nr_open、file-max(OK)

在開發運維的時候我們常常會遇到類似“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其實就是對單一程式的限制,程序級別的

file-max是所有時程最大的檔案數

nr_open是單個程序可分配的最大檔案數

[root@server-mysql fs]# ulimit -n unlimited
-bash: ulimit: open files: cannot modify limit: Operation not permitted
[root@server-mysql fs]# 
[root@server-mysql fs]# ulimit -n 1048576       
[root@server-mysql fs]# ulimit -n 1048577
-bash: ulimit: open files: cannot modify limit: Operation not permitted
[root@server-mysql fs]# cat /proc/sys/fs/nr_open
1048576
[root@server-mysql fs]# echo 1000000 > /proc/sys/fs/nr_open
[root@server-mysql fs]# cat /proc/sys/fs/nr_open
1000000
[root@server-mysql fs]# ulimit -n 999999
[root@server-mysql fs]# ulimit -n 1000000
[root@server-mysql fs]# ulimit -n 1000001
-bash: ulimit: open files: cannot modify limit: Operation not permitted
?
[root@server-mysql fs]# cat file-nr 2496 0 132022 [root@server-mysql fs]# cat file-max 132022
[root@server-mysql fs]# echo 2000000 >file-max
[root@server-mysql fs]# cat file-nr
2496    0       2000000

man 5 proc:
/proc/sys/fs/file-max This file defines a system-wide limit on the number of open files for all processes. (See also setrlimit(2), which can be used by a process to set the per-process limit, RLIMIT_NOFILE, on the number of files it may open.) If you get lots of error messages about running out of file handles, try increasing this value: echo 100000 > /proc/sys/fs/file-max The kernel constant NR_OPEN imposes an upper limit on the value that may be placed in file- max. If you increase /proc/sys/fs/file-max, be sure to increase /proc/sys/fs/inode-max to 3-4 times the new value of /proc/sys/fs/file-max, or you will run out of inodes. /proc/sys/fs/file-nr This (read-only) file gives the number of files presently opened. It contains three num- bers: the number of allocated file handles; the number of free file handles; and the maximum number of file handles. The kernel allocates file handles dynamically, but it doesn’t free them again. If the number of allocated files is close to the maximum, you should consider increasing the maximum. When the number of free file handles is large, you’ve encountered a peak in your usage of file handles and you probably don’t need to increase the maximum.

ulimit中硬限制是實際的限制,而軟限制,是warnning限制,只會做出warning,其實ulimit命令本身就有分軟硬設定,加-H就是硬,加-S就是軟。
預設顯示的是軟限制,如果修改的時候沒有加上的話,就是兩個一起改
配置檔案最前面的一位是domain,設定為星號代表全域性,另外你也可以針對不同的使用者做出不同的限制

ulimit其實就是對單一程式的限制,程序級別的
系統總限制:/proc/sys/fs/file-max 通過 man 5 proc 找到file-max的解釋:
file-max指定了系統範圍內所有程序可以開啟的檔案控制代碼的數量限制---kernel-level
可以通過cat檢視目前的值,echo來立刻修改 echo 10000 > /proc/sys/fs/file-max
另外還有一個,/proc/sys/fs/file-nr 只讀,可以看到整個系統目前使用的檔案控制代碼數量

寫一個簡單的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:

Thevalueinfile-maxdenotesthemaximumnumberoffile-
handlesthattheLinuxkernelwillallocate.Whenyougetlots
oferrormessagesaboutrunningoutoffilehandles,youmight
wanttoincreasethislimit

執行: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-max是核心可分配的最大檔案數,nr_open是單個程序可分配的最大檔案數,所以在我們使用ulimit或limits.conf來設定時,

如果要超過預設的1048576值時需要先增大nr_open值(sysctl -w fs.nr_open=100000000或者直接寫入sysctl.conf檔案)。

當然百萬級別的單程序最大file-handle開啟數應該也夠