重要なポイント
Linux で「開いているファイルが多すぎます」というエラー メッセージが表示された場合、プロセスが開くことができるファイルの上限 (通常は 1,024) に達しています。コマンド「ulimit -n 2048」を使用すると、一時的に制限を 2,048 ファイルなどに増やすことができます。 systemd 構成ファイルを編集して、制限を永続的に増やします。
Linux コンピュータでは、システム リソースがユーザー間で共有されます。適正な割合を超えて使用しようとすると、上限に達してしまいます。他のユーザーやプロセスがボトルネックになる可能性もあります。
開いているファイルが多すぎるエラーとは何ですか?
Linux コンピュータのカーネルは 、数え切れないほどのジョブの中で、 RAM や CPU サイクル などの有限なシステム リソースを誰がどれだけ使用しているかを常に監視しています。 マルチユーザー システムでは、 ユーザーやプロセスが特定のシステム リソースを適切以上に使用していないことを確認するために、常に注意を払う必要があります。
たとえば、誰かが CPU 時間を大量に消費して、他の人にとってコンピューターが遅いと感じるのは不公平です。 Linux コンピューターを使用するのが自分だけである場合でも、プロセスが使用できるリソースには制限が設定されています。結局のところ、あなたはまだ単なるユーザーです。
RAM、CPU サイクル、ハード ドライブ容量など、一部のシステム リソースはよく知られており、明白です。しかし、さらに多くのリソースが監視されており、各ユーザー (またはユーザーが所有する各プロセス) には上限が設定されています。その 1 つは、プロセスが一度に開くことができる ファイル の数です。
ターミナル ウィンドウで「開いているファイルが多すぎます」というエラー メッセージを見たことがある場合、またはシステム ログで見つかった場合は、上限に達しており、プロセスがこれ以上ファイルを開くことが許可されていないことを意味します。
なぜこれほど多くのファイルが開かれるのでしょうか?
Linux が処理できる開いているファイルの数にはシステム全体の制限があります。後でわかるように、これは非常に大きな数ですが、それでも制限があります。各ユーザー プロセスには、使用できる割り当てがあります。各ユーザーは、割り当てられたシステム全体のうちのわずかなシェアを受け取ります。
実際に割り当てられるのは、ファイル ハンドルの数です。開かれる各ファイルにはハンドルが必要です。かなり寛大な割り当てを行ったとしても、システム全体のファイル ハンドルは、最初の想像よりも早く使い果たされる可能性があります。
Linux は、ほとんどすべてを抽象化して 、あたかもファイルであるかのように見せます 。場合によっては、単なる古いファイルであることもあります。ただし、ディレクトリを開くなどの他のアクションでもファイル ハンドルが使用されます。 Linux は、ブロック特殊ファイルをハードウェア デバイスの一種のドライバーとして使用します。キャラクター特殊ファイルは非常によく似ていますが、 パイプ やシリアル ポートなど、スループットの概念を持つデバイスで使用されることが多くなります。
ブロック スペシャル ファイルは一度にデータ ブロックを処理し、キャラクタ スペシャル ファイルは各文字を個別に処理します。これらの特殊ファイルは両方とも、ファイル ハンドルを使用することによってのみアクセスできます。プログラムで使用されるライブラリはファイル ハンドルを使用し、ストリームはファイル ハンドルを使用し、ネットワーク接続はファイル ハンドルを使用します。
これらのさまざまな要件をすべて抽象化してファイルとして表示すると、それらの要件とのインターフェイスが簡素化され、パイプやストリームなどの機能が可能になります。
Linux は舞台裏で、ユーザー プロセスを 気にせずに、Linux 自体を実行するためだけにファイルを開いてファイル ハンドルを使用していることがわかります。開いているファイルの数は、単に開いたファイルの数ではありません。オペレーティング システムのほとんどすべてがファイル ハンドルを使用しています。
ファイル ハンドルの制限を確認する方法
システム全体のファイル ハンドルの最大数は、このコマンドで確認できます。
cat /proc/sys/fs/file-max
これにより、9.2 京という途方もない大きな数値が返されます。これは理論上のシステム最大値です。これは 、64 ビット 符号付き整数で保持できる最大値です。あなたの貧弱なコンピュータが実際に一度にこれほど多くのファイルを開くことができるかどうかは、まったく別の問題です。
ユーザー レベルでは、開くことができるファイルの最大数に明示的な値はありません。しかし、大まかに理解することはできます。プロセスの 1 つが開くことができるファイルの最大数を確認するには、
ulimit
コマンドに
-n
(ファイルを開く) オプションを付けて使用します。
ulimit -n
ユーザーが持つことができるプロセスの最大数を調べるには、
-u
(ユーザー プロセス) オプションを指定して
ulimit
を使用します。
ulimit -u
1024 と 7640 を乗算すると、7,823,360 になります。もちろん、これらのプロセスの多くは、デスクトップ環境やその他のバックグラウンド プロセスによってすでに使用されています。つまり、これも理論上の最大値であり、現実的には決して達成できない値です。
重要な数値は、プロセスが開くことができるファイルの数です。デフォルトでは、これは 1024 です。同じファイルを 1024 回同時に開くことは、1024 個の異なるファイルを同時に開くのと同じであることに注意してください。ファイル ハンドルをすべて使い果たしたら、作業は完了です。
プロセスが開くことができるファイルの数を調整することができます。この数値を調整する際には、実際には 2 つの値を考慮する必要があります。 1 つは現在設定されている値、または設定しようとしている値です。これをソフトリミットと呼びます。ハード制限もあり、これがソフト制限を引き上げることができる最高値です。
これについて考える方法は、ソフト リミットは実際には「現在値」であり、上限は現在値が到達できる最高値であるということです。 root 以外の通常のユーザーは、ソフト制限をハード制限までの任意の値に上げることができます。 root ユーザーはハード制限を増やすことができます。
現在のソフト制限とハード制限を確認するには、
-S
(ソフト) オプションと
-H
(ハード) オプション、および
-n
(オープン ファイル) オプションを指定して
ulimit
を使用します。
ulimit -Sn
ulimit -Hn
ソフトリミットが強制されている状況を作り出すために、失敗するまで繰り返しファイルを開く
プログラムを作成しました
。次に、キーストロークを待ってから、使用していたすべてのファイル ハンドルを放棄します。このプログラムは
open-files
と呼ばれます。
./open-ファイル
1021 個のファイルを開いて、1022 個のファイルを開こうとすると失敗します。
1024 から 1021 を引いた値は 3 です。他の 3 つのファイル ハンドルはどうなったのでしょうか?これらは
STDIN
、
STDOUT
、および
STDERR
ストリーム
に使用されました。これらはプロセスごとに自動的に作成されます。これらのファイル記述子の値は常に 0、1、2 です。
これらは、
lsof
コマンド
に
-p
(プロセス) オプションと
open-files
プログラムの
プロセス ID を
指定して実行すると確認できます。便利なことに、プロセス ID がターミナル ウィンドウに出力されます。
lsof -p 11038
もちろん、現実の状況では、どのプロセスがすべてのファイル ハンドルを飲み込んだのかはわからないかもしれません。調査を開始するには、この一連のパイプされたコマンドを使用します。あなたのコンピュータ上でファイル ハンドルを最も多用している 15 人のユーザーがわかります。
lsof | awk '{ print $1 " " $2; }' |ソート -rn |ユニーク -c |ソート -rn |頭 -15
表示するエントリの数を増減するには、
head
コマンドの
-15
パラメータを調整します。プロセスを特定したら、プロセスが不正になって制御不能になったために大量のファイルを開いているのか、それともそれらのファイルが本当に必要なのかを判断する必要があります。これらが必要な場合は、ファイル ハンドルの制限を増やす必要があります。
ソフトリミットを増やす方法
ソフト制限を増やしてプログラムを再度実行すると、より多くのファイルが開かれることが確認できるはずです。
ulimit
コマンドと
-n
(ファイルを開く) オプションを数値 2048 で使用します。これが新しいソフト制限になります。
ulimit -n 2048
今回は2045個のファイルを開くことに成功しました。予想通り、
STDIN
、
STDOUT
、および
STDERR
にファイル ハンドルが使用されているため、これは 2048 より 3 少ない値です。
ファイル制限を永続的に変更する方法
ソフト制限を増やすと、現在のシェルにのみ影響します。 新しいターミナル ウィンドウを開いて 、ソフト リミットを確認します。これが古いデフォルト値であることがわかります。ただし、プロセスが保持できるオープン ファイルの最大数に対して、永続的で 再起動 後も存続する新しいデフォルト値をグローバルに設定する方法があります。
古いアドバイスでは、「/etc/sysctl.conf」や「/etc/security/limits.conf」などのファイルを編集することが推奨されることがよくあります。ただし、 systemd ベースのディストリビューションでは、特にグラフィカル ログイン セッションの場合、これらの編集は一貫して機能しません。
ここで示す手法は、systemd ベースのディストリビューションでこれを行う方法です。作業する必要があるファイルが 2 つあります。 1 つ目は「/etc/systemd/system.conf」ファイルです。
sudo
を使用する必要があります。
sudo gedit /etc/systemd/system.conf
文字列「DefaultLimitNOFILE」を含む行を検索します。行の先頭からハッシュ「#」を削除し、最初の数値をプロセスの新しいソフト制限に設定する値に編集します。私たちは 4096 を選択しました。その行の 2 番目の数値はハードリミットです。私たちはこれを調整しませんでした。
ファイルを保存してエディタを閉じます。
「/etc/systemd/user.conf」ファイルに対してその操作を繰り返す必要があります。
sudo gedit /etc/systemd/user.conf
文字列「DefaultLimitNOFILE」を含む行にも同様の調整を加えます。
ファイルを保存してエディタを閉じます。コンピューターを再起動するか、
systemctl
コマンドを
daemon-reexec
オプションとともに使用して、
systemd
が再実行され、新しい設定が取り込まれるようにする必要があります。
sudo systemctl デーモン-reexec
ターミナル ウィンドウを開いて新しい制限を確認すると、設定した新しい値が表示されるはずです。私たちの場合、それは 4096 でした。
ulimit -n
ファイル貪欲プログラムを再実行することで、これが実際の運用上の値であることをテストできます。
./open-ファイル
プログラムはファイル番号 4094 を開けませんでした。これは、4093 個のファイルが開かれたことを意味します。これは期待値であり、4096 より 3 少ない値です。
すべてはファイルであることを忘れないでください
Linux がファイル ハンドルに大きく依存しているのはこのためです。これで、割り当てが不足し始めた場合に、割り当てを増やす方法がわかりました。





