2.3. クラスター化されたキャッシュモード
クラスター化された Data Grid キャッシュを複製または分散として設定できます。
- 分散キャッシュ
- クラスター全体で各エントリーのコピー作成を減らして、容量を最大化します。
- レプリケートされたキャッシュ
- クラスター内の各ノードにすべてのエントリーのコピーを作成して冗長性を提供します。
読み取り操作 : 書き込み操作
アプリケーションによる書き込み操作を多くするか、読み取り操作を多くするか検討します。通常、分散キャッシュは書き込み操作で最適なパフォーマンスを、レプリケートキャッシュは読み取り操作で最適なパフォーマンスを実現できます。
所有者が 2 名のノード 3 つで設定されるクラスターの分散キャッシュに k1 を配置するには、Data Grid は k1 を 2 回書き込みます。レプリケートされたキャッシュで同じ操作を行うと、Data Grid は k1 を 3 回書き込みます。レプリケートキャッシュへの各書き込みの追加ネットワークトラフィックの量は、クラスター内のノード数と等しくなります。ノードが 10 個あるクラスターのレプリケートキャッシュでは、書き込みのトラフィクが 10 倍になるなどです。クラスタートランスポートのマルチキャストで UDP スタックを使用して、トラフィックを最小限に抑えることができます。
レプリケートキャッシュから k1 を取得するには、ノードごとに、ローカルに読み取り操作を実行できます。分散キャッシュから k1 を取得するには、操作を処理するノードはクラスター内の別のノードからキーを取得しないといけない場合があります。これにより、ネットワークホップが追加で発生し、読み取り操作が完了するまで時間が長くなります。
クライアントのインテリジェンスとニアキャッシュ
Data Grid は、一貫性のあるハッシュ技術を使用して、Hot Rod クライアントがトポロジーに対応するようにし、ネットワークホップが追加で発生しないようにすることで、分散キャッシュでも、レプリケートきゃっしゅでも、読み取り操作が同程度のパフォーマンスを出せるようにします。
また、Hot Rod クライアントは、ニアキャッシュ機能を使用して、頻繁にアクセスされるエントリーをローカルメモリーで保持し、読み込みの繰り返しを回避することもできます。
分散キャッシュは、ほとんどの Data Grid Server デプロイメントの選択肢として最適です。クラスタースケーリングの弾力性と合わせて、読み込み、書き取り操作でできるだけベストなパフォーマンスを獲得できます。
データの保証
各ノードにすべてのエントリーが含まれるため、レプリケートキャッシュは分散キャッシュよりも、データが損失されないように保護されます。3 つのノードで設定されるクラスターでは、2 つのノードがクラッシュでき、複製キャッシュからデータが失われることはありません。
同じシナリオでは、所有者が 2 人の分散キャッシュでは、データが損失します。分散キャッシュによるデータの損失を回避するには、owners 属性を宣言するか、numOwners() メソッドで各エントリーの所有者をさらに設定し、クラスター全体でのレプリカ数を増してください。
ノードの障害発生時の操作のリバランス
ノードの障害後に操作をリバランスすると、パフォーマンスや容量に影響を与える可能性があります。ノードがクラスターから退出すると、Data Grid は残りのメンバー間でキャッシュエントリーを複製して、設定された所有者数を復元します。このリバランス操作は一時的なものですが、クラスターのトラフィックが増加すると、パフォーマンスに悪影響を及ぼします。ノードの退出が増えると、パフォーマンスがさらに低下します。多数のノードが退出すると、クラスター内に残っているノードの容量が足りなくなり、メモリーに全データを保持できなくなる可能性があります。
クラスターのスケーリング
Data Grid クラスターは、ワークロードのニーズに合わせて水平的にスケーリングし、CPU やメモリーなどのコンピュートリソースをより効率的に使用します。この弾力性を最大限に活用するには、ノード数の増減でスケーリングすることでどの程度キャッシュの容量に影響があるかを検討する必要があります。
レプリケートキャッシュの場合は、ノードがクラスターに参加するたびに、データセットの完全なコピーを受け取ります。各ノードに全エントリーを複製すると、ノードの参加にかかる時間が長くなり、全体的な容量に制限が課せられます。レプリケートキャッシュは、ホストで利用可能なメモリー量を超えることはできません。たとえば、データセットのサイズが 10 GB の場合、各ノードに少なくとも 10 GB のメモリーが必要です。
分散キャッシュの場合は、クラスターの各メンバーがデータのサブセットのみを格納するため、ノードを追加すると容量も増加します。10 GB のデータを保存するには、所有者数が 2 つで、メモリーのオーバーヘッドを考慮しない場合には、利用可能なメモリーが 5 GB のノードを 8 個指定すると良いでしょう。追加のノードがクラスターに参加すると、分散キャッシュの容量が 5GB 増加します。
分散キャッシュの容量は、基盤となるホストで利用可能なメモリー量により、制限されることはありません。
同期または非同期のレプリケーション
Data Grid は、プライマリーの所有者がレプリケーション要求をバックアップノードに送信すると、同期または非同期に通信できます。
| レプリケーションモード | パフォーマンスへの影響 |
|---|---|
| 同期 | 同期レプリケーションは、データの整合性を保つのに役立ちますが、クラスタートラフィックに対するレイテンシーが増え、キャッシュの書き込みのスループットが減少します。 |
| 非同期 | 非同期レプリケーションでは、レイテンシーが短くなり、書き込み操作の速度が早くなりますが、データの不整合が発生するため、データ損失に対する保証が少なくなります。 |
同期レプリケーションでは、Data Grid は、バックアップノードでレプリケーション要求の完了時に元のノードに通知します。Data Grid は、クラスタートポロジーの変更が原因でレプリケーション要求に失敗すると、操作を再試行します。他のエラーが原因でレプリケーション要求に失敗すると、Data Grid はクライアントアプリケーションの例外を出力します。
非同期のレプリケーションでは、Data Grid はレプリケーション要求の確認は行いません。これは、すべての要求が正常に実行されるのと同じ効果を持ちます。ただし、Data Grid クラスターでは、プライマリーの所有者のエントリーが正しく、Data Grid は今後のある時点でバックアップノードに複製を作成します。プライマリー所有者がクラッシュすると、バックアップノードにエントリーのコピーがない場合や、以前のコピーが含まれる可能性があります。
クラスタートポロジーが変更されたことが原因で、非同期のレプリケーションでデータの不整合が生じる可能性もあります。たとえば、プライマリー所有者が複数指定されている Data Grid クラスターについて考えてみましょう。ネットワークエラーまたはその他の問題により、1 つ以上のプライマリー所有者が予期せずにクラスターから退出するため、Data Grid により、どのノードがどのセグメントのプライマリー所有者であるかが更新されます。これが発生すると、一部のノードで以前のクラスタートポロジーを使用し、他のノードで更新されたトポロジーを使用することが理論的に可能です。非同期通信では、Data Grid が以前のトポロジーからのレプリケーション要求を処理し、書き込み操作から以前の値を適用する時間が短縮される可能性があります。ただし、Data Grid はノードクラッシュを検出し、このシナリオから多くの書き込み操作に影響が及ばないように、素早くクラスターのトポロジーの変更を更新します。
非同期レプリケーションでは、1 回にノードが処理できるバックアップの書き込み数を、考えられる送信者数だけに限定するため、非同期のレプリケーションを使用しても、書き込みのスループットは保証されません。同期レプリケーションにより、ノードはより多くの受信書き込み操作を同時に処理できるようになり、特定の設定では個別の操作の完了に時間がかかることが考慮され、合計スループットが多くなっています。
ノードがエントリー複製の要求を複数送信すると、JGroups はクラスターの残りのノードに一度に 1 つずつメッセージを送信するので、送信元のノード別の複製要求は 1 つだけ作成されることになります。つまり、Data Grid ノードは他の書き込み操作と並行して処理でき、クラスター内の他のノードから書き込みを行うことができます。
Data Grid は、クラスタートランスポート層で JGroups フロー制御プロトコルを使用して、バックアップノードへのレプリケーション要求を処理します。未確認のレプリケーション要求の数が、max_credits 属性 (デフォルトでは 4MB) で設定されたフロー制御のしきい値を超えると、送信元ノードで書き込み操作がブロックされます。これは、同期および非同期レプリケーションの両方に適用されます。
セグメント数
Data Grid は、データをセグメントに分割して、データをクラスター全体に均等に分散します。セグメントを均等分散すると、個別のノードのオーバーロードが回避され、クラスターのリバランス操作をより効率化します。
Data Grid はデフォルトで、クラスターごとに 256 ハッシュ領域セグメントを作成します。クラスターごとに最大 20 個のノードで設定されるデプロイメントの場合には、このセグメント数が理想的であるため、変更しないでください。
クラスターごとに 20 を超えるノードで設定されるデプロイメントの場合には、セグメント数を増やすと、データの詳細レベルが上がるので、Data Grid はクラスター全体に効率的に分散できるようにします。設定するセグメント数を算出するには、以下の式を使用します。
Number of segments = 20 * Number of nodes
Number of segments = 20 * Number of nodes
たとえば、クラスターが 30 個ある場合は、600 セグメントを設定する必要があります。大規模なクラスターのセグメントを増やすことは、一般的には適切ですが、この公式でデプロイメントに適したおおよその数がわかります。
Data Grid が作成するセグメント数を変更するには、クラスターを完全に再起動する必要があります。永続ストレージを使用する場合は、キャッシュストアの実装によっては、StoreMigrator ユーティリティーを使用してセグメント数を変更する必要もあります。
セグメント数を変更すると、データが破損する可能性があるため、ベンチマーキングおよびパフォーマンスの監視で収集したメトリックをもとに、注意して変更する必要があります。
Data Grid は、メモリーに格納するデータを常にセグメント化します。キャッシュストアの設定時には、Data Grid では永続ストレージでデータのセグメント化が行われるわけではありません。
キャッシュストアの実装に依存しますが、可能な場合にはキャッシュストアのセグメント化を有効にしてください。セグメント化されたキャッシュストアは、永続ストレージのデータを反復処理する時に、Data Grid のパフォーマンスを向上させます。たとえば、RocksDB と JDBC 文字列ベースのキャッシュストアを使用すると、セグメント化により、Data Grid がデータベースから取得する必要のあるオブジェクトの数が減ります。