Node.jsで「EMFILE: too many open files」エラー
コンテンツ
Next.jsのビルド時に、下記エラーが発生しビルド中断が発生
環境:Amazon Linux 2
Node.js version 16.13.0
glob error [Error: EMFILE: too many open files, scandir '/home/ec2-user/xxx'] {
errno: -24,
code: 'EMFILE',
syscall: 'scandir',
path: '/home/ec2-user/xxx'
}
info - Creating an optimized production build .node:internal/process/promises:246
triggerUncaughtException(err, true /* fromPromise */);
^
[Error: EMFILE: too many open files, scandir '/home/ec2-user/xxx'] {
errno: -24,
code: 'EMFILE',
syscall: 'scandir',
path: '/home/ec2-user/xxx'
}
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
ファイルディスクリプタの上限設定が原因
Linux OSに設定されているファイルディスクリプタの設定値が原因の模様
ファイルディスクリプタとは、プログラムからファイルを操作する際、操作対象のファイルを識別・同定するために割り当てられる番号。OSにアクセスを依頼する際にファイルを指定するのに用いられる整数値である。主にUNIX系OSで用いられる仕組みで、Windowsではファイルハンドル(file handle)がほぼこれに相当する仕組みを提供する。
https://e-words.jp/w/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%83%87%E3%82%A3%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%82%BF.html#:~:text=%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%83%87%E3%82%A3%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%82%BF%E3%81%A8%E3%81%AF%E3%80%81%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0,%E3%82%89%E3%82%8C%E3%82%8B%E6%95%B4%E6%95%B0%E5%80%A4%E3%81%A7%E3%81%82%E3%82%8B%E3%80%82
エラー発生現象の確認
下記手順でエラー原因を特定
- 現状のファイルディスクリプタの設定値を確認
- ビルドプロセスのPIDを確認
- ビルドプロセスの読み込みファイルの確認
ファイルディスクリプタの設定値の確認
ファイルディスクリプタの設定値は下記コマンドで確認
$ ulimit -n
1024
Amazon Linux 2 の初期値は 1024です。
ファイルディスクリプタの設定値を変更
ファイルディスクリプタの設定値は下記コマンドで変更
$ ulimit -n 4096
//確認
$ ulimit -n
4096
ビルドを実行しプロセスのIDを確認(PID)
ビルド実行
$npm run build
$yarn build
..etc
ビルドを実行しプロセスのIDは下記コマンドで確認
$ ps aux
または
$ top
topコマンドで node コマンドのプロセス
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
8544 ec2-user 20 0 11.1g 496704 34240 R 87.5 24.4 0:07.81 node
1 root 20 0 123824 2760 2016 S 0.0 0.1 0:02.78 systemd
ビルドプロセスの読み込みファイルの確認
ビルド実行のプロセスが読み込んでいるファイル数の確認
$ lsof -p 8544 | wc -l
434
ここで、ファイル読み込み数が4096を超えた時点で、エラーが発生
$ lsof -p 8544 | wc -l
4122
再度 ファイルディスクリプタの設定値を変更
$ ulimit 65535
ulimit: open files: cannot modify limit: Operation not permitted
ulimit コマンドでは4096以上の設定が不可の模様
/etc/security/limits.conf に直接ファイルディスクリプタ上限値を設定
$sudo su -
#cd /etc/security/limits.conf
下記設定
* soft nofile 65536
* hard nofile 65536
再度ログインすると/etc/security/limits.conf の設定が反映
再度ビルドを実行
$yarn build
読み込みファイルが上限値に達すること無く終了。
参考:
https://stackoverflow.com/questions/11342167/how-to-increase-ulimit-on-amazon-ec2-instance
https://christina04.hatenablog.com/entry/how-to-change-file-descriptor-limit