2017-01-16 4 views
0
public class CassandraData { 

    private static Session cassandraSession = null; 
    private static Cluster cluster = null; 

    CassandraData() { 
     // Do nothing 
    } 

    static { 

     if (cassandraSession == null) { 
      QueryOptions qs = new QueryOptions().setConsistencyLevel(ConsistencyLevel.LOCAL_QUORUM); 

      PoolingOptions poolingOptions = new PoolingOptions(); 
      poolingOptions.setConnectionsPerHost(HostDistance.LOCAL, 2, 10).setConnectionsPerHost(HostDistance.REMOTE, 
        10, 20); 

      SocketOptions socketOptions = new SocketOptions(); 
      socketOptions.setConnectTimeoutMillis(60000); 
      socketOptions.setReadTimeoutMillis(600000); 

      cluster = Cluster.builder().addContactPoints("***.***.***.***").withQueryOptions(qs) 
        .withPoolingOptions(poolingOptions).withSocketOptions(socketOptions) 
        .withLoadBalancingPolicy(new RoundRobinPolicy()).build(); 

      cassandraSession = cluster.connect("sf"); 
     } 
     // monitor(); 
    } 

    public Session getSession() { 

     return cassandraSession; 

    } 
    public Data findOne(PK pk) { 

     Data mc = null; 

     Statement statement = new SimpleStatement(getCqlString(pk)); 

     ResultSet results = getSession().execute(statement); 


     List<Row> rowList = results.all(); 

     if (rowList != null && rowList.size() > 0) { 
      Row row = rowList.get(0); 
      mc = EntityConvert.ConvertToMC(row); 
     } 

     return mc; 
    } 
} 
    private String getCqlString(PK pk) { 
    String cqlStr = "select * from table" + " where E='" 
      + pk.E + "' and D=" + pk.D + " and M=" 
      + pk.M; 
    return cqlStr; 
} 

サーブレット:私のサーブレットアプリケーションで異なるクライアントからの複数の同時要求を処理する方法は?

public class OneServlet extends HttpServlet { 
    private static final long serialVersionUID = 1L; 
    private static final Logger logger = LogManager.getLogger(OneServlet.class); 
    /** 
    * @see HttpServlet#HttpServlet() 
    */ 
    public OneServlet() { 
     super(); 
    } 

    /** 
    * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse 
    *  response) 
    */ 
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
      throws ServletException, IOException { 

     response.setContentType("application/json; charset=utf-8"); 
     response.setCharacterEncoding("UTF-8"); 
     long start = System.currentTimeMillis(); 

     PK pk = ValidData.getOnePk(); 

     CassandraData dataAccess = new CassandraData(); 
     long end2 = System.currentTimeMillis(); 
     Data mc = dataAccess.findOne(pk); 

     String rsJson = JSON.toJSONString(mc); 
     long end = System.currentTimeMillis(); 

     logger.info("Create CassandraData:" + (end2 - start)/1000.0 +"s elapsed." + "Show One:" + (end - start)/1000.0 +"s elapsed."); 

     OutputStream out = response.getOutputStream(); 
     out.write(rsJson.getBytes("UTF-8")); 
     out.flush(); 
    } 

    /** 
    * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse 
    *  response) 
    */ 
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
      throws ServletException, IOException { 
     doGet(request, response); 
    } 

} 

、私はカサンドラにアクセスするには上記のコードを使用したいと思います。 ユーザーがサーブレットにアクセスすると、データをフェッチするのに平均0.1秒かかります。 複数のユーザー(60など)がサーブレットにアクセスすると、各リクエストは平均20秒間でデータを取得します。
複数のユーザーがいるため、このコードを変更して要求時間を短縮する方法を教えてください。

+0

* 60などの複数のユーザーがサーブレットにアクセスすると、各リクエストに平均20秒かかる*その結論はどうでしたか? – shmosel

+1

私はJmeterを使ってこのサーブレットをテストしました。ログファイルでクエリ時間を確認しました。 – niaomingjian

答えて

0
private Select getCqlSelect(PK pk) { 

    Select select = QueryBuilder.select().from("table"); 
    select.where(QueryBuilder.eq("E", pk.E)) 
      .and(QueryBuilder.eq("D", pk.D)) 
      .and(QueryBuilder.eq("M", pk.M)).limit(1) 

    return select; 
} 

私はPrepared statementsを使用し、20回以上パフォーマンスを改善しました。プリペアドステートメントを使用して、

Prepared statements

は、複数の利点を提供します。準備されたステートメントは解析され、Cassandraノードで準備され、将来の実行の準備が整います。パラメータをバインドするときには、これらの(およびクエリID)だけがワイヤを介して送信されます。これらのパフォーマンスの向上は、同じクエリを(異なるパラメータを使用して)繰り返して使用すると増加します。

プリペアドステートメントを使用するためのルールは簡単です。準備を1回行い、複数回バインドして実行します。

関連する問題