最近はあまり記事を書く気がしないので、Raft に関する論文をいくつか書く予定も、いくつかの事情で遅れています。しかし、考えてみると何か書く準備をしておくべきだと思い、今日出会った Linux カーネルパラメータの問題についてのメモを作成しました。
開始#
私は Mac があまり好きではないので、自宅で使用している開発環境は Manjaro です(ここで広告を打ちますが、非常に優れたディストリビューションで、開封即使用と言えます。広告は 5 円です)。そして、コードツールは Jetbrains の製品群と VSCode を組み合わせて使用しています。
今日、Goland を開いたときに、IDE から次のような警告が表示されました。「External file changes sync may be slow: The current inotify (7) watch limit is too low.」
それで、皆さんは分かると思いますが、私はこのような警告を見ると強迫観念に駆られる人間ですので、調べてみました。
簡単に話しましょう#
私たちは普段、ファイルやディレクトリの変更(ファイルの作成、削除など)を監視する必要があります。通常、私たちはポーリング(直接的な方法)を使用して対応します。
しかし、この方法ではパフォーマンスが非常に低下します。では、この問題を解決する手段はあるのでしょうか?
あります! Linux にはこの問題を処理するための対応する API が提供されています。それが今日話す「inotify」です。
公式の説明によると、「inotify」は実際には非常にシンプルです。
inotify API は、ファイルシステムのイベントを監視するためのメカニズムを提供します。inotify は個々のファイルを監視するために使用することも、ディレクトリを監視するために使用することもできます。ディレクトリが監視されている場合、inotify はディレクトリ自体のイベントと、ディレクトリ内のファイルのイベントを返します。
要するに、「inotify」はファイルシステムのイベントを監視するためのものです。個々のファイルやディレクトリを監視するために使用できます。監視されているファイルやディレクトリの変更はすべて監視の範囲内に含まれます。
対応するファイルを監視した後、「inotify」は以下のようなイベントを返します。
-
IN_ACCESS ファイルが読み取り可能になった
-
IN_ATTRIB メタデータが変更された
-
IN_CLOSE_WRITE 書き込み用に開かれたファイルが閉じられた
-
IN_CLOSE_NOWRITE 書き込み用に開かれていないファイルが閉じられた
-
IN_CREATE 監視されているディレクトリ内でファイル / ディレクトリが作成された
-
IN_DELETE 監視されているディレクトリ内でファイル / ディレクトリが削除された
-
IN_DELETE_SELF 監視されているファイル / ディレクトリが削除された
-
IN_MODIFY ファイルが変更された
-
IN_MOVE_SELF 監視されているファイル / ディレクトリが移動された
-
IN_MOVED_FROM ファイル / ディレクトリが監視されているディレクトリから移動された
-
IN_MOVED_TO ファイル / ディレクトリが監視されているディレクトリに移動された
-
IN_OPEN ファイルが開かれた
合計 12 のイベントタイプで、一般的な要件をカバーしています。しかし、「inotify」には欠点もあります。
-
再帰的な監視はサポートされていません。例えば、A ディレクトリを監視している場合、A ディレクトリ内で B ディレクトリが作成されたイベントをキャプチャすることができます。しかし、B ディレクトリ内のイベントを監視することはできません。B ディレクトリも監視キューに追加する必要があります。
-
Python で利用可能な inotify は非常に少ないです。
最初の欠点に対して、一般的な解決策は、再帰的な監視を自分で実装することです。メインディレクトリにファイル / ディレクトリ作成イベントがある場合、対応するファイル / ディレクトリも監視キューに追加します。
しかし、これにより新たな問題が発生します。非常に大きなプロジェクトの場合、この方法で行うと、最終的にメモリの消費量が非常に大きくなります。そのため、「inotify」の設計時には、いくつかのカーネルパラメータで制限を設けました。
一般的な制限は 2 つあります。
-
/proc/sys/fs/inotify/max_queued_events イベントキューの長さを制限し、イベントが積み重なると新しいイベントは破棄されます。
-
/proc/sys/fs/inotify/max_user_watches 各ユーザー ID が作成できるウォッチャーの数を制限し、メモリの爆発を防ぎます。
デフォルトでは、「max_user_watches」の値は異なる Linux ディストリビューションによって異なりますが、ほとんどのディストリビューションでは比較的小さい値です。つまり、制限に達すると新しいウォッチャーを追加することができなくなります。これが IDE が「External file changes sync may be slow: The current inotify (7) watch limit is too low.」と警告する理由です。
この問題を解決するためには、/etc/sysctl.conf を変更することで対応できます。
最後に#
Linux は本当に宝庫です。自分が関わっていないことに出会うことが頻繁にありますので、記録しておくことはやはり大切です。これを一つの水文として記録し、自分自身の参照にも供しています。