web-dev-qa-db-ja.com

数十万の0バイトロックファイルに対してtmpfs` / run / lock`を設定し、iノード制限を処理します

同時実行制御のために数十万の0バイトロックファイルを作成する必要がある状況があります。

私は以下を使用してそれらを作成することをテストしました:

for i in `seq 1 50000`; do touch "/run/lock/${i}.lock"; done

ファイルは0バイトであるため、パーティション内のスペースを増やすことはありません。 df -hを見てください:

Filesystem      Size  Used Avail Use% Mounted on
tmpfs            50M  344K   49M   1% /run
none            5.0M     0  5.0M   0% /run/lock
none            246M     0  246M   0% /run/shm
none            100M     0  100M   0% /run/user

0%の数字は、/run/lock行ではまったく変化しません。

ただし、メモリサイズは、ロックファイルあたり平均約1KB増加します。これは、free -h内に70,000個のロックファイルを作成する前後の/run/lockを比較することで発見しました。このメモリの増加は、実際のメモリ使用量(仮想メモリからバッファ/キャッシュを差し引いたもの)に反映されました。

後で私は、この1KBの増加はiノードが原因である可能性が最も高いことを発見しました。そこで、df -iを使用してiノードの使用状況を確認しました。

Filesystem      Inodes  IUsed   IFree IUse% Mounted on
tmpfs            62729    322   62407    1% /run
none             62729  50001   12728   80% /run/lock
none             62729      1   62728    1% /run/shm
none             62729      2   62727    1% /run/user

ご覧のとおり、ロックファイルは/run/lockパーティション内のiノードを増やします。

私は現在Ubuntuを使用していますが、/runマウントは/etc/fstab内に反映されていません。 mountを実行すると、次のようになります。

tmpfs on /run type tmpfs (rw,noexec,nosuid,size=10%,mode=0755)
none on /run/lock type tmpfs (rw,noexec,nosuid,nodev,size=5242880)
none on /run/shm type tmpfs (rw,nosuid,nodev)
none on /run/user type tmpfs (rw,noexec,nosuid,nodev,size=104857600,mode=0755)

これに関していくつか質問があります(ただし、最初の質問が最も重要です)。

  1. /run/lockのiノード制限を永続的に増やすにはどうすればよいですか?この制限が再起動後も存続するように?
  2. /run/lockを使用する代わりに、独自のディレクトリを作成し、それにtmpfsをマウントして、これに使用する方がよいでしょうか。
  3. 各パーティションのサイズ制限は互いに完全に独立していますか?つまり、ファイルを/runに保存しても、/run/lockには影響しないようです。その逆も同様です。
  4. 1KBはiノードから派生していますか?空でないファイルを作成する場合、基本ブロックはファイルごとに4KBであることに気付きました。
  5. /runのファイルシステムタイプがtmpfsであるのに、/run/lock/run/shm/run/userのファイルシステムタイプが「none」であるのはなぜですか。 TMPFSに支えられていますか? tmpfs列ですべてがFilesystemとして読み取られないのはなぜですか?
  6. すべてのディレクトリが独立して制約されている場合、複数の完全なTMPFSパーティションがあり、それぞれのサイズがRAMの50%であり、RAMも同様です。明らかにRAMを100%以上使用することはできません。 https://www.kernel.org/doc/Documentation/filesystems/tmpfs.txt によると、システムはデッドロックします。それはどのように機能しますか?
3
CMCDragonkai

あなたの質問のいくつかに、順番に答えます:

  1. アプリケーションの起動スクリプトでmount -o remount,nr_inodes=NUM /run/lockを使用できます(uid = 0で実行されている場合)。 / etc/fstabに関連する行を追加しても安全ですが、テストされていません。
  2. すべてのiノードがいっぱいになった場合でもシステムの他の部分に干渉しないため、ここでは分離がある程度意味があります。
  3. はい、完全に独立しています。
  4. [...]
  5. 仮想(非ブロックデバイスベース)ファイルシステムでは、デバイスとして何でもマウントコマンドに入れることができます。重要なのはタイプだけです。
  6. [...]

アプリケーションが空のファイルを開いて作成するかどうか(およびその期間)はわかりませんが、枯渇を避けるために、開いているファイルの制限を増やすことを検討することもできます(チェックlimit)。

1
sam_pan_mariusz

あなたはこれについて間違った方向に進んでいます。ファイルシステムのセマンティクスを使用して、一貫性を強制できます。

  1. ファイルを読みたいときは、開いて読んでください。 常にこの操作にはopenを使用し、決してaccessを使用しないでください。 PHPライブラリを使用してこれを行う場合は、ファイルでopenではなくaccessを呼び出すだけであることを確認してください。ただし、fopenは正常に機能するはずです。

  2. 新しいファイルを更新または作成する場合は、次の操作を実行します。-

    • 一時ファイル作成メカニズムを使用して新しいファイルを作成します。存在しない場合-存在する可能性が低い新しいファイル名を作成します(filename.XXXXXX、Xはランダムな文字に置き換えられます)。必ずO_EXCLで開いてください。
    • 関連するデータをファイルに書き込みます。
    • ファイルの名前を古いファイルの名前に変更します。

名前の変更はアトミックに定義されているため、これは操作上安全です。ファイルを開くリーダーには、古いファイルまたは新しいファイルのいずれかが表示されますが、キャッシュ内に存在しないファイルは表示されません。

各ファイルの同時チェックが多数ある最悪の場合、多数のライターが互いに簡単に上書きします。しかし、これは方法です-各ファイルに対してファイルロックを使用するよりもはるかに安価です。

または、ファイルごとにロックファイルを用意するのではなく、実際には個々のキャッシュオブジェクトを直接ロックすることを検討してください。しかし、私はまだこれが拡大縮小するとは思いません。

この場合、renameおよびlinkセマンティクスを使用すると、キャッシュとの整合性が保証され、ファイルをロックするよりもはるかに安価に管理できます。

0
Matthew Ife