ファイルオープン数が上限値に達した
CentOSで「too many files」なるエラーが多発したのでその対応策をメモしておく。
下記を参考にした。
- http://thinkit.co.jp/free/tech/23/5
- http://www.matsuaz.com/matsumotojs/2010/12/24/1293117835413.html
確認方法
ファイル上限値の確認コマンドは以下。
$ cat /proc/sys/fs/file-nr
1792 0 566699
左から順に
- 今までにオープンしたことのあるファイルの最大数
- 現在オープンしているファイルの総数
- オープン可能なファイル数の上限
となる。
一時的な設定方法
システム全体
現状のファイルディスクリプタの上限値を確認
$ cat /proc/sys/fs/file-nr
1792 0 566699
一時的にファイルディスクリプタの上限値を変更する。
$ /sbin/sysctl -w fs.file-max = 1234567
設定値の確認
$ cat /proc/sys/fs/file-nr
1216 0 1234567
ユーザ毎(カレントユーザ)
現在のセッション(自分が起動したプロセス)に対して、
ファイルディスクリプタ上限値を設定するには、 ulimit
を使用する。
ulimitはユーザに対していろいろな制限を設定するコマンド。 ulimit -a で全ての設定値を確認できる。
$ 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) 114688
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) 114688
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
ファイルディスクリプタの上限値を設定するには、 ulimit -n N
でファイルディスクリプタ上限をN個に変更できる。
まず現状のファイルディスクリプタの上限値を確認する。
# (open filesが該当)
$ ulimit -n
1024
下記は、Nを2048個にする例。
$ ulimit -n 2048
-bash: ulimit: open files: cannot modify limit: 許可されていない操作です
$ sudo ulimit -n 2048
sudo: ulimit: command not found
残念ながら一般ユーザ実行すると失敗する(sudoでも実行できない)。 rootユーザで実行しなくてはならない。
$ sudo su
# ulimit -n 2048
$ ulimit -n
2048
ただし直接rootになることは禁止されている環境も多いため、実質この方法は実施できない。
恒久的な設定方法
一時的な方法では、OSを再起動すると初期値に戻ってしまう。 これを防ぐためには、設定ファイルに直接記述する。
設定対象のファイルは以下のとおり。
- /etc/sysctl.conf
- システム全体のファイルオープン数
- /etc/security/limits.conf
- アカウント毎のファイルオープン数
設定前にバックアップしておく。
sudo cp /etc/security/limits.conf /etc/security/limits.conf.orig
sudo cp /etc/sysctl.conf /etc/sysctl.conf.orig
sysctl.conf
まず現在値を確認。
$ cat /proc/sys/fs/file-nr
1792 0 566699
sysctl.confを編集。
$ sudo vi /etc/sysctl.conf
fs.file-max = 1232457
# FORMAT
# fs.file-max = N :システム全体のファイルディスクリプタの上限
# kernel.threads-max = N :システム全体のプロセス数の上限
設定ファイルの内容を反映させる。
$ sudo /sbin/sysctl -p
変更を確認。
$ cat /proc/sys/fs/file-nr
1792 0 1234567
ちなみに上限値は下記でも確認できる。
$ /sbin/sysctl fs.file-max
fs.file-max = 593544
limits.conf
注意点として、limits.confに設定した値は、ログインしないdameonプロセスには効かないとのこと。
/etc/init.d/配下から起動する場合は、その起動スクリプト内に ulimit -n <num> を記述する必要がある。
limits.confは設定値は、ログインしたユーザのセッション内で有効になる。
$ sudo vi /etc/security/limits.conf
mikio soft nofile 2048
mikio hard nofile 2048
# FORMAT
# <USER> <soft|hard> <nofile|noproc> <設定数>
# soft:一般ユーザが設定可能な上限値(ulimit -nのことかな?)
# hard:ルートユーザが設定可能な上限値
# nofile: ファイルディスクリプタの上限値
# noproc: プロセス(スレッド)の上限値
すぐに反映させるには、一度ログアウトして、そこから対象プロセス(tomcatやapache)を再起動する。