2015-02-27 15 views
5

Tôi cần truy vấn một trong các bảng trong Cassandra bằng trình điều khiển Java Datastax. Dưới đây là đoạn code tôi có mà hoạt động tốt -Làm thế nào để sử dụng câu lệnh chuẩn bị hiệu quả bằng trình điều khiển java datastax trong Cassandra?

public class TestCassandra { 

     private Session session = null; 
     private Cluster cluster = null; 

     private static class ConnectionHolder { 
      static final TestCassandra connection = new TestCassandra(); 
     } 

     public static TestCassandra getInstance() { 
      return ConnectionHolder.connection; 
     } 

     private TestCassandra() { 
      Builder builder = Cluster.builder(); 
      builder.addContactPoints("127.0.0.1"); 

      PoolingOptions opts = new PoolingOptions(); 
      opts.setCoreConnectionsPerHost(HostDistance.LOCAL, opts.getCoreConnectionsPerHost(HostDistance.LOCAL)); 

      cluster = builder.withRetryPolicy(DowngradingConsistencyRetryPolicy.INSTANCE).withPoolingOptions(opts) 
        .withLoadBalancingPolicy(new TokenAwarePolicy(new DCAwareRoundRobinPolicy("DC2"))) 
        .withReconnectionPolicy(new ConstantReconnectionPolicy(100L)) 
        .build(); 
      session = cluster.connect(); 
     } 

    private Set<String> getRandomUsers() { 
     Set<String> userList = new HashSet<String>(); 

     for (int table = 0; table < 14; table++) { 
      String sql = "select * from testkeyspace.test_table_" + table + ";"; 

      try { 
       SimpleStatement query = new SimpleStatement(sql); 
       query.setConsistencyLevel(ConsistencyLevel.QUORUM); 
       ResultSet res = session.execute(query); 

       Iterator<Row> rows = res.iterator(); 
       while (rows.hasNext()) { 
        Row r = rows.next(); 

        String user_id = r.getString("user_id"); 
        userList.add(user_id); 
       } 
      } catch (Exception e) { 
       System.out.println("error= " + ExceptionUtils.getStackTrace(e)); 
      } 
     } 

     return userList; 
    } 
} 

Tôi đang sử dụng trên lớp như thế này trong ứng dụng chính của tôi -

TestCassandra.getInstance().getRandomUsers(); 

Có cách nào tôi có thể sử dụng PreparedStatement trong getRandomUsers một cách hiệu quả? Tôi đoán tôi cần phải chắc chắn rằng tôi đang tạo ra PreparedStatement chỉ một lần thay vì tạo ra nó nhiều lần. Thiết kế tốt nhất cho điều đó trong kiến ​​trúc hiện tại của tôi là gì và tôi có thể sử dụng nó như thế nào?

Trả lời

11

Bạn có thể tạo bộ nhớ cache (đây là một ví dụ khá cơ bản để cung cấp cho bạn một ý tưởng) về các câu lệnh bạn cần. Cho phép bắt đầu bằng cách tạo lớp sẽ được sử dụng làm bộ đệm.

private class StatementCache { 
    Map<String, PreparedStatement> statementCache = new HashMap<>(); 
    public BoundStatement getStatement(String cql) { 
     PreparedStatement ps = statementCache.get(cql); 
     // no statement cached, create one and cache it now. 
     if (ps == null) { 
      ps = session.prepare(cql); 
      statementCache.put(cql, ps); 
     } 
     return ps.bind(); 
    } 
} 

Sau đó, thêm một ví dụ để singleton của bạn:

public class TestCassandra { 
    private Session session = null; 
    private Cluster cluster = null; 
    private StatementCache psCache = new StatementCache(); 
    // rest of class... 

Và cuối cùng sử dụng bộ nhớ cache từ chức năng của bạn:

private Set<String> getRandomUsers(PreparedStatement ps) { 
// lots of code.  
     try { 
      SimpleStatement query = new SimpleStatement(sql); 
      query.setConsistencyLevel(ConsistencyLevel.QUORUM); 
      // abstract the handling of the cache to it's own class. 
      // this will need some work to make sure it's thread safe 
      // as currently it's not. 
      ResultSet res = session.execute(psCache.getStatement(sql)); 
+0

Đây là tuyệt vời. Tôi hiểu bây giờ những gì chúng ta cần làm như vậy về cơ bản chúng ta cần tạo một lớp an toàn đơn lẻ trong đó chúng ta cần điền tất cả các câu lệnh mới vào bộ nhớ đệm và sau đó sử dụng các câu lệnh đó từ trình lấy. Đúng? – john

+0

@david Trên thực tế, tôi sẽ có một bộ nhớ cache cho mỗi n đề (bạn cần phải làm việc ra khi bản đồ trở nên quá đắt, do đó có nghĩa là một bộ nhớ cache mới được yêu cầu) Hãy thử một cái gì đó giống như 1 bộ nhớ cache cho mỗi 5 chủ đề. Thậm chí có thể mỗi thread phải có bộ nhớ đệm ps riêng của nó (dựa trên bao nhiêu câu lệnh trong đó, càng có nhiều câu lệnh, bạn càng cần ít bộ đệm). –

+0

Tôi không hiểu nhận xét cuối cùng của bạn, bộ nhớ cache cho mỗi chủ đề n? Làm thế nào chúng ta có thể làm điều đó? – john

Các vấn đề liên quan