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其實就是對單一程序的限制,進程級別的

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:

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-max是內核可分配的最大文件數,nr_open是單個進程可分配的最大文件數,所以在我們使用ulimit或limits.conf來設置時,

如果要超過默認的1048576值時需要先增大nr_open值(sysctl -w fs.nr_open=100000000或者直接寫入sysctl.conf文件)。

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM