2017-08-02 83 views
1

我们在我们的项目中使用NoSQL(Cassandra)。我们有一个表A(5000条记录),它是一个主表。我们还有另一个表B(2000年的记录)。表B有4列,表A有25列。我们公开了一个REST服务来获取B中的所有记录;像/ service/getB。这项服务将在响应,返回6列 -提高Cassandra和java集合的性能

{ 
    "result": [ 
     { 
      "col1FromB": "1B", 
      "col2FromB": "2B", 
      "col3FromB": "3B", 
      "col4FromB": "4B", 
      "col1FromA": "1A", 
      "col2FromA": "2A" 
     }, 
     { 
      "col1FromB": "11B", 
      "col2FromB": "12B", 
      "col3FromB": "13B", 
      "col4FromB": "14B", 
      "col1FromA": "11A", 
      "col2FromA": "12A" 
     } 
    ] 
} 

所以,有一个查找查询表A表B.每个项目这是我正在做它 -

//Get all from Table B (took 90 ms in Local and 30 ms in Test) 
    Select select = QueryBuilder.select().from("B"); 
    List<B> bList = cassandraOperations.select(select, B.class); 

    //Loop through bList and do a lookup using id in Table A (took 46000 ms (46 sec) in Local (horrible) and 6000 ms (6 sec) in Test) 
    For(B b: bList) { 
    Select select = QueryBuilder.select(“col1FromA”, “col2FromA”).from("A"); 
    select.where(QueryBuilder.eq(“id”, b.getId())); 
    A a = cassandraOperations.selectOne(select, A.class); 

    ---- 
    ---- 
    //Prepare final Pojo with a and b objects and add into a List<finalPjo> and return 
} 

因此,本地环境中的查找时间非常高,在测试环境中也不太好。我所使用的只是Java集合。

有没有什么办法让它更好,让我们在较短的时间内获得记录。

+0

是否有这些记录不能共位的原因? – dilsingi

回答

2
For(B b: bList) { 
Select select = QueryBuilder.select(“col1FromA”, “col2FromA”).from("A"); 
select.where(QueryBuilder.eq(“id”, b.getId())); 
A a = cassandraOperations.selectOne(select, A.class); 

该代码执行在每个迭代阻塞请求cassandraOperations.selectOne,它意味着每个下一迭代必须等待前一个。所有2000个请求将被逐个执行并且很长一段时间。

为了避免这种情况,使用异步方式获取循环中的记录(就像我看到的,您使用的是Spring并且selectOne可以被返回ResultSetFuture的selectOneAsynchronously取代,将这些期货保存在某个列表中并使用它来检索记录当所有请求被发送时)。

+0

太好了。谢谢。我在FutureCallback中使用了session.executeAsync(),现在结果仅在583 ms内出现。 – Saurabh

2

Cassandra根据分区键在其节点上分配数据。它可以确保分区内的所有行(具有相同分区键的一组行)位于同一节点上,为全分区或部分分区快速创建SELECT语句。

如果您有一个查询拉下多个分区,则每个分区可能位于不同的节点上,导致选择过程中的网络流量会导致性能下降。通过添加第二个表格,您正在解决问题。

在卡桑德拉你应该看看你的查询,然后如果可能的话,每个查询创建一个表。当您拥抱数据重复并避免连接时,Cassandra数据模型可提升性能。

因此,我将创建一个新表,将查询数据预加入到名为C的表中。当您在A中编写数据时,您会将它写入A和C,并且当您向B写入数据时会将其写入B和C.如果可能,您希望将要在同一分区中一起查询的数据。如果每次调用端点时都要下拉整个数据集,则可能需要考虑对表中的所有数据使用单个分区键(因为您的数据量相对较少),这将保证在何时您读取表格时,整个读取将从单个节点开始。

我想你在你的本地机器上看到很好的性能,因为你的查询没有打到网络上。