【问题标题】:Improve performance in Cassandra and java collections提高 Cassandra 和 java 集合的性能
【发布时间】:2017-08-03 18:08:10
【问题描述】:

我们在项目中使用 NoSQL (Cassandra)。我们有一个表 A(5000 条记录),它是一个主表。我们还有另一个表 B(2000 条记录)。表 B 有 4 列,表 A 有 25 列。我们公开了一个 REST 服务来从 B 获取所有记录;像 /service/getB。该服务将返回 6 列作为响应 –

{
    "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"
        }
    ]
}

所以,对于表 B 中的每个项目,都有一个对表 A 的查找查询。这就是我的做法 -

    //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 集合。

有什么方法可以让它变得更好,以便我们在更短的时间内获得记录。

【问题讨论】:

  • 这些记录不能共存的原因是什么?

标签: java collections cassandra nosql


【解决方案1】:
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,将这些期货保存在某个列表中,并使用它来检索发送所有请求时的记录)。

【讨论】:

  • 太棒了。谢谢。我将 session.executeAsync() 与 FutureCallback 一起使用,现在结果仅在 583 毫秒内出现。
【解决方案2】:

Cassandra 根据分区键将其数据分布在其节点上。它保证一个分区内的所有行(一组具有相同分区键的行)都在同一个节点上,这使得完整或部分分区的 SELECT 语句非常快。

如果您有一个下拉多个分区的查询,那么每个分区可能位于不同的节点上,从而在选择期间导致网络流量,这会降低您的性能。添加第二个表会使问题更加复杂。

在 Cassandra 中,您应该查看您的查询,然后尽可能为每个查询创建一个表。当您接受数据重复并避免连接时,Cassandra 数据模型有助于提高性能。

所以我会创建一个新表,将查询的数据预先连接到一个名为 C 的表中。当您将数据写入 A 时,您会将其同时写入 A 和 C,而当您将数据写入 B 时,您将将其写入 B 和 C。如果可能,您希望将要一起查询的数据放在同一个分区中。如果您在每次调用端点时都拉下完整的数据集,您可能需要考虑为表中的所有数据使用单个分区键(因为您的数据量相对较少),这将保证当您读取表,整个读取将来自单个节点。

我想您在本地计算机上看到了良好的性能,因为您的查询没有访问网络。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-04
    • 2015-12-16
    • 2012-06-17
    • 1970-01-01
    • 2014-05-15
    • 2012-02-02
    • 2019-11-11
    • 2017-06-15
    相关资源
    最近更新 更多