ホームページ  >  記事  >  Java  >  Java が cassandra の高度な操作のページング例を実装 (写真)

Java が cassandra の高度な操作のページング例を実装 (写真)

黄舟
黄舟オリジナル
2017-04-01 10:09:391554ブラウズ

この記事では、cassandra の高度な操作を実装するための ページネーション の例を主に紹介します (特定のプロジェクト要件を伴う)。興味のある方は参考にしてください。

前回のブログでは cassandra ページングについて説明しましたが、皆さんも注目していただけると思います。次の クエリ は前のクエリ (前のクエリの最後のレコードのすべての主キー) に依存しますが、これは ほど柔軟ではありません。そのため、前ページと次ページの機能しか実装できませんが、最初のページの機能は実装できません(無理に実装すると性能が落ちてしまいます)。

まずは

ドライバーの公式ページングメソッドを見てみましょう

クエリで取得したレコード数が多すぎて一度に返すと効率が非常に低く、メモリオーバーフローを引き起こす可能性がありますアプリケーション全体をクラッシュさせます。したがって、ドライバーは結果セットをページ分割し、データの適切なページを返します。

1. フェッチ サイズの設定

フェッチ サイズは、cassandra から一度に取得できるレコードの数を指します。つまり、クラスター インスタンスを作成するときに指定します。フェッチ サイズのデフォルト値。指定しない場合、デフォルト値は 5000 です

// At initialization:
Cluster cluster = Cluster.builder()
  .addContactPoint("127.0.0.1")
  .withQueryOptions(new QueryOptions().setFetchSize(2000))
  .build();

// Or at runtime:
cluster.getConfiguration().getQueryOptions().setFetchSize(2000);

さらに、フェッチ サイズはステートメントでも設定できます

Statement statement = new SimpleStatement("your query");
statement.setFetchSize(2000);

フェッチ サイズがステートメントに設定されている場合、フェッチステートメント サイズが機能します。それ以外の場合は、クラスター上のフェッチ サイズが機能します。

注: フェッチ サイズを設定しても、cassandra が常に正確な結果セット (フェッチ サイズと同じ) を返すとは限りません。フェッチ サイズよりわずかに大きいか小さい結果セットが返される場合があります。

2. 結果セットの反復

フェッチ サイズは、特定のページを反復すると、ドライバーがバックグラウンドで次のページのレコードを自動的にフェッチします。次の例のように、フェッチ サイズ = 20:

デフォルトでは、自動バックグラウンドフェッチは最後の瞬間、つまり特定のページのレコードが反復されたときに発生します。より適切な制御が必要な場合は、ResultSet

インターフェースが次のメソッドを提供します:

getAvailableWithoutFetching() and isFullyFetched() to check the current state;
fetchMoreResults() to force a page fetch;

以下は、特定の処理を繰り返した後に次のページを取得することによって引き起こされるパフォーマンスを回避するために、これらのメソッドを使用して次のページを事前に準備する方法です。ページダウン:

ResultSet rs = session.execute("your query");
for (Row row : rs) {
  if (rs.getAvailableWithoutFetching() == 100 && !rs.isFullyFetched())
    rs.fetchMoreResults(); // this is asynchronous
  // Process the row ...
  System.out.println(row);
}

3. ページング 状態を保存して再利用する

場合によっては、ページング状態を保存すると、後で復元するのに非常に役立ちます。結果のリストを表示して表示するステートレスな Web サービスがあると想像してください。次のページへのリンク ユーザーがこのリンクをクリックすると、前のページが停止した場所から反復を開始する必要がある点を除き、前とまったく同じクエリを実行する必要があります。次のページはここから始めることができます。

これを行うために、ドライバーは、次のページがフェッチされたときの結果セット内の位置を表す PagingState

オブジェクト を公開します。

ResultSet resultSet = session.execute("your query");
// iterate the result set...
PagingState pagingState = resultSet.getExecutionInfo().getPagingState();

// PagingState对象可以被序列化成字符串或字节数组
String string = pagingState.toString();
byte[] bytes = pagingState.toBytes();

PagingState オブジェクトのシリアル化されたコンテンツは永続的に保存でき、後で再利用するためにページング リクエストのパラメーターとして使用することもできます。

PagingState.fromBytes(byte[] bytes);
PagingState.fromString(String str);

ページング状態は再利用のみできることに注意してください。まったく同じステートメント (同じクエリ、同じパラメータ) を使用します。さらに、これは不透明な値であり、再利用できる状態値を保存するためにのみ使用されます。その内容を変更したり、別のステートメントで使用しようとすると、ドライバーはエラーをスローします。

具体的にコードを見てみましょう。次の例は、t

eacher テーブル内のすべてのレコードを走査するためのシミュレートされたページ ページング リクエストです。

import java.util.Map;

import com.datastax.driver.core.PagingState;

public interface ICassandraPage
{
  Map<String, Object> page(PagingState pagingState);

}
ステートメントの setPagingState(pagingState) メソッドを見てみましょう:


4.

ページング状態を保存すると、あるページから次のページへの移動が適切に機能するようになります (前のページも実装できます)。ただし、ページ 10 に直接ジャンプするなどのランダムなジャンプは満たされません。 10ページ目 前ページのページングステータス。オフセットクエリを必要とするこのような機能は、cassandra ではネイティブにサポートされていません。その理由は、オフセットクエリが非効率であるため (パフォーマンスはスキップされる行の数に線形反比例するため)、cassandra は公式にオフセットの使用を推奨していません。オフセット クエリを実装する必要がある場合は、クライアント側でシミュレートできます。ただし、パフォーマンスは依然として線形に反比例します。つまり、パフォーマンスが許容範囲内であれば、オフセットが大きいほどパフォーマンスは低下します。たとえば、各ページは 10 行表示され、最大 20 ページを表示できます。これは、20 ページ目を表示するときに最大 190 行を追加で取得する必要があることを意味しますが、これによってパフォーマンスが大幅に低下することはありません。 , データ量が大きくない場合でも、オフセット クエリをシミュレートすることは可能です。

たとえば、各ページに 10 レコードが表示され、フェッチ サイズが 50 であると仮定すると、ページ 12 (つまり、行 110 から 119) を要求します:

1 クエリが初めて実行されるとき、結果セット。 49 行目には、ページング ステータスを使用する必要はありません。

2. 最初のクエリで取得したページング ステータスを使用して、2 番目のクエリを実行します。 2 番目のクエリから、3 番目のクエリを実行します。結果セットには 100 ~ 149 行が含まれます。

4. 3 番目のクエリで取得した結果セットを使用して、最初に最初の 10 レコードを除外し、次に 10 レコードを読み取り、最後に残りのレコードを破棄して 10 レコードを読み取ります。 12ページに表示する必要があるレコード。

最適なバランスを実現するには、最適なフェッチ サイズを見つける必要があります。小さすぎるとバックグラウンドでのクエリが多くなり、大きすぎると大量の情報と不要な行が返されます。

また、cassandra 自体はオフセットクエリをサポートしていません。満足のいくパフォーマンスを前提とした場合、クライアント側のシミュレーション オフセットの実装は妥協にすぎません。公式の推奨事項は次のとおりです。

1. 想定が正しいことを確認するために、予想されるクエリ パターンを使用してコードをテストします。

2. 悪意のあるユーザーが大量のページをスキップするクエリをトリガーしないように、最大​​ページ数にハード制限を設定します。行

5 つ目、概要 Cassandra ではページングのサポートが制限されており、前のページと次のページの実装がより簡単です。オフセット クエリはサポートされていません。どうしても実装したい場合は、クライアント シミュレーションを使用できます。ただし、cassandra は一般にビッグ データの問題を解決するために使用され、データ量をオフセットするため、このシナリオは cassandra では使用しないことをお勧めします。クエリ内の値が大きすぎると、パフォーマンスを向上させることができません。私のプロジェクトでは、

index

repair は cassandra のページングを使用します。シナリオは次のとおりです。cassandra テーブルはセカンダリ インデックスを構築せず、elasticsearch を使用して cassandra テーブルのセカンダリ インデックスを実装します。これには整合性修復が含まれます。この問題では、cassandra のページングを使用して、cassandra の特定のテーブルを 1 つずつ検索し、elasticsearch に存在しない場合は、elasticsearch に追加します。矛盾している場合は、elasticsearch で修正します。 elasticsearch が cassandra のインデックス作成機能をどのように実装するかについては、次回のブログで具体的に説明するので、ここでは詳しく説明しません。 cassandra テーブル全体を走査する場合、テーブル内のデータ量が大きすぎて、一度に数億のデータをメモリにロードすることができないため、ページングが必要になります。

以上がJava が cassandra の高度な操作のページング例を実装 (写真)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。