コンピューティングとストレージが分離されたアーキテクチャでは、Fluid データキャッシングを使用して、Kubernetes クラスター内のストレージシステムにアクセスする際の高レイテンシーや帯域幅の制限といった問題を解決できます。これにより、データ処理の効率が向上します。このトピックでは、Fluid データキャッシュポリシーを使用して、パフォーマンス、安定性、および読み書きの整合性を最適化する方法について説明します。
利用シーン
キャッシング技術は、局所性の原理に基づいてデータアクセス性能を向上させます。AI トレーニング、推論サービスの起動、ビッグデータ分析などのシナリオはすべて、反復的なデータアクセスを特徴とします。例:
AI トレーニングでは、モデルの反復をサポートするためにデータセットが定期的に読み取られます。
推論サービスが起動すると、複数のインスタンスが同じモデルファイルを GPU メモリに同時にロードします。
ビッグデータ分析では、SparkSQL がユーザーペルソナやプロダクト情報を処理する際に、注文データが複数のタスクで共有されます。
Fluid データキャッシングは、上記のすべてのシナリオで効率を向上させるために使用できます。
パフォーマンス向上のための Fluid データキャッシュ最適化ポリシー
Fluid データキャッシングでパフォーマンスを向上させるには、パフォーマンス要件と予算に基づいて ECS インスタンスタイプ、キャッシュメディア、キャッシュシステムのパラメーター、および管理ポリシーを設定できます。また、クライアントのデータ読み取りモードを適応させてパフォーマンスを最適化することもできます。このトピックでは、これらの設定要素を組み合わせて適用する方法について説明します。
ポリシー 1:キャッシュシステム用の ECS インスタンスタイプの選択
パフォーマンスの見積もり
分散ファイルキャッシュシステムは、複数のノード上のストレージと帯域幅リソースを集約して、アプリケーションにより大きなキャッシュ容量とより高い利用可能帯域幅を提供できます。キャッシュ容量、利用可能帯域幅、および最大アプリケーションデータアクセス帯域幅の理論上の上限は、次の数式を使用して推定できます:
利用可能なキャッシュ容量 = 分散キャッシュ Worker Pod あたりのキャッシュ容量 × 分散キャッシュ Worker Pod のレプリカ数
利用可能なキャッシュ帯域幅 = 分散キャッシュ Worker Pod のレプリカ数 × min{Worker Pod が配置されている ECS ノードの最大利用可能帯域幅, Worker Pod が使用するキャッシュメディアの I/O スループット}。利用可能なキャッシュ帯域幅は、データアクセス中の実際の帯域幅を表すものではありません。実際の帯域幅は、クライアント ECS ノードの利用可能帯域幅と、シーケンシャル読み取りやランダム読み取りなどのアクセスモードの影響を受けます。
アプリケーション Pod のデータアクセスの理論上の最大帯域幅 = min{アプリケーション Pod が配置されている ECS ノードの利用可能帯域幅, 利用可能なキャッシュ帯域幅}。複数のアプリケーション Pod が同時にデータにアクセスする場合、利用可能なキャッシュ帯域幅はこれらの Pod 間で共有されます。
例
たとえば、2 つの ecs.g7nex.8xlarge ECS インスタンスを追加して Container Service for Kubernetes (ACK) クラスターをスケールアウトし、分散キャッシュクラスターを構築できます。クラスターには 2 つのキャッシュ Worker Pod が含まれます。各 Pod はキャッシング用に 100 GiB のメモリで構成され、2 つの Pod は別々の ECS インスタンスで実行されます。アプリケーション Pod は 1 つの ecs.gn7i-c8g1.2xlarge ECS インスタンス (8 vCPU、30 GiB のメモリ、16 Gbps の帯域幅) にデプロイされます。キャッシュ容量、利用可能帯域幅、および最大帯域幅の理論値は次のとおりです:
利用可能なキャッシュ容量 = 100 GiB × 2 = 200 GiB
利用可能なキャッシュ帯域幅 = 2 × min{40 Gbps, メモリアクセス I/O スループット} = 80 Gbps
キャッシュヒットが発生した場合、アプリケーション Pod のデータアクセスの最大利用可能帯域幅 = min{80 Gbps, 16 Gbps} = 16 Gbps
推奨される ECS インスタンスタイプ
分散キャッシュクラスターの利用可能帯域幅は、クラスター内の各 ECS ノードの最大利用可能帯域幅と使用されるキャッシュメディアに依存します。分散キャッシュシステムのパフォーマンスを向上させるには、高帯域幅の ECS インスタンスタイプを使用し、メモリ、ローカル HDD、またはローカル SSD をキャッシュメディアとして使用できます。次の表に、推奨される ECS インスタンスタイプを示します。
ECS インスタンスファミリー | ECS インスタンスタイプ | ECS インスタンス構成 |
g7nex、ネットワーク拡張型汎用インスタンスファミリー | ecs.g7nex.8xlarge | 32 vCPU、128 GiB メモリ、40 Gbps 帯域幅 |
ecs.g7nex.16xlarge | 64 vCPU、256 GiB メモリ、80 Gbps 帯域幅 | |
ecs.g7nex.32xlarge | 128 vCPU、512 GiB メモリ、160 Gbps 帯域幅 | |
i4g、ローカル SSD 搭載インスタンスファミリー | ecs.i4g.16xlarge | 64 vCPU、256 GiB メモリ、2 × 1920 GB ローカル SSD ストレージ、32 Gbps 帯域幅 |
ecs.i4g.32xlarge | 128 vCPU、512 GiB メモリ、4 × 1920 GB ローカル SSD ストレージ、64 Gbps 帯域幅 | |
g7ne、ネットワーク拡張型汎用インスタンスファミリー | ecs.g7ne.8xlarge | 32 vCPU、128 GiB メモリ、25 Gbps 帯域幅 |
ecs.g7ne.12xlarge | 48 vCPU、192 GiB メモリ、40 Gbps 帯域幅 | |
ecs.g7ne.24xlarge | 96 vCPU、384 GiB メモリ、80 Gbps 帯域幅 | |
g8i、汎用インスタンスファミリー | ecs.g8i.24xlarge | 96 vCPU、384 GiB メモリ、50 Gbps 帯域幅 |
ecs.g8i.16xlarge | 64 vCPU、256 GiB メモリ、32 Gbps 帯域幅 |
ECS インスタンスの詳細については、「インスタンスファミリー」をご参照ください。
ポリシー 2:キャッシュメディアの選択
分散キャッシュクラスターの利用可能帯域幅は、クラスター内の各 ECS ノードの最大利用可能帯域幅と使用されるキャッシュメディアに依存します。分散キャッシュシステムのパフォーマンスを向上させるには、高帯域幅の ECS インスタンスタイプを使用し、メモリまたはローカル SSD をキャッシュメディアとして使用できます。Fluid では、Runtime リソースオブジェクトの spec.tieredstore パラメーターを設定することで、さまざまなキャッシュメディアとキャッシュ容量を構成できます。
エンタープライズ SSD (ESSD) をキャッシュメディアとして使用する場合、データ集約型アプリケーションの高性能なデータアクセスニーズを満たせないことがよくあります。たとえば、単一の PL2 ディスクの最大スループットは 750 MB/s です。これは、キャッシュメディアとして 1 つの PL2 ディスクのみを使用する場合、750 MB/s を超える利用可能帯域幅を持つ ECS インスタンスタイプを選択したとしても、ECS ノードが提供できる最大利用可能キャッシュ帯域幅はわずか 750 MB/s になることを意味します。この構成では、ECS ノードの最大利用可能帯域幅が無駄になります。
キャッシュメディアとしてメモリを使用
メモリをキャッシュメディアとして使用する場合、Runtime リソースオブジェクトの spec.tieredstore を次のように構成できます:
spec:
tieredstore:
levels:
- mediumtype: MEM
volumeType: emptyDir
path: /dev/shm
quota: 30Gi # 単一の分散キャッシュ Worker レプリカが提供できるキャッシュ容量。
high: "0.99"
low: "0.95"キャッシュメディアとしてローカルストレージを使用
ローカルシステムディスクストレージをキャッシュメディアとして使用する場合:
spec: tieredstore: levels: - mediumtype: SSD volumeType: emptyDir # emptyDir を使用して、キャッシュデータのライフサイクルが分散キャッシュ Worker Pod と同じになるようにします。これにより、キャッシュデータの残留を防ぎます。 path: /var/lib/fluid/cache quota: 100Gi # 単一の分散キャッシュ Worker レプリカが提供できるキャッシュ容量。 high: "0.99" low: "0.95"追加でマウントされた SSD データディスクをキャッシュメディアとして使用する場合:
spec: tieredstore: levels: - mediumtype: SSD volumeType: hostPath path: /mnt/disk1 # /mnt/disk1 はホスト上のローカル SSD のマウントパスです。 quota: 100Gi # 単一の分散キャッシュ Worker レプリカが提供できるキャッシュ容量。 high: "0.99" low: "0.95"複数の SSD データディスクを同時にキャッシュメディアとして使用する場合:
spec: tieredstore: levels: - mediumtype: SSD volumeType: hostPath path: /mnt/disk1,/mnt/disk2 # /mnt/disk1 と /mnt/disk2 はホスト上のデータディスクのマウントパスです。 quota: 100Gi # 単一の分散キャッシュ Worker レプリカが提供できるキャッシュ容量。容量は複数のキャッシュパスに均等に分散されます。たとえば、/mnt/disk1 と /mnt/disk2 にはそれぞれ 50 GiB の容量が割り当てられます。 high: "0.99" low: "0.95"
ポリシー 3:データキャッシュとアプリケーション間のスケジューリングアフィニティの設定
データアクセスリクエストがキャッシュにヒットすると、アプリケーション Pod はキャッシュシステムからデータを読み取ります。したがって、アプリケーション Pod とキャッシュシステムが異なるゾーンにデプロイされている場合、アプリケーションはゾーンを越えてキャッシュデータにアクセスする必要があります。データアクセスプロセスにおけるゾーン間のネットワーク変動の影響を軽減するために、アプリケーション Pod とキャッシュシステムの関連 Pod との間のスケジューリングアフィニティを考慮する必要があります。具体的には:
可能な限り、キャッシュシステムの Worker Pod を同じゾーンにアフィニティ展開します。
可能な限り、アプリケーション Pod とキャッシュシステムの Worker Pod を同じゾーンにアフィニティ展開します。
複数のアプリケーション Pod とキャッシュシステムの Worker Pod を単一ゾーンに展開すると、アプリケーションと関連サービスのディザスタリカバリ能力が低下します。ビジネスのサービスレベルアグリーメント (SLA) に基づいて、パフォーマンスへの影響とサービスの可用性のバランスを取ることができます。
Fluid では、以下に示すように、Dataset リソースオブジェクトの spec.nodeAffinity を設定することで、キャッシュシステムの Worker Pod のスケジューリングアフィニティを構成できます:
apiVersion: data.fluid.io/v1alpha1
kind: Dataset
metadata:
name: demo-dataset
spec:
...
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: topology.kubernetes.io/zone
operator: In
values:
- <ZONE_ID> # Pod が配置されているゾーン、例:cn-beijing-i。上記の設定により、すべての分散キャッシュシステムの Worker Pod が <ZONE_ID> ゾーンの ECS ノードにデプロイされます。
さらに、Fluid は必要なキャッシュのアフィニティ情報をアプリケーション Pod に自動的に注入できます。これにより、アプリケーション Pod とキャッシュシステムの Worker Pod が可能な限り同じゾーンにアフィニティ展開されることが保証されます。詳細については、「データキャッシュアフィニティに基づくスケジューリングの最適化」をご参照ください。
ポリシー 4:大容量ファイルの完全シーケンシャル読み取りシナリオにおけるパラメーター設定の最適化
多くのデータ集約型シナリオでは、大容量ファイルの完全シーケンシャル読み取りというデータアクセスモードが伴います。例としては、TFRecord または Tar 形式のデータセットに基づくモデルトレーニング、AI モデル推論サービスの開始時に 1 つ以上のモデルパラメーターファイルをロードする場合、分散データ分析のために Parquet ファイル形式を読み取る場合などがあります。このようなシナリオでは、より積極的なプリフェッチポリシーを使用してデータアクセスパフォーマンスを向上させることができます。たとえば、キャッシュシステムのプリフェッチ同時実行数とプリフェッチデータ量を適切に増やすことができます。
Fluid では、分散キャッシュランタイムが異なると、以下で説明するように、プリフェッチポリシーのパラメーター設定も異なります:
キャッシュランタイムとして JindoRuntime を使用
JindoRuntime をキャッシュランタイムとして使用する場合、spec.fuse.properties パラメーターを設定して、Jindo FUSE の動作とパフォーマンスをカスタマイズできます。
kind: JindoRuntime
metadata:
...
spec:
fuse:
properties:
fs.oss.download.thread.concurrency: "200"
fs.oss.read.buffer.size: "8388608"
fs.oss.read.readahead.max.buffer.count: "200"
fs.oss.read.sequence.ambiguity.range: "2147483647" # 約 2 GB。fs.oss.download.thread.concurrency:Jindo クライアントの同時プリフェッチスレッド数。各スレッドはバッファーをプリフェッチするために使用されます。fs.oss.read.buffer.size:単一バッファーのサイズ。fs.oss.read.readahead.max.buffer.count:Jindo クライアントによる単一ストリームプリフェッチの最大バッファー数。fs.oss.read.sequence.ambiguity.range:Jindo クライアントがプロセスがファイルをシーケンシャルに読み取っているかどうかを判断するために使用する範囲。
キャッシュランタイムとして JuiceFSRuntime を使用
キャッシュランタイムとして JuiceFSRuntime を使用する場合、Runtime リソースオブジェクトの spec.fuse.options と spec.worker.options をそれぞれ構成することで、FUSE および Worker コンポーネントのパラメーターを設定できます。
kind: JuiceFSRuntime
metadata:
...
spec:
fuse:
options:
buffer-size: "2048"
cache-size: "0"
max-uploads: "150"
worker:
options:
buffer-size: "2048"
max-downloads: "200"
max-uploads: "150"
master:
resources:
requests:
memory: 2Gi
limits:
memory: 8Gi
...buffer-size:読み取り/書き込みバッファーのサイズ。
max-downloads:プリフェッチプロセスのダウンロード同時実行数。
fuse cache-size:JuiceFS FUSE コンポーネントで利用可能なローカルキャッシュ容量。
たとえば、JuiceFS FUSE コンポーネントで利用可能なローカルキャッシュ容量を 0 に設定し、FUSE コンポーネントのメモリ requests を 2 GiB などの小さい値に設定できます。FUSE コンポー-ネントは、ノード上の利用可能なメモリを Linux ファイルシステムカーネルのニアローカルキャッシュ (ページキャッシュ) として自動的に使用します。ニアローカルキャッシュミスが発生した場合、JuiceFS Worker 分散キャッシュから直接データを読み取り、効率的なアクセスを実現します。パフォーマンスチューニングとパラメーターの詳細については、「JuiceFS 公式ドキュメント」をご参照ください。
安定性のための Fluid データキャッシュ最適化ポリシー
Fluid データキャッシュシステムの安定した運用を確保するために、いくつかの最適化ポリシーを実装できます。単一点過負荷を防ぐために、多数のファイルを持つディレクトリをマウントターゲットとしてマウントすることは避けてください。エンタープライズ SSD (ESSD) などの永続ストレージを使用してメタデータの永続化を実装し、ディザスタリカバリ能力を強化します。FUSE Pod のリソースを割り当てて需要と供給のバランスを取り、自動障害回復のための自己修復メカニズムを有効にします。以下のセクションでは、これらの主要なポリシーを実装する方法について説明します。
ポリシー 1:多数のファイルを含むディレクトリを基盤となるデータソースとしてマウントしない
キャッシュシステムは、マウントされた基盤となるストレージディレクトリ内のすべてのファイルのメタデータを維持し、各ファイルのキャッシュステータスなどの追加のメタデータを記録する必要があります。キャッシュシステムが、大規模ストレージシステムのルートディレクトリなど、多数のファイルを含む基盤となるストレージディレクトリをマウントする場合、キャッシュシステムはメタデータを保存するために大量のメモリリソースを使用し、メタデータアクセスリクエストを処理するためにより多くの CPU リソースを使用する必要があります。
Fluid は、Dataset を特定のアプリケーションの論理的に関連するデータセットとして定義します。Dataset は、分散キャッシュシステムの起動に対応します。Dataset は、1 つまたは少数の関連するデータ集約型タスクに対してのみデータアクセス高速化サービスを提供する必要があります。したがって、複数の Dataset を作成し、各 Dataset で基盤となるデータソースの異なるサブディレクトリを定義できます。特定のサブディレクトリレベルは、ビジネスアプリケーションが必要とするデータ収集に依存します。異なるビジネスアプリケーションは、異なる Dataset にバインドされたキャッシュシステムを使用してデータにアクセスできます。これにより、ビジネスアプリケーション間の分離が向上し、システムの安定性とパフォーマンスが確保されます。Dataset の構成例は次のとおりです:
apiVersion: data.fluid.io/v1alpha1
kind: Dataset
metadata:
name: demo-dataset
spec:
...
mounts:
- mountPoint: oss://<BUCKET>/<PATH1>/<SUBPATH>/
name: sub-bucket複数のキャッシュシステムを作成すると、運用保守 (O&M) の複雑さが増す可能性があります。実際のビジネスニーズに基づいて、アーキテクチャソリューションを柔軟に選択できます。例:
キャッシュするデータセットが単一のバックエンドストレージシステムに保存され、サイズが小さく、ファイル数が少なく、関連性が強い場合は、単一の Fluid Dataset と分散キャッシュシステムを作成してサービスを提供できます。
キャッシュするデータセットが大きく、多数のファイルが含まれている場合は、データディレクトリのビジネスロジックに基づいて複数の Fluid Dataset と分散キャッシュシステムに分割できます。アプリケーション Pod は、指定されたディレクトリにマウントする 1 つ以上の Fluid Dataset を宣言できます。
キャッシュするデータセットが複数のユーザーの異なるストレージシステムから取得され、ユーザー間のデータ分離が必要な場合は、各ユーザーまたはユーザーの一連のデータ関連ジョブに対して短命の Fluid Dataset を作成できます。また、Kubernetes Operator を開発して、クラスター内の複数の Fluid Dataset を柔軟に管理することもできます。
ポリシー 2:メタデータの永続化によるキャッシュシステムの安定性向上
多くの分散キャッシュシステムは、Master-Worker 分散アーキテクチャを使用しています。これらのシステムは、Master Pod コンポーネントに依存して、マウントされたバックエンドストレージディレクトリのファイルメタデータを維持し、各ファイルのキャッシュステータスを記録します。アプリケーションがこのようなキャッシュシステムを介してデータにアクセスする場合、まず Master Pod コンポーネントからファイルメタデータを取得し、次に基盤となるファイルストレージまたはキャッシュ Worker コンポーネントからデータを取得します。したがって、キャッシュ Master Pod コンポーネントの安定性は、キャッシュシステムの高可用性にとって極めて重要です。
キャッシュランタイムとして JindoRuntime を使用する場合、Fluid で次の構成を使用してキャッシュ Master Pod コンポーネントの可用性を向上させることができます:
apiVersion: data.fluid.io/v1alpha1
kind: JindoRuntime
metadata:
name: sd-dataset
spec:
...
volumes:
- name: meta-vol
persistentVolumeClaim:
claimName: demo-jindo-master-meta
master:
resources:
requests:
memory: 4Gi
limits:
memory: 8Gi
volumeMounts:
- name: meta-vol
mountPath: /root/jindofs-meta
properties:
namespace.meta-dir: "/root/jindofs-meta"上記の YAML の例では、demo-jindo-master-meta は事前に作成された永続ボリューム要求 (PVC) です。この PVC は、永続ボリューム (PV) として ESSD を使用します。これは、Master Pod コンポーネントによって維持されるメタデータを永続的に保存でき、Pod と共に移行できることを意味します。詳細については、「JindoRuntime を使用して Master Pod コンポーネントの状態を永続化する」をご参照ください。
ポリシー 3:FUSE Pod のリソース設定
キャッシュシステムのクライアントプログラムは FUSE Pod 内で実行されます。FUSE Pod は、ノード上に FUSE ファイルシステムをマウントします。このファイルシステムは、アプリケーション Pod 上の指定されたパスにマウントされ、POSIX ファイルアクセスインターフェイスを公開します。これにより、アプリケーション Pod は、アプリケーションコードを変更することなく、リモートストレージシステム内のデータにローカルストレージにアクセスするかのようにアクセスでき、キャッシュ高速化の恩恵を受けることができます。FUSE プログラムは、アプリケーションとキャッシュシステム間のデータトンネルを維持します。したがって、FUSE Pod のリソースを設定することを推奨します。
Fluid では、Runtime リソースオブジェクトの spec.fuse.resources フィールドを構成することで、FUSE Pod のリソース使用量を設定できます。FUSE プログラムのメモリ不足 (OOM) エラーによるファイルマウントターゲットの破損を避けるために、FUSE Pod にメモリ制限を設定しないか、大きなメモリ制限を設定することを推奨します。たとえば、FUSE Pod のメモリ制限を ECS ノードの割り当て可能なメモリサイズに近づけることができます。
spec:
fuse:
resources:
requests:
memory: 8Gi
# limits:
# memory: <ECS_ALLOCATABLE_MEMORY>ポリシー 4:FUSE 自己修復機能の有効化によるデータアクセスクライアントの可用性向上
FUSE プログラムは、アプリケーションとキャッシュシステム間のデータトンネルを維持します。デフォルトでは、FUSE プログラムが予期しない動作によりクラッシュした場合、FUSE プログラムが再起動して回復した後でも、アプリケーションコンテナーはその FUSE ファイルシステムのマウントターゲットを介してデータにアクセスできなくなります。データアクセスを復元するには、アプリケーションコンテナーを再起動する必要があります。この再起動により、FUSE ファイルシステムのマウントターゲットからアプリケーション Pod へのバインドマウントロジックが再トリガーされます。これは、アプリケーション Pod の可用性に影響します。
Fluid は FUSE 自己修復メカニズムを提供します。このメカニズムが有効になっている場合、アプリケーションコンテナーを再起動する必要はありません。FUSE プログラムが再起動してから短時間で、アプリケーションコンテナー内の FUSE マウントターゲットへのデータアクセスが自動的に復元されます。
FUSE プログラムがクラッシュしてから再起動するまでの短時間、アプリケーション Pod 内のマウントターゲットはアクセス不能になります。これは、アプリケーションがクラッシュを避けるためにこれらの I/O エラーを処理し、リトライロジックを含める必要があることを意味します。
FUSE 自己修復機能を有効にして使用するには、「FUSE 自動回復機能を有効にする方法」をご参照ください。FUSE 自己修復機能には多くの制限があります。この機能は、明確な要件と適切なビジネスニーズを持つ特定のアプリケーションシナリオでのみ有効にすることを推奨します。例としては、オンライン Notebook やその他の環境を使用してアプリケーションを対話的に開発およびデバッグする対話型プログラミング開発シナリオなどがあります。
キャッシュの読み書き整合性のベストプラクティス
キャッシュシステムはデータアクセス効率を向上させる一方で、キャッシュの整合性の問題も引き起こします。強力な整合性は通常、パフォーマンスの低下や運用保守 (O&M) コストの増加につながるため、ビジネスシナリオに合った読み書き整合性ポリシーを選択する必要があります。以下のセクションでは、複数のシナリオでキャッシュの読み書き整合性を構成する方法について詳しく説明します。
シナリオ 1:データが読み取り専用で、バックエンドストレージのデータが変更されない場合
ユースケース:単一の AI モデルトレーニングプロセス中に、固定データセットからデータサンプルを読み取り、反復的なモデルトレーニングを行います。トレーニング完了後、データキャッシュはクリアされます。
構成:このシナリオは Fluid によってデフォルトでサポートされています。デフォルトの Fluid Dataset 構成を使用するか、明示的に読み取り専用に設定できます。
構成例:
apiVersion: data.fluid.io/v1alpha1
kind: Dataset
metadata:
name: demo-dataset
spec:
...
# accessModes: ["ReadOnlyMany"] ReadOnlyMany がデフォルト値です。accessModes: ["ReadOnlyMany"] を設定すると、データセットが読み取り専用モードでマウントされることが保証されます。これにより、トレーニングプロセス中のデータセットの偶発的な変更を防ぎ、データ管理とキャッシュポリシーを簡素化します。
シナリオ 2:データが読み取り専用で、バックエンドストレージのデータが定期的に変更される場合
ユースケース:キャッシュシステムは Kubernetes クラスター内に存在します。ビジネス関連データは毎日収集され、バックエンドストレージシステムに保存されます。データ分析ジョブは深夜に定期的に実行され、その日の新しいビジネスデータを分析および集計します。集計結果はキャッシュをバイパスして、バックエンドストレージシステムに直接書き込まれます。
構成:デフォルトの Fluid Dataset 構成を使用するか、明示的に読み取り専用に設定し、定期的な間隔でデータプリフェッチを実行して、バックエンドストレージシステムからのデータ変更を同期させることができます。
構成例:
apiVersion: data.fluid.io/v1alpha1
kind: Dataset
metadata:
name: demo-dataset
spec:
...
# accessModes: ["ReadOnlyMany"] ReadOnlyMany はデフォルト値です。
---
apiVersion: data.fluid.io/v1alpha1
kind: DataLoad
metadata:
name: demo-dataset-warmup
spec:
...
policy: Cron
schedule: "0 0 * * *" # 毎日 00:00 にデータをプリフェッチします。
loadMetadata: true # データプリフェッチ中にバックエンドストレージシステムからデータ変更を同期します。
target:
- path: /path/to/warmup # プリフェッチが必要なバックエンドストレージシステム内のパスを指定します。accessModes: ["ReadOnlyMany"]を設定することで、データセットが主に読み取り操作に使用されることを保証します。これは、ビジネスデータがキャッシュレイヤーに干渉することなくバックエンドストレージシステムに直接書き込まれることを意味し、データの整合性と完全性を保証します。policy: Cronとschedule: "0 0 * * *"を設定すると、データプリフェッチ操作が毎日深夜に自動的に実行されることが保証されます。loadMetadata: true設定により、プリフェッチプロセス中にメタデータも同期されることが保証されます。
シナリオ 3:データが読み取り専用だが、ビジネスイベントに基づいてバックエンドストレージのデータが変更される場合
ユースケース:モデル推論サービスでは、カスタム AI モデルをアップロードして推論に使用できます。アップロードされた AI モデルはキャッシュされずにバックエンドストレージシステムに直接書き込まれます。モデルが正常にアップロードされた後、それを選択して推論を実行し、結果を表示できます。
構成:デフォルトの Fluid Dataset 構成を使用するか、明示的に読み取り専用に設定できます。FUSE (Filesystem in Userspace) のファイルメタデータタイムアウトを小さい値に設定し、キャッシュシステムのサーバーサイドのメタデータキャッシュを無効にします。
構成例:
キャッシュランタイムとして JindoRuntime を使用:
apiVersion: data.fluid.io/v1alpha1
kind: Dataset
metadata:
name: demo-dataset
spec:
mounts:
- mountPoint: <MOUNTPOINT>
name: data
path: /
options:
metaPolicy: ALWAYS # metaPolicy: ALWAYS を設定することで、サーバーサイドのメタデータキャッシュが無効になります。
---
apiVersion: data.fluid.io/v1alpha1
kind: JindoRuntime
metadata:
name: demo-dataset
spec:
fuse:
args:
- -oauto_cache
# メタデータのタイムアウトを 30 秒に設定します。xxx_timeout=0 の場合、強力な整合性を提供できますが、データ読み取り効率が大幅に低下する可能性があります。
- -oattr_timeout=30
- -oentry_timeout=30
- -onegative_timeout=30
- -ometrics_port=0metaPolicy: ALWAYS を設定することで、サーバーサイドのメタデータキャッシュが無効になります。これにより、各アクセスがバックエンドストレージを直接クエリして最新のメタデータを取得することが保証され、より強力な整合性を必要とするアプリケーションシナリオに適しています。
シナリオ 4:読み取りリクエストと書き込みリクエストが異なるディレクトリにある場合
ユースケース:大規模な分散 AI トレーニングでは、トレーニングジョブはディレクトリ A のデータセットからデータサンプルを読み取り、各エポックの後にモデルのチェックポイントをディレクトリ B に書き込みます。モデルのチェックポイントは大きくなる可能性があるため、書き込みをキャッシュすると効率が向上します。
構成:2 つの Fluid Dataset を作成します。一方のアクセスモードを読み取り専用に、もう一方を読み書きに設定します。2 つの Fluid Dataset をそれぞれディレクトリ A とディレクトリ B にマウントして、読み書き分離を実現します。
構成例:
apiVersion: data.fluid.io/v1alpha1
kind: Dataset
metadata:
name: train-samples
spec:
...
# accessModes: ["ReadOnlyMany"] ReadOnlyMany はデフォルト値です。
---
apiVersion: data.fluid.io/v1alpha1
kind: Dataset
metadata:
name: model-ckpt
spec:
...
accessModes: ["ReadWriteMany"] トレーニングデータセット train-samples を読み取り専用アクセスモード accessModes: ["ReadOnlyMany"] (デフォルト設定) に設定すると、すべてのトレーニングジョブがこのディレクトリからのみデータを読み取ることが保証されます。これにより、データソースの不変性が確保され、トレーニング中の書き込み操作によって引き起こされる可能性のある整合性の問題が回避されます。一方、モデルのチェックポイントディレクトリ (model-ckpt) は読み書きモード (accessModes: ["ReadWriteMany"]) で構成されます。これにより、トレーニングジョブは各反復後にモデルのチェックポイントを安全に書き込むことができ、書き込み効率が向上します。
アプリケーション Pod の定義例は次のとおりです:
apiVersion: v1
kind: Pod
metadata:
...
spec:
containers:
...
volumeMounts:
- name: train-samples-vol
mountPath: /data/A
- name: model-ckpt-vol
mountPath: /data/B
volumes:
- name: train-samples-vol
persistentVolumeClaim:
claimName: train-samples
- name: model-ckpt-vol
persistentVolumeClaim:
claimName: model-ckpt2 つの異なるボリューム (train-samples-vol と model-ckpt-vol) を指定されたパス (/data/A と /data/B) にマウントすることで、トレーニングデータセットとモデルのチェックポイントディレクトリ間の物理的な分離が実現されます。
シナリオ 5:読み取りリクエストと書き込みリクエストが同じディレクトリにある必要がある場合
ユースケース:オンラインの Jupyter Notebook や VS Code 開発などの対話型プログラミング開発シナリオでは、個人のワークスペースディレクトリがあります。このワークスペースディレクトリには、データセットやコードなどのファイルが保存されており、これらのファイルを頻繁に追加、削除、または変更することがあります。
構成:Dataset のアクセスモードを読み書きに設定します。バックエンド実装として、完全な POSIX (Portable Operating System Interface) 互換性を持つストレージシステムを使用することを推奨します。
構成例:
apiVersion: data.fluid.io/v1alpha1
kind: Dataset
metadata:
name: myworkspace
spec:
...
accessModes: ["ReadWriteMany"] accessModes: ["ReadWriteMany"] を設定すると、複数のユーザーまたはプロセスが同じワークスペースディレクトリに同時に読み書きできることが保証されます。