1. 程式人生 > >系統技術非業餘研究 » 老生常談: ulimit問題及其影響

系統技術非業餘研究 » 老生常談: ulimit問題及其影響

ulimit最初設計是用來限制程序對資源的使用情況的,因為早期的系統系統資源包括記憶體,CPU都是非常有限的,系統要保持公平,就要限制大家的使用,以達到一個相對公平的環境。以下是典型的機器預設的限制情況:

$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 204800
max locked memory       (kbytes, -l) 32
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 204800
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

但是很多年過去了,情況發生變化了,硬體在過去的時間裡面發展的非常迅猛,一個擁有幾十個核心的,上百G記憶體的機器差不多也是白菜價格了。但是軟體的限制還是沒怎麼發生變化,導致一系列使用的問題。其中很重要的檔案控制代碼使用限制尤為明顯。

特別是類似web伺服器,資料庫程式等需要大量的檔案控制代碼,一旦開太小,比如預設(1024),在控制代碼使用完畢的時候,系統就頻繁出現emfile錯誤
,這時候系統很容易陷入不可用。但是如果設定太大了,又會有這樣的副作用。很多伺服器程式是事件派遣的,比如說用epoll,程式在啟動的時候通常會根據最大的檔案控制代碼數來預留內部的slot,比如說Erlang一個slot貌似要佔用幾K的資源,如果你設定檔案控制代碼數目太大,就可能無端的浪費了幾百M記憶體。所以要正視這個問題,設定一個合適的值。

通常我們是在shell下用來ulimit -n NNNN來設定新開的程序的檔案控制代碼的限制,但是在一個生產環境下會有如下麻煩:

$ ulimit -n 22222222
-bash: ulimit: open files: cannot modify limit: Operation not permitted
$ sudo ulimit -n 22222222
sudo: ulimit: command not found

JulyClyde([email protected])同學介紹解釋了這個問題:

shell裡不能直接更改,是因為登入的時候pam已經從limits.conf中設定了上限,ulimit命令只能在低於上限的範圍內發揮了。

這時候我們通常需要修改/etc/security/limits.conf

# 確認包含下面的內容:
* soft nofile NNNNN
* hard nofile NNNNN

修改後,重現登入shell, 用ulimit -Hn和ulimit -Sn確認修改已生效.

另外淘寶雕樑說:

在linux kernel 2.6.25之前通過ulimit -n(setrlimit(RLIMIT_NOFILE))設定每個程序的最大開啟檔案控制代碼數不能超過NR_OPEN (1024*1024),也就是100多w(除非重新編譯核心),而在25之後,核心匯出了一個sys介面可以修改這個最大值(/proc/sys/fs /nr_open).具體的changelog在這裡

直接在你自己的程式裡面繞開檔案控制代碼的限制。

祝大家玩得開心!

Post Footer automatically generated by wp-posturl plugin for wordpress.