はじめに
とあるアプリケーションを利用していて 1 プロセスが同時に開くことが出来るファイルディスクリプタの数がテーマになって色々と調べたのでメモ。
参考
- 絵で見てわかるファイルディスクリプタ・パイプ・リダイレクト
- ファイルディスクリプタ(file descriptor)について調べてみた
- Linuxのファイルディスクリプタ数を変更・確認する方法
- ファイルディスクリプタ数の上限変更とlimits.confの罠
- ulimitが効かない不安を無くす設定
うんちく
Linux におけるファイルディスクプリタとは
- プログラムがアクセスするファイルや標準入出力などをOSが識別するために用いる識別子
制限
- 1 プロセスで開くことが出来るディスクプリタの数は 1024
- OS 全体で開くことが出来る数は
/proc/sys/fs/file-max
を確認する
実例
Apache の場合
Prefork MPM
の場合 1プロセスあたりのファイルディスクプリタオープン数はそこまで増えないので問題にならないWorker MPM
の場合には 1 スレッドで多くのファイルディスクプリタを開くのでファイルディスクリプタの上限が問題になることがある
確認
OS 全体の最大値を確認
cat /proc/sys/fs/file-max
プロセス単位の最大値を確認
cat /proc/${PID}/limits
ちなみに CoreOS
上で起動している Docker
コンテナに関しては以下のような感じ。
調整
ファイルディスクリプタのオープン数の上限を調整する為にいくつかの方法がある。また、PAM
が通ってかつ、pam_limits.so
が有効である場合のみ /etc/security/limits.conf
への設定が有効になる等、色々と気を使わないといけないことがあるみたい。
ulimit コマンドで指定する
ulimit -n ${NUM}
即反映だが、OS を再起動してしまったりすると設定は失われてしまう。
/etc/security/limits.conf に記述する
以下のように適用するユーザー(${user})、SOFT
と HARD
のリミットをそれぞれ設定(設定しない場合には -
を設定) して、値(${NUM})を設定する。
${user} ${soft} ${hard} ${NUM}
また、/etc/security/limits.d/
以下にアプリケーション毎、ユーザー毎に設定しても良いと思われる。
/etc/security/limits.d/hoge.conf
OS 起動時に実行されるアプリケーション等の場合
やり方は一つではないと思われるが、init
スクリプトに直接設定する方法を試した。
--- /tmp/nginx 2013-09-26 09:24:53.633757188 +0000 +++ /etc/init.d/nginx 2013-09-26 09:26:19.129623273 +0000 @@ -44,6 +44,7 @@ # Set the ulimits ulimit $ULIMIT fi + ulimit -n 2048 start-stop-daemon --start --quiet --pidfile /var/run/$NAME.pid \ --exec $DAEMON -- $DAEMON_OPTS || true echo "$NAME."
上記は nginx
の init
スクリプト。幸い ubuntu
の apt-get
でインストールした nginx
は /etc/default/nginx
で ulimit
の設定が出来るので、上記のように記載する必要は無いが、今回はあえて直書きした。
上記の状態で nginx
を起動してファイルディスクリプタのオープン数の上限を確認すると以下のようになっている。
まとめ
- 奥深い