Cassandra帮助:使用复合键的任一部分支持快速查询

时间:2017-01-10 22:27:15

标签: cassandra

我是Cassandra的新手,并且不清楚存储我的数据以支持我的查询需求的最佳方式。我希望能够根据任一键或两者来搜索我的数据。为了说明,我将使用此表示例:

CREATE TABLE temperature (
weatherstation_id text,
event_time timestamp,
temperature text,
PRIMARY KEY (weatherstation_id,event_time)
);

这适用于像这两样的查询:

SELECT event_time,temperature FROM temperature WHERE weatherstation_id=’1234ABCD’;

...因为它直接进入单个分区

SELECT temperature FROM temperature WHERE weatherstation_id=’1234ABCD’ AND event_time > ’2013-04-03 07:01:00′ AND event_time < ’2013-04-03 07:04:00′;

...因为它仍然会进入单个分区并从有序列表中获得一片结果

但是如果我想这样的话会怎么样:

SELECT temperature FROM temperature WHERE event_time > ’2013-04-03 07:01:00′ AND event_time < ’2013-04-03 07:04:00′;

如果我的理解对我有用,那么这不会有效率,因为它需要迭代每个分区吗?不仅如此,它还需要按时间顺序恢复。

最好的解决方案是什么?

2 个答案:

答案 0 :(得分:3)

其实你的查询:

SELECT temperature FROM temperature WHERE event_time > ’2013-04-03 07:01:00′ AND event_time < ’2013-04-03 07:04:00′;

将无法运行。 Cassandra确实必须知道哪个分区必须查找您请求的数据,即您始终必须指定分区键。

为了有效地检索此查询的数据,您还需要围绕该查询建模数据:

CREATE TABLE temperature_by_time (
    granularity timestamp,
    event_time timestamp,
    weatherstation_id text,
    temperature text,
    PRIMARY KEY (granularity, event_time)    
);

我在这里添加了字段granularity。此字段允许您控制分区的宽度。一个好的经验法则是每个分区最多有大约10k-100k行。根据您写入此表的速度,您可以采用不同的方式进行操作。例子:

<案例1
  • 您有10个传感器
  • 每个传感器每秒给出1个小节

在这种情况下,你将写出10个/秒,36k /小时的措施。一个好的粒度值就像yyyy-mm-dd HH:00:00,就是你每小时对数据进行分区:

INSERT INTO temperature_by_time (granularity, event_time, ..) VALUES ('2017-01-11 10:00:00', '2017-01-11 10:05:01', ...);
INSERT INTO temperature_by_time (granularity, event_time, ..) VALUES ('2017-01-11 10:00:00', '2017-01-11 10:19:15', ...);
INSERT INTO temperature_by_time (granularity, event_time, ..) VALUES ('2017-01-11 10:00:00', '2017-01-11 10:39:35', ...);
INSERT INTO temperature_by_time (granularity, event_time, ..) VALUES ('2017-01-11 10:00:00', '2017-01-11 10:59:49', ...);

SELECT * FROM temperature_by_time WHERE granularity='2017-01-11 10:00:00';
SELECT * FROM temperature_by_time WHERE granularity='2017-01-11 10:00:00' AND event_time >= '2017-01-1 10:30:00' AND event_time < '2017-01-1 11:00:00';

即您将event_time“截断”为整数小时,并且只能以小时/小时为单位获取记录。

<案例2
  • 您有100个传感器
  • 每个传感器每秒给出1个小节

在这种情况下,你将每秒写100个测量值,每小时360k测量值。然后,良好的粒度值类似于yyyy-mm-dd HH:00:00yyyy-mm-dd HH:15:00yyyy-mm-dd HH:30:00yyyy-mm-dd HH:45:00,即您将数据分为四小时:

INSERT INTO temperature_by_time (granularity, event_time, ..) VALUES ('2017-01-11 10:00:00', '2017-01-11 10:05:01', ...);
INSERT INTO temperature_by_time (granularity, event_time, ..) VALUES ('2017-01-11 10:15:00', '2017-01-11 10:19:15', ...);
INSERT INTO temperature_by_time (granularity, event_time, ..) VALUES ('2017-01-11 10:30:00', '2017-01-11 10:39:35', ...);
INSERT INTO temperature_by_time (granularity, event_time, ..) VALUES ('2017-01-11 10:45:00', '2017-01-11 10:59:49', ...);

SELECT * FROM temperature_by_time WHERE granularity='2017-01-11 10:00:00';
SELECT * FROM temperature_by_time WHERE granularity='2017-01-11 10:00:00' AND event_time >= '2017-01-1 10:30:00' AND event_time < '2017-01-1 10:33:00';

即你将event_time“截断”到四分之一小时,并且只能在一个小时内获得记录。

<案例3

你已经知道如何继续......

答案 1 :(得分:2)

PRIMARY KEY ((day_of_year), event_time, weatherstation_id)会让你有能力在一天内完成一系列时间。如果期限跨越多天,则按day_of_year进行查询,并将其合并到应用程序中。

  

然后需要按时间顺序取回

不,它不会在你的例子中,因为它会返回按时间排序的行,一次一个分区。但是使用上面列出的主键,它会按时间列出它们,与weatherstation_id无关。