実行中のプロセスの max open files の値を変更する
実行中のプロセスの max open files の値を変更する prlimit
というコマンドがあります(max open files 以外も変更できます)。
https://github.com/tkuchiki/docker-prlimit-example で試せる環境を用意して動作検証しました。
以下のコマンドを順に実行すると、unicorn のプロセスが起動している docker container に接続できます。
$ git clone https://github.com/tkuchiki/docker-prlimit-example
$ cd docker-prlimit-example
$ docker build -t prlimit .
$ docker run -d --rm prlimit
$ docker exec -it $(docker ps | grep prlimit | awk '{print $1}') bash
ps を実行してみると、unicorn のプロセスが動いていることを確認できます。
root@b83fe16b540e:/app# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 1.2 1.1 102084 23336 ? Ssl 04:03 0:00 unicorn master -c unicorn_config.rb -E development -d -l0.0.0.0:8080
root 10 0.0 0.9 102084 19436 ? Sl 04:03 0:00 unicorn worker[0] -c unicorn_config.rb -E development -d -l0.0.0.0:8080
root 13 0.0 0.9 102084 19044 ? Sl 04:03 0:00 unicorn worker[1] -c unicorn_config.rb -E development -d -l0.0.0.0:8080
root 16 4.3 0.1 18500 3348 pts/0 Ss 04:04 0:00 bash
root 27 0.0 0.1 34396 2732 pts/0 R+ 04:04 0:00 ps aux
では、実際に prlimit を使って max open files を変更していきます。
まず、現在の値を確認するには以下を実行します。
root@b83fe16b540e:/app# prlimit --pid 1
RESOURCE DESCRIPTION SOFT HARD UNITS
AS address space limit unlimited unlimited bytes
CORE max core file size 0 unlimited bytes
CPU CPU time unlimited unlimited seconds
DATA max data size unlimited unlimited bytes
FSIZE max file size unlimited unlimited bytes
LOCKS max number of file locks held unlimited unlimited locks
MEMLOCK max locked-in-memory address space 83968000 83968000 bytes
MSGQUEUE max bytes in POSIX mqueues 819200 819200 bytes
NICE max nice prio allowed to raise 0 0
NOFILE max number of open files 1048576 1048576 files
NPROC max number of processes unlimited unlimited processes
RSS max resident set size unlimited unlimited bytes
RTPRIO max real-time priority 0 0
RTTIME timeout for real-time tasks unlimited unlimited microsecs
SIGPENDING max number of pending signals 7862 7862 signals
STACK max stack size 8388608 unlimited bytes
NOFILE
の行が max open files です。soft limit / hard limit ともに 1048576 になっています。
(実際のオペレーションで値を下げることはあまりないかもしれませんが) soft limit / hard limit の値を 1024 に変更します。
root@b83fe16b540e:/app# prlimit --pid 1 --nofile=1024:1024
root@b83fe16b540e:/app# prlimit --pid 1
RESOURCE DESCRIPTION SOFT HARD UNITS
AS address space limit unlimited unlimited bytes
CORE max core file size 0 unlimited bytes
CPU CPU time unlimited unlimited seconds
DATA max data size unlimited unlimited bytes
FSIZE max file size unlimited unlimited bytes
LOCKS max number of file locks held unlimited unlimited locks
MEMLOCK max locked-in-memory address space 83968000 83968000 bytes
MSGQUEUE max bytes in POSIX mqueues 819200 819200 bytes
NICE max nice prio allowed to raise 0 0
NOFILE max number of open files 1024 1024 files
NPROC max number of processes unlimited unlimited processes
RSS max resident set size unlimited unlimited bytes
RTPRIO max real-time priority 0 0
RTTIME timeout for real-time tasks unlimited unlimited microsecs
SIGPENDING max number of pending signals 7862 7862 signals
STACK max stack size 8388608 unlimited bytes
1024 に変わっていることが確認できます。
このとき、unicorn のようにプロセスを fork している場合、子プロセスには反映されません(同じプロセスではないので当然ですね)。
以下のようなワンライナーを実行すると prlimit コマンドを生成できます。
root@b83fe16b540e:/app# PID=1; pids(){ echo $1; for p in $(ps --ppid $1 --no-heading | awk '{ print $1 }'); do echo $p; pids $p ; done ; }; pids $PID | uniq | xargs -I{} echo "prlimit --pid {} --nofile=65536:65536"
prlimit --pid 1 --nofile=65536:65536
prlimit --pid 10 --nofile=65536:65536
prlimit --pid 13 --nofile=65536:65536
上記の例では、PID=1
が親プロセスの PID で、PID = 10, 13 が子プロセスです。
PID で指定したプロセスとその子プロセス分の prlimit コマンドを生成しています。
わざわざいきなり xargs で prlimit を実行していないのは、prlimit は失敗したときの影響が大きいので、確認できるようにするためです。
たとえば、間違えて –nofile=1:1 のようにしてしまった場合、ほとんどの場合プロセスが正常に動作しなくなるでしょう。
親プロセスは変更しなく良い場合は以下のワンライナーで OK です。
root@b83fe16b540e:/app# PID=1; pids(){ for p in $(ps --ppid $1 --no-heading | awk '{ print $1 }'); do echo $p; pids $p ; done ; }; pids $PID | xargs -I{} echo "prlimit --pid {} --nofile=65536:65536"
prlimit --pid 10 --nofile=65536:65536
prlimit --pid 13 --nofile=65536:65536