2013/3/02

CentOSで「too many files」なるエラーが多発したのでその対応策をメモしておく。

下記を参考にした。

1 確認方法

ファイル上限値の確認コマンドは以下。

$ cat /proc/sys/fs/file-nr
1792    0       566699

左から順に

  • 今までにオープンしたことのあるファイルの最大数
  • 現在オープンしているファイルの総数
  • オープン可能なファイル数の上限

となる。

2 一時的な設定方法

2.1 システム全体

現状のファイルディスクリプタの上限値を確認

$ 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

2.2 ユーザ毎(カレントユーザ)

現在のセッション(自分が起動したプロセス)に対して、 ファイルディスクリプタ上限値を設定するには、 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になることは禁止されている環境も多いため、実質この方法は実施できない。

3 恒久的な設定方法

一時的な方法では、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
  1. 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
    
  2. 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)を再起動する。

blog comments powered by Disqus