用于标准SELECT / FROM / WHERE / IN查询的Cassandra Schema

时间:2016-05-07 04:50:14

标签: cassandra

对Cassandra来说很新 - 我的数据看起来像这样:

<geohash text, category int, payload text>

我要运行的查询是:

SELECT category, payload FROM table WHERE geohash IN (list of 9 geohashes)

在这种情况下最好的架构是什么?

我知道我可以简单地将我的geohash作为主键并完成它,但是有更好的方法吗?

定义PRIMARY KEY (geohash, category, payload)有什么好处?

2 个答案:

答案 0 :(得分:0)

这取决于每行的数据大小(geohash文本,类别int,有效负载文本)。如果您的有效负载大小未达到数十Mb,那么您可能希望使用人工 bucketId int 将更多 geohash 值放入同一分区,因此您的查询可以在服务器上执行。架构看起来像这样 geohash text,bucketId int,category int,payload text 其中分区键是goehash和bucketId。 建议使用一个相当大的分区&lt; = 100 Mb,这样您就不必查找太多分区。有更多内容here

如果您在(geohash, category, payload)上有主键,则可以按升序顺序在category and payload上对数据进行排序。

答案 1 :(得分:0)

所以基于查询,听起来你正在考虑一个如下所示的CQL模式:

CREATE TABLE geohash_data (
  geohash text,
  category int,
  data text,
  PRIMARY KEY (geohash)
);

在Cassandra中,PRIMARY KEY中的第一个(仅在此情况下)列是分区键。分区密钥用于在集群周围分发数据。因此,当您执行SELECT ... IN ()查询时,您基本上是在查询9个不同分区中的数据,这取决于您的群集的大小,复制因子以及用于执行查询的一致性级别,最终查询至少 9台服务器(可能还有更多)。为什么这很重要?

  1. 延迟:我们的查询中涉及的分区(以及副本/服务器)越多,速度慢的服务器就越有可能对数据返回的速度产生负面影响。
  2. 可用性:我们的查询中涉及的分区(以及副本/服务器)越多,单个服务器发生故障的可能性就越大,使得查询无法满足。
  3. 这两个都是糟糕的情况(正如Toan在他的回答和他提供的链接中正确指出的那样),我们尝试在Cassandra中使用数据模型,这样我们的查询就会像在很少的分区(以及复制品/服务器)上一样可能。这对你的场景意味着什么?在不知道所有细节的情况下,很难肯定地说,但是让我对你的场景做一些猜测,并举例说明我将如何解决它。

    听起来你可能已经提前知道了可能的geohash值列表(也许它们处于预定义网格的某个规则间隔的间隔)。这听起来也许你正在查询9个geohash值,因为你正在进行某种“接近”搜索,你试图在给定点周围的每个方向上获取9个地理数据的数据。

    如果是这种情况,诀窍可能是在写入时将数据非规范化为优化用于读取的数据模型。例如,这样的架构:

    CREATE TABLE geohash_data (
      geohash text,
      data_geohash text,
      category int,
      data text,
      PRIMARY KEY (geohash, data_geohash)
    );
    

    当您INSERT数据点时,您将计算您希望数据应显示在结果中的周围区域的地理位置。对于您计算的每个地理位置,然后INSERT数据多次。因此,geohash的值是您希望它显示在查询结果中的计算值,而data_geohash的值是您要插入的数据的实际值。因此,对于给定的geohash,您的分区中有多个(最多9个)行,表示周围地理数据的数据。

    这意味着您的SELECT查询现在不必执行IN并点击多个分区。您只需查询WHERE geohash = ?以查找要搜索的点。