オブジェクトストレージとデータベースの組み合わせによって駆動されるファイルシステムの場合、キャッシュはローカルクライアントとリモートサービス間の効率的な相互作用のための重要なリンクです。読み取りおよび書き込みデータは、事前にまたは非同期でキャッシュにロードできます。その後、クライアントはバックグラウンドでリモートサービスと対話して、非同期のアップロードまたはプリフェッチデータを実行します。リモートサービスと直接対話する場合と比較して、キャッシングテクノロジーを使用すると、ストレージ操作の遅延を大幅に削減し、データスループットを向上させることができます。
データの一貫性
JuiceFSは、「オープンに近い」整合性保証を提供します。つまり、2つ以上のクライアントが同時に同じファイルを読み書きする場合、クライアントAの変更がクライアントBにすぐに表示されない場合があります。ただし、ファイルがクライアントAで書き込まれ、閉じられると、後で任意のクライアントでファイルを再度開くと、同じノードであるかどうかに関係なく、最後に書き込まれたデータへのアクセスが保証されます。
「閉じて再度開く」は、JuiceFSが提供する最低限の整合性保証です。場合によっては、最新の書き込みデータにアクセスするためにファイルを再度開く必要がないことがあります。たとえば、複数のアプリケーションが同じJuiceFSクライアントを使用して、同じファイルにアクセスしたり(ファイルの変更はすぐに表示されます)、異なるノードのtail -f
コマンド。
メタデータキャッシュ
JuiceFSは、メタデータアクセスのパフォーマンスを向上させるために、カーネルおよびクライアントメモリ(つまり、JuiceFSプロセス)でのメタデータのキャッシュをサポートします。
カーネルメタデータキャッシュ
カーネルにキャッシュできるメタデータには、属性、エントリ、およびdirentryの3種類があります。キャッシュ時間は、次のマウントパラメータによって制御できます。
--attr-cache value 属性缓存时长,单位秒 (默认值: 1)
--entry-cache value 文件项缓存时长,单位秒 (默认值: 1)
--dir-entry-cache value 目录项缓存时长,单位秒 (默认值: 1)
JuiceFSは、デフォルトで1秒間、属性、ファイルアイテム、およびディレクトリアイテムをカーネルにキャッシュして、ルックアップとgetattrのパフォーマンスを向上させます。複数のノードのクライアントが同時に同じファイルシステムを使用する場合、カーネルにキャッシュされたメタデータは、時間の経過とともにのみ無効にできます。つまり、極端な場合、ノードAがファイルのメタデータを変更する可能性があり(たとえばchown
)、ノードBを介したアクセスでは更新をすぐに確認できません。もちろん、キャッシュの有効期限が切れると、すべてのノードは最終的にAによって行われた変更を確認します。
クライアント側のメモリ内メタデータキャッシュ
注:この機能には、JuiceFSバージョン0.15.0以降が必要です。
open()
JuiceFSクライアントがファイルを開くと、そのファイル属性はクライアントメモリに自動的にキャッシュされます。ファイルシステムが0より大きい値でマウントされているときに--open-cache
オプション、キャッシュの有効期限が切れていない限り、後続getattr()
のopen()
操作はメモリ内キャッシュから結果をすぐに返します。
read()
操作、つまりファイルの読み取りを実行すると、ファイルのチャンクとスライスの情報がクライアントメモリに自動的にキャッシュされます。キャッシュの有効期間中に、チャンクを再度読み取ると、メモリキャッシュからスライス情報がすぐに返されます。
ヒント:「JuiceFSがファイルを保存する方法」を読んで、チャンクとスライスが何であるかを学ぶことができます。
デフォルトでは、メタデータがメモリにキャッシュされているファイルの場合、どのプロセスからも1時間以上アクセスされていないと、そのすべてのメタデータキャッシュが自動的に削除されます。
データキャッシュ
JuiceFSは、カーネルのページキャッシュや、クライアントが配置されているノードのローカルキャッシュなど、パフォーマンスを向上させるためのデータのさまざまなキャッシュメカニズムも提供します。
カーネルデータキャッシュ
注:この機能には、JuiceFSバージョン0.15.0以降が必要です。
読み取られたファイルの場合、カーネルはそのコンテンツを自動的にキャッシュしてからファイルを開きます。ファイルが更新されていない場合(つまり、mtimeが更新されていない場合)、ファイルはキャッシュから直接読み取ることができます。最高のパフォーマンスを得るためにカーネルで。カーネルキャッシュのおかげで、JuiceFSで同じファイルを繰り返し読み取ることができ、待ち時間はマイクロ秒と短く、スループットは1秒あたりGiBです。
JuiceFSクライアントは、デフォルトでカーネルの書き込みキャッシュ機能を有効にしていません。Linuxカーネル3.15以降、FUSEは「ライトバックキャッシュモード」をサポートします。これは、write()
システム。ファイルシステムをマウントするときに-o writeback_cache
オプション。非常に小さいデータ(約100バイトなど)を頻繁に書き込む必要がある場合は、このマウントオプションを有効にすることをお勧めします。
クライアント読み取りキャッシュ
JuiceFSクライアントは、読み取りモードに従ってデータをキャッシュに自動的に事前読み取りするため、順次読み取りのパフォーマンスが向上します。デフォルトでは、データを読み取るときに、1つのブロックが同時にプリフェッチされてローカルにキャッシュされます。ローカルキャッシュは、ハードディスク、SSD、またはメモリに基づく任意のローカルファイルシステムに設定できます。
ローカルキャッシュは、ファイルシステムをマウントするときに次のオプションで調整できます。
--prefetch value 并发预读 N 个块 (默认: 1)
--cache-dir value 本地缓存目录路径;使用冒号隔离多个路径 (默认: "$HOME/.juicefs/cache" 或 "/var/jfsCache")
--cache-size value 缓存对象的总大小;单位为 MiB (默认: 1024)
--free-space-ratio value 最小剩余空间比例 (默认: 0.1)
--cache-partial-only 仅缓存随机小块读 (默认: false)
さらに、JuiceFSのローカルキャッシュをメモリに保存する場合は、2つの方法があります。1つはに--cache-dir
設定memory
する方法/dev/shm/<cache-dir>
です。2つの方法の違いは、前者はJuiceFSファイルシステムを再マウントした後にキャッシュされたデータをクリアし、後者はそれを保持することであり、パフォーマンスの点で2つの方法に大きな違いはありません。
JuiceFSクライアントは、オブジェクトストレージからダウンロードされたデータ(1ブロックサイズ未満の新しくアップロードされたデータを含む)を、圧縮や暗号化を行わずにできるだけ早くキャッシュディレクトリに書き込みます。JuiceFSは、オブジェクトストアに書き込まれるすべてのブロックオブジェクトに一意の名前を生成し、すべてのブロックオブジェクトは変更されないため、ファイルの内容が更新されるときにキャッシュデータの無効化について心配する必要はありません。
キャッシュスペースが上限に達すると(つまり、キャッシュのサイズが以上になると--cache-size
)、またはディスクがいっぱいになると(つまり、ディスク上の空き領域の割合がそれよりも小さくなると--free-space-ratio
)、次のようになります。自動的にクリーンアップされます。現在のルールでは、アクセス時間に応じて、アクセス頻度の低いファイルを最初にクリーンアップします。
データキャッシングは、ランダム読み取りパフォーマンスを効果的に向上させることができます。ElasticsearchやClickHouseなど、より高いランダム読み取りパフォーマンスを必要とするアプリケーションでは、より高速なストレージメディアにキャッシュパスを設定し、より大きなキャッシュスペースを割り当てることをお勧めします。
クライアント書き込みキャッシュ
データを書き込む場合、JuiceFSクライアントはデータをメモリclose()
にfsync()
、チャンクがいっぱいになるか、またはによって強制されるまで、データはオブジェクトストレージにアップロードされません。fsync()
またはを呼び出すclose()
と、クライアントはデータがオブジェクトストアに書き込まれるまで待機し、メタデータサービスに通知してから戻ります。これにより、データの整合性が確保されます。
場合によっては、ローカルストレージの信頼性が高く、ローカルストレージの書き込みパフォーマンスがネットワーク書き込み(SSDディスクなど)よりも大幅に優れている場合は、データの非同期アップロードを有効にすることで書き込みパフォーマンスを向上させることができます。close()
操作は、データがオブジェクトストアに書き込まれるのを待機しませんが、データがローカルキャッシュディレクトリに書き込まれると戻ります。
非同期アップロード機能はデフォルトで無効になっており、次のオプションで有効にできます。
--writeback 后台异步上传对象 (默认: false)
短時間で多数の小さなファイルを書き込む必要がある場合は、--writeback
パラメータ。書き込みが完了したら、このオプションをキャンセルして再マウントすることを検討してください。後続の書き込まれたデータのより高い信頼性を取得します。さらに、MySQLの増分バックアップなど、多数のランダム書き込み操作を必要とするシナリオを有効にすることもお勧めします--writeback
。
警告:非同期アップロードが有効になっている
--writeback
場合<cache-dir>/<UUID>/rawstaging
場合は、ディレクトリの内容を削除しないでください。削除すると、データが失われます。
キャッシュディスクがいっぱいになると、データの書き込みが一時停止され、代わりにデータがオブジェクトストレージに直接アップロードされます(つまり、クライアント側の書き込みキャッシュ機能がオフになります)。非同期アップロード機能を有効にすると、キャッシュ自体の信頼性はデータ書き込みの信頼性に直接関係します。高いデータ信頼性が必要なシナリオでは注意して使用する必要があります。
要約する
最後に、ユーザーがよく尋ねる質問を共有します**「キャッシュサイズが50 GiBに設定されているのに、実際には60GiBのスペースが必要なのはなぜですか?」**
キャッシュされたデータの量が同じ場合、ファイルシステムごとに容量計算ルールが異なります。JuiceFSは現在、キャッシュされたすべてのオブジェクトのサイズを累積し、固定オーバーヘッド(4KiB)を追加することによって推定されます。これは、du
コマンド。キャッシュディスクがいっぱいになるのを防ぐために、キャッシュディレクトリが配置されているファイルシステムの容量が不足すると、クライアントはキャッシュの使用量を可能な限り削減しようとします。
上記の紹介を通じて、JuiceFSのキャッシングメカニズムの原理をさらに理解することができます。JuiceFS自体は、基盤となるファイルシステムとして、メタデータキャッシュ、データの読み取りおよび書き込みキャッシュなどを含むさまざまなキャッシュメカニズムを提供し、データの一貫性を最大限に確保します。この記事を理解することで、JuiceFSをより適切に適用できることを願っています。
推奨読書:Zhihu x JuiceFS:JuiceFSを使用してFlinkコンテナの起動を加速する
それが役に立ったら、私たちのプロジェクトJuicedata / JuiceFSに従ってください!(0ᴗ0✿)