こんにちは 山下(@tomorrowkey) です。
Linuxをセットアップする時にすぐに数を大きくするfile descriptorの数ですが、どのプロセスがどのくらいファイルを開いているか確認する方法を知らなかったので調べました。
早速最終的なコマンドから。例えばunicorn
が開いているファイルの数を調べるならこんな感じ。
for i in $(ps aux | grep "[u]nicorn" | awk '{print $2}'); do ls /proc/$i/fd | wc -l; done
開いているファイルディスクリプタは/proc/$PID/fd
にあるので、数を数えればOKです。
調べたことなど書きます。
dockerでfile descriptorの数を設定する
検証にはdockerを使います。
起動時に--ulimit
というオプションを渡すだけで制限が可能です。
検証用なので極端に小さく設定します。
$ docker run --ulimit="nofile=64" --rm -it ruby:2.4.2-jessie /bin/bash root@ea6e45c79d10:/# ulimit -n 64
irbを起動しただけのfile descriptorの数を調べる
プロセスIDを調べます。
# ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.1 20244 3208 pts/0 Ss 00:35 0:00 /bin/bash root 7 0.1 0.1 20244 3196 pts/1 Ss 00:35 0:00 /bin/bash root 14 1.6 0.4 47672 9632 pts/0 Sl+ 00:35 0:00 irb root 16 0.0 0.1 17500 2072 pts/1 R+ 00:35 0:00 ps aux
file descriptorの数を調べます。
# ls /proc/14/fd | wc -l 9
9個でした。
今度はlsofで数を確認します。 rubyのdockerイメージにはlsofがインストールされていないので、インストールします。
# apt-get update && apt-get install -y lsof
# lsof -p 14 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME irb 14 root cwd DIR 0,46 4096 52302 / irb 14 root rtd DIR 0,46 4096 52302 / irb 14 root txt REG 254,1 146248 3145942 /usr/local/bin/ruby irb 14 root mem REG 254,1 171800 1444564 /lib/x86_64-linux-gnu/libtinfo.so.5.9 irb 14 root mem REG 254,1 151120 1444515 /lib/x86_64-linux-gnu/libncurses.so.5.9 irb 14 root mem REG 254,1 297040 1444546 /lib/x86_64-linux-gnu/libreadline.so.6.3 irb 14 root mem REG 254,1 260648 3146915 /usr/local/lib/ruby/2.4.0/x86_64-linux/readline.so irb 14 root mem REG 254,1 292976 3146919 /usr/local/lib/ruby/2.4.0/x86_64-linux/stringio.so irb 14 root mem REG 254,1 33400 3146874 /usr/local/lib/ruby/2.4.0/x86_64-linux/enc/trans/transdb.so irb 14 root mem REG 254,1 183168 3146831 /usr/local/lib/ruby/2.4.0/x86_64-linux/enc/encdb.so irb 14 root mem REG 254,1 1738176 1444479 /lib/x86_64-linux-gnu/libc-2.19.so irb 14 root mem REG 254,1 1051056 1444509 /lib/x86_64-linux-gnu/libm-2.19.so irb 14 root mem REG 254,1 35176 1444487 /lib/x86_64-linux-gnu/libcrypt-2.19.so irb 14 root mem REG 254,1 14664 1444492 /lib/x86_64-linux-gnu/libdl-2.19.so irb 14 root mem REG 254,1 137384 1444543 /lib/x86_64-linux-gnu/libpthread-2.19.so irb 14 root mem REG 254,1 15803280 3145980 /usr/local/lib/libruby.so.2.4.2 irb 14 root mem REG 254,1 140928 1444461 /lib/x86_64-linux-gnu/ld-2.19.so irb 14 root 0u CHR 136,0 0t0 3 /dev/pts/0 irb 14 root 1u CHR 136,0 0t0 3 /dev/pts/0 irb 14 root 2u CHR 136,0 0t0 3 /dev/pts/0 irb 14 root 3r FIFO 0,10 0t0 54293 pipe irb 14 root 4w FIFO 0,10 0t0 54293 pipe irb 14 root 5r FIFO 0,10 0t0 54294 pipe irb 14 root 6w FIFO 0,10 0t0 54294 pipe irb 14 root 7u CHR 136,0 0t0 3 /dev/pts/0 irb 14 root 8u CHR 136,0 0t0 3 /dev/pts/0
FD
カラムに注目すると…
cwd
-> current working directoryrtd
-> root directorytxt
-> program textmem
-> memory-mapped device\[0-9]+r\
-> read-onlyで開いているファイル\[0-9]+w\
-> write-onlyで開いているファイル\[0-9]+u\
-> read-writeで開いてるファイル
lsofでfile descriptorの数を調べるにはFDが数字から始まるものを数えるとよさそう。 その他の値についてはこちら https://linux.die.net/man/8/lsof
lsofを使えばどのファイルを開いているかまで分かります。
たくさんのファイルを開いてfile descriporの数を調べる
スクリプトでファイルをたくさん開きます。
files = [] (1..(2 ** 10)).each do |i| puts i files << File.open("#{i}", "w") sleep 0.5 end
1 2 3 # ... 54 55 56 Errno::EMFILE: Too many open files @ rb_sysopen - 56 from (irb):4:in `initialize' from (irb):4:in `open' from (irb):4:in `block in irb_binding' from (irb):2:in `each' from (irb):2 from /usr/local/bin/irb:11:in `<main>'
無事ファイルの開き過ぎでエラーを吐きました。 irbをそのままに、違うターミナルでfile descriptorの数を調べます。
# for i in $(ps aux | grep "[i]rb" | awk '{print $2}'); do ls /proc/$i/fd | wc -l; done 64
lsofで確認します。
# lsof -p $(ps aux | grep "[i]rb" | awk '{print $2}' | tr -d " ") COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME irb 14 root cwd DIR 0,46 4096 52302 / irb 14 root rtd DIR 0,46 4096 52302 / irb 14 root txt REG 254,1 146248 3145942 /usr/local/bin/ruby irb 14 root mem REG 254,1 171800 1444564 /lib/x86_64-linux-gnu/libtinfo.so.5.9 irb 14 root mem REG 254,1 151120 1444515 /lib/x86_64-linux-gnu/libncurses.so.5.9 irb 14 root mem REG 254,1 297040 1444546 /lib/x86_64-linux-gnu/libreadline.so.6.3 irb 14 root mem REG 254,1 260648 3146915 /usr/local/lib/ruby/2.4.0/x86_64-linux/readline.so irb 14 root mem REG 254,1 292976 3146919 /usr/local/lib/ruby/2.4.0/x86_64-linux/stringio.so irb 14 root mem REG 254,1 33400 3146874 /usr/local/lib/ruby/2.4.0/x86_64-linux/enc/trans/transdb.so irb 14 root mem REG 254,1 183168 3146831 /usr/local/lib/ruby/2.4.0/x86_64-linux/enc/encdb.so irb 14 root mem REG 254,1 1738176 1444479 /lib/x86_64-linux-gnu/libc-2.19.so irb 14 root mem REG 254,1 1051056 1444509 /lib/x86_64-linux-gnu/libm-2.19.so irb 14 root mem REG 254,1 35176 1444487 /lib/x86_64-linux-gnu/libcrypt-2.19.so irb 14 root mem REG 254,1 14664 1444492 /lib/x86_64-linux-gnu/libdl-2.19.so irb 14 root mem REG 254,1 137384 1444543 /lib/x86_64-linux-gnu/libpthread-2.19.so irb 14 root mem REG 254,1 15803280 3145980 /usr/local/lib/libruby.so.2.4.2 irb 14 root mem REG 254,1 140928 1444461 /lib/x86_64-linux-gnu/ld-2.19.so irb 14 root 0u CHR 136,0 0t0 3 /dev/pts/0 irb 14 root 1u CHR 136,0 0t0 3 /dev/pts/0 irb 14 root 2u CHR 136,0 0t0 3 /dev/pts/0 irb 14 root 3r FIFO 0,10 0t0 54293 pipe irb 14 root 4w FIFO 0,10 0t0 54293 pipe irb 14 root 5r FIFO 0,10 0t0 54294 pipe irb 14 root 6w FIFO 0,10 0t0 54294 pipe irb 14 root 7u CHR 136,0 0t0 3 /dev/pts/0 irb 14 root 8u CHR 136,0 0t0 3 /dev/pts/0 irb 14 root 9w REG 254,1 0 3149355 /1 irb 14 root 10w REG 254,1 0 3149365 /2 irb 14 root 11w REG 254,1 0 3149369 /3 irb 14 root 12w REG 254,1 0 3149372 /4 irb 14 root 13w REG 254,1 0 3149422 /5 irb 14 root 14w REG 254,1 0 3149423 /6 irb 14 root 15w REG 254,1 0 3149425 /7 irb 14 root 16w REG 254,1 0 3149455 /8 irb 14 root 17w REG 254,1 0 3149457 /9 irb 14 root 18w REG 254,1 0 3149458 /10 irb 14 root 19w REG 254,1 0 3149459 /11 irb 14 root 20w REG 254,1 0 3149460 /12 irb 14 root 21w REG 254,1 0 3149461 /13 irb 14 root 22w REG 254,1 0 3149462 /14 irb 14 root 23w REG 254,1 0 3149463 /15 irb 14 root 24w REG 254,1 0 3149464 /16 irb 14 root 25w REG 254,1 0 3149465 /17 irb 14 root 26w REG 254,1 0 3149466 /18 irb 14 root 27w REG 254,1 0 3149467 /19 irb 14 root 28w REG 254,1 0 3149468 /20 irb 14 root 29w REG 254,1 0 3149469 /21 irb 14 root 30w REG 254,1 0 3149470 /22 irb 14 root 31w REG 254,1 0 3149471 /23 irb 14 root 32w REG 254,1 0 3149472 /24 irb 14 root 33w REG 254,1 0 3149473 /25 irb 14 root 34w REG 254,1 0 3149474 /26 irb 14 root 35w REG 254,1 0 3149475 /27 irb 14 root 36w REG 254,1 0 3149476 /28 irb 14 root 37w REG 254,1 0 3149477 /29 irb 14 root 38w REG 254,1 0 3149478 /30 irb 14 root 39w REG 254,1 0 3149479 /31 irb 14 root 40w REG 254,1 0 3149480 /32 irb 14 root 41w REG 254,1 0 3149481 /33 irb 14 root 42w REG 254,1 0 3149482 /34 irb 14 root 43w REG 254,1 0 3149483 /35 irb 14 root 44w REG 254,1 0 3149484 /36 irb 14 root 45w REG 254,1 0 3149485 /37 irb 14 root 46w REG 254,1 0 3149486 /38 irb 14 root 47w REG 254,1 0 3149487 /39 irb 14 root 48w REG 254,1 0 3149488 /40 irb 14 root 49w REG 254,1 0 3149489 /41 irb 14 root 50w REG 254,1 0 3149490 /42 irb 14 root 51w REG 254,1 0 3149491 /43 irb 14 root 52w REG 254,1 0 3149492 /44 irb 14 root 53w REG 254,1 0 3149493 /45 irb 14 root 54w REG 254,1 0 3149494 /46 irb 14 root 55w REG 254,1 0 3149495 /47 irb 14 root 56w REG 254,1 0 3149496 /48 irb 14 root 57w REG 254,1 0 3149497 /49 irb 14 root 58w REG 254,1 0 3149498 /50 irb 14 root 59w REG 254,1 0 3149499 /51 irb 14 root 60w REG 254,1 0 3149500 /52 irb 14 root 61w REG 254,1 0 3149501 /53 irb 14 root 62w REG 254,1 0 3149502 /54 irb 14 root 63w REG 254,1 0 3149503 /55
64個ファイルを開いていることが確認できました。
以上です。