cassandra - cassandra 中的时间序列建模(带有开始和结束日期)

标签 cassandra cql cql3 cassandra-2.1

我正在进行时间序列数据建模,其中有事件的开始日期和结束日期。我需要查询该数据模型,如下所示:

Select * from tablename where startdate>'2012-08-09' and enddate<'2012-09-09'

我在 cql where clause 上引用了以下链接但我无法实现这一点。有办法做到吗?我还可以更改数据模型或任何 cql 调整。我使用的是 Cassandra 2.1。

最佳答案

我必须在以前的职位之一中解决类似的问题。这是您可以实现这一目标的一种方法...

I need to make query on that data model like the following: Select * from tablename where startdate>'2012-08-09' and enddate<'2012-09-09'.

有两个建模问题导致此查询无法正常工作。首先,要运行范围查询,您首先需要使用分区键限制查询。对于时间序列数据,最好的想法是创建一个称为时间桶的东西。在本示例中,我将按月对数据进行分区,分区键名为 monthbucket .

另一个问题是您只能对单个列/键值运行范围查询。当您想按开始日期和结束日期进行查询时,这会出现问题。一种解决方案是将表中的每一行存储两次,并创建一个附加的聚集键来保存该行是起始行还是结束行的值。我将这个专栏称为beginend .

根据这些注释,我将创建一个如下所示的表格:

CREATE TABLE events (
  monthBucket TEXT,
  eventDate TIMESTAMP,
  beginEnd TEXT,
  eventid UUID,
  eventName TEXT,
  PRIMARY KEY (monthBucket, eventDate, beginEnd, eventid))
WITH CLUSTERING ORDER BY (eventDate DESC, beginEnd ASC, eventid ASC);
  • 对于大多数时间序列实现,您往往更关心最新的数据。为此,我聚集在 eventDate按降序排列。
  • 此外,由于您可能会同时启动多个事件,因此您还应该添加一个额外的集群键以确保唯一性(在本例中为 eventid)。

插入一些行后,让我们按 2015 年 9 月的分区键进行查询:

aploetz@cqlsh:stackoverflow> SELECT * FROM events WHERE monthbucket='201509';

 monthbucket | eventdate                | beginend | eventid                              | eventname
-------------+--------------------------+----------+--------------------------------------+------------------------
      201509 | 2015-09-25 23:59:59+0000 |        E | a223ad16-2afd-4213-bee3-08a2c4dd63e6 |             Hobbit Day
      201509 | 2015-09-25 00:00:00+0000 |        B | a223ad16-2afd-4213-bee3-08a2c4dd63e6 |             Hobbit Day
      201509 | 2015-09-24 23:59:59+0000 |        E | 9cd6a265-6c60-4537-9ea9-b57e7c152db9 |       Cassandra Summit
      201509 | 2015-09-22 00:00:00+0000 |        B | 9cd6a265-6c60-4537-9ea9-b57e7c152db9 |       Cassandra Summit
      201509 | 2015-09-19 23:59:59+0000 |        E | b9fe9668-cef2-464e-beb4-d4f985ef9c47 | Talk Like a Pirate Day
      201509 | 2015-09-19 00:00:00+0000 |        B | b9fe9668-cef2-464e-beb4-d4f985ef9c47 | Talk Like a Pirate Day

(6 rows)

与您的示例类似,假设我要查询 9 月 18 日到 9 月 24 日之间的事件:

aploetz@cqlsh:stackoverflow> SELECT * FROM events WHERE monthbucket='201509' AND eventdate > '2015-09-18' AND eventdate < '2015-09-24';

 monthbucket | eventdate                | beginend | eventid                              | eventname
-------------+--------------------------+----------+--------------------------------------+------------------------
      201509 | 2015-09-22 00:00:00+0000 |        B | 9cd6a265-6c60-4537-9ea9-b57e7c152db9 |       Cassandra Summit
      201509 | 2015-09-19 23:59:59+0000 |        E | b9fe9668-cef2-464e-beb4-d4f985ef9c47 | Talk Like a Pirate Day
      201509 | 2015-09-19 00:00:00+0000 |        B | b9fe9668-cef2-464e-beb4-d4f985ef9c47 | Talk Like a Pirate Day

(3 rows)

如您所见,我应该得到三行:“Talk Like A Pirate Day”的开始行和结束行以及 2015 Cassandra Summit 的开始行。

与所有数据建模方法一样,需要进行权衡。在本例中,要为两个日期的查询建模,需要权衡的是您必须复制行。当然,为了能够进行范围查询,您必须决定一个好的分区键 ( monthbucket ),它提供相关数据和所需的查询灵 active 。无论如何,请尝试一下,看看是否可以使其适合您的用例。

编辑以回答问题:

  1. If I want to find all events between 25th Nov,2015 to 25th Nov,2016. How that could be possible ?

这就是您需要找出适合您的应用程序的最佳时间段的地方。考虑一下最常见的查询,并据此进行建模。现在您不想在单行(桶)中存储太多内容,因为这会破坏您的数据分布。因此,请尝试在查询灵 active 和数据分布之间找到一个平衡点。

在这种特殊情况下,monthBucket您必须对每个月执行一次查询。我设计此解决方案的应用程序从未同时查看一整年的事件值(value)。如果这是您需要支持的查询模式,那么您需要让您的时间范围更大一些。

  • Is there any way to remove this duplicate row from the result set only?

  • 不。需要在应用程序级别处理/忽略重复项。 Cassandra CQL 确实有 DISTINCT 关键字,但它仅对分区键起作用。

  • Can this type of merging be done at the Cassandra level ?

  • 不,Cassandra 没有办法将表连接在一起。应用程序端连接是可能的,但性能不佳,并且在技术上是一种反模式。

    在应用程序端处理数据(无论是连接还是过滤)通常不是一个好主意。但关键是适度。如果您查询 20 个事件并且必须忽略其中一些事件的重复事件,那也没什么大不了的。但查询 20,000,000 个事件并应用该数量的应用程序端流程根本无法很好地扩展。同样,您必须在此处查看可用选项,并决定哪些选项适合您的应用程序。

    关于cassandra - cassandra 中的时间序列建模(带有开始和结束日期),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33876872/

    相关文章:

    scala - 如何定义 Scala 预定义的列名

    cassandra - 无法在集群模式下使用 bundle.zip 连接 EMR 中的 Cassandra

    cassandra - 如何在 cassandra 中使用 CQL3 创建计数器列族

    cassandra - 在 Cassandra 中管理多对多关系

    java - DataStax 访问器 bean 作为绑定(bind)参数

    javascript - 如何使用 node.js 关闭与 cassandra 的连接

    cassandra - 主键相关的CQL3查询排序时的情况和错误

    cassandra - Cassandra CQL 中的 Where 和 Order By 条款

    csv - 如何将带有计数器列的 CSV 文件加载到 Cassandra CQL3 表中

    考虑到 Cassandra 的 MySQL 应用程序