2016-07-29 13 views
0

私は100万行のデータの読み込みをテストするJavaクライアントを作成しています。私は列の地図のキーからデータをフィルタリングしています。コードはデータを正しく作成して挿入していますが、データを読み取ることはできません。私のコード:Apache Cassandraのデータ読み込みでReadFailureExceptionが発生する

public class MillionMapTest { 
    private Cluster cluster; 
    private Session session; 

    public void connect(String node) { 
     cluster = Cluster.builder().addContactPoint(node).build(); 
     session = cluster.connect(); 
    } 

    public void createSchema() { 
     session.execute("CREATE KEYSPACE xx WITH replication " + 
       "= {'class':'SimpleStrategy', 'replication_factor':3};"); 
     session.execute(
       "CREATE TABLE xx.events (" + 
         "log_time_local timeuuid," + 
         "username text," + 
         "log_type text," + 
         "log_time timestamp," + 
         "device_category text," + 
         "log text," + 
         "priority INT," + 
         "client_ip text," + 
         "backend_app text," + 
         "location_details map<text, text>," + 
         "device_details map<text, text>," + 
         "extra_info Blob," + 
         "PRIMARY KEY (log_time_local, username, log_type)" + 
       ");"); 
     session.execute("CREATE INDEX devicekeys ON xx.events(KEYS(device_details));"); 
    } 

    public void loadData() { 
     PreparedStatement statement = session.prepare(
       "INSERT INTO xx.events VALUES (now(), ?, ?, toTimestamp(now()), ?, ?, ?, ?, ?, ?, ?, ?);"); 
     BoundStatement boundStatement = new BoundStatement(statement); 
     for (int i=0; i<1000000; i++) { 
      Map<String, String> tags = new HashMap<>(); 
      tags.put("os", "ios"); 
      tags.put("category", "tab"); 
      tags.put("dev_num", "12ABF847CA"); 
      if (i % 100 == 0) tags.put("category", "mobile"); 
      session.execute(boundStatement.bind("name_"+i,"type_"+i, "cat_"+i, "log_"+i, i, "ip_"+i, "app_"+i, null, tags, null)); 
     } 
    } 

    public void querySchema() { 
     ResultSet results = session.execute("SELECT * FROM xx.events WHERE device_details['category'] = 'mobile' ALLOW FILTERING;");  
    } 

    public static void main(String[] args) { 
     MillionMapTest client = new MillionMapTest(); 
     client.connect("localhost"); 
     client.createSchema(); 
     client.loadData(); 
     client.querySchema(); 
     session.close(); 
     cluster.close(); 
    } 
} 

エラーはcom.datastax.driver.core.exceptions.ReadFailureException: Cassandra failure during read query at consistency LOCAL_ONE (1 responses were required but only 0 replica responded, 1 failed)です。

cqlshを実行しているときにクエリが正しく実行されていて、このコードがいくつかのデータで機能していました。しかしそれは百万と働いていません。このエラーの原因は何ですか?どのように修正しますか?

+0

このクエリをcqlshから実行できましたか? – Rocherlee

+0

@Rocherleeはい、Cassandraサーバーのcqlshから動作します。 – khateeb

答えて

0

問題は「セカンダリインデックス」のようです。彼らはC *の中で最もパフォーマンスの良いものではなく、独自の注意書きが付いています。セカンダリインデックスに関する問題については、C *でのいくつかの良いドキュメントがあります。このlink。あなたはセカンダリインデックスを持っていますし、マップデータ型でもそうです。これは遅いでしょう。あなたがReadTimeoutの代わりにReadFailureExceptionを取得するという事実は、あなたがそれを照会するときに最新ではないインデックスと関係があるかもしれません(私はあまり確かではありませんが、ReadFailureExceptionがスローされる場合があるissueを参照してください)。

スキーマを改造したり、テーブルを非正規化する必要があり、セカンダリインデックスに頼るのではなく、キー検索を行う方法があると思います。

+0

私はこのクエリをcqlsh上で実行しようとしました。私は少しのデータでそれを試してみました。 2番目のリンクの問題は、バージョン3.1で解決されました。私はバージョン3.7を使用しています – khateeb

関連する問題