2017-11-10 5 views
0

私の現在のプロジェクトでは、データを頻繁に取得するためにCassandra Dbを使用しています。毎秒少なくとも30 Dbのリクエストが発生します。要求ごとに、Dbからフェッチするために少なくとも40000の行が必要です。以下は現在のコードですが、このメソッドはハッシュマップを返します。カサンドラ例外

public Map<String,String> loadObject(ArrayList<Integer> tradigAccountList){ 

     com.datastax.driver.core.Session session; 
     Map<String,String> orderListMap = new HashMap<>(); 
     List<ResultSetFuture> futures = new ArrayList<>(); 
     List<ListenableFuture<ResultSet>> Future; 

     try { 
      session =jdbcUtils.getCassandraSession(); 
      PreparedStatement statement = jdbcUtils.getCassandraPS(CassandraPS.LOAD_ORDER_LIST); 

      for (Integer tradingAccount:tradigAccountList){ 
       futures.add(session.executeAsync(statement.bind(tradingAccount).setFetchSize(3000))); 
      } 
      Future = Futures.inCompletionOrder(futures); 

      for (ListenableFuture<ResultSet> future : Future){ 
       for (Row row: future.get()){ 
        orderListMap.put(row.getString("cliordid"), row.getString("ordermsg")); 
       } 
      } 

     }catch (Exception e){ 
     }finally { 
     } 
     return orderListMap; 
    } 

マイデータ要求クエリは、このようなもので、 は "tradacntid = omsks_v1.ordersStringV1 FROM cliordid、ordermsgを選択?"。 マイカサンドラクラスタは、32同時読み取りとの2つのノードがあり、

CREATE TABLE omsks_v1.ordersstringv1_copy1 (
    tradacntid int, 
    cliordid text, 
    ordermsg text, 
    PRIMARY KEY (tradacntid, cliordid) 
) WITH bloom_filter_fp_chance = 0.01 
AND comment = '' 
AND dclocal_read_repair_chance = 0.1 
AND default_time_to_live = 0 
AND gc_grace_seconds = 864000 
AND max_index_interval = 2048 
AND memtable_flush_period_in_ms = 0 
AND min_index_interval = 128 
AND read_repair_chance = 0.0 
AND speculative_retry = '99.0PERCENTILE' 
AND caching = { 
    'keys' : 'ALL', 
    'rows_per_partition' : 'NONE' 
} 
AND compression = { 
    'sstable_compression' : 'LZ4Compressor' 
} 
AND compaction = { 
    'class' : 'SizeTieredCompactionStrategy' 
}; 

私の問題は、これらすべての要求

答えて

2
を処理するために私のコードを最適化する方法、カサンドラのタイムアウト例外を取得しているに従うよう、それぞれ、私のDBスキーマのためのスレッドを書きます

その例外のスニペット(読み取り/書き込み例外)を添付する方が良いでしょう。私はあなたがタイムアウトを読み込んでいると仮定します。 1回のリクエストで大きなデータセットをフェッチしようとしています。 Dbの

から

をフェッチするために必要な各リクエスト少なくとも40000行については

あなたが大規模なレコードを持っているし、結果セットが大きすぎる場合には結果がで述べた制限時間内に戻すことができないならば、それは例外をスローしますCassandra.yaml。

read_request_timeout_in_ms

あなたはタイムアウトを増やすことができますが、これは良いオプションではありません。それは問題を解決するかもしれません(例外を投げることはできませんが、結果を返すためにはもっと時間がかかるでしょう)。

解決策:大きなデータセットの場合、制限付き手動ページネーション(範囲クエリ)を使用して結果を得ることができます。

SELECT cliordid、omsks_v1.ordersStringV1 tradacntid> = FROM ordermsg?とcliordid>?限界?

または使用範囲クエリ

SELECT cliordid、tradacntid = omsks_v1.ordersStringV1 FROM ordermsg?とcliordid> =?そして、クリオードイド< =?

これは、結果セット全体をフェッチするよりもはるかに高速です。

フェッチサイズを小さくすることもできます。それは全体の結果セットを返しますが。

public Statement setFetchSize(int fetchSize)例外がスローされたかどうかを確認します。

setFetchSizeはページサイズを制御しますが、結果セットで返される最大行数は にはなりません。注意する

もう一つのポイント:

tradigAccountListのサイズは何ですか?

一度にリクエストが多すぎるとタイムアウトにつながる可能性があります。大規模なtradigAccountListと多数の読み取り要求が一度に実行されます(要求のロードバランシングはCassandraによって処理され、処理できる要求の数はクラスタのサイズやその他の要因によって異なります)。

いくつかの関連リンク:

Cassandra read timeout

NoHostAvailableException With Cassandra & DataStax Java Driver If Large ResultSet

Cassandra .setFetchSize() on statement is not honoured

+0

これは素晴らしかったです。いい説明。どうもありがとうございます。 – IsharaD

+0

聞いてよかったです。 :)あなたが問題を解決するのに役立ったら、答えを受け入れてください。 – Chaity

+1

確か:P ...これは素晴らしい説明です。ありがとうございました。 – IsharaD

関連する問題