【问题标题】:Cassandra help : Supporting fast queries using either part of composite keyCassandra 帮助:使用组合键的任一部分支持快速查询
【发布时间】:2017-01-11 17:20:00
【问题描述】:

我是 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′;

如果我的理解对我有帮助,这会不会效率低下,因为它需要遍历每个分区?不仅如此,还需要采取措施以按时间顺序取回。

解决这个问题的最佳设计是什么?

【问题讨论】:

    标签: cassandra


    【解决方案1】:

    其实你的查询:

    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 行。根据您写入此表的速度,您可以采用不同的方式进行操作。例子:


    案例一

    • 您有 10 个传感器
    • 每个传感器每秒测量一次

    在这种情况下,您将编写 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 个传感器
    • 每个传感器每秒测量一次

    在这种情况下,您将编写 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) 我想要某个时间范围内的所有临时工 3) 我想要 Weatherstation_id=123 的所有临时工 4)我想要使​​用 weatherstation_id=123 或 weatherstation_id=456 的所有临时工 5) 我想要使用 weatherstation_id=123 在某个时间范围内的所有临时工 6) 我想要使用 weatherstation_id=123 或 weatherstation_id=456 在某个时间范围内的所有临时工 公平地说我需要多张桌子吗? ...或物化视图
    • 1.气馁,2. 使用我的桌子,3. 4. 5. 6. 使用你的桌子。你写了你的查询规则:我想要 by xxx 的临时文件。用一张桌子满足每个by
    • 谢谢圣诞节,标记你的答案。但确实希望有一个简单的后续问题。如果我的粒度是 1 小时,并且我想搜索一个月的数据,那么在该选择的 where 子句中,您会指定“WHERE 粒度 IN(...)”内的所有分区吗?因为这个列表可能会变得很长,在我的示例中,一个月将超过 700 个分区。还是人们通常只是用单独的选择遍历每个分区?
    • 正确答案是选项 3:通常人们运行多个选择,每个分区一个,并行...
    【解决方案2】:

    PRIMARY KEY ((day_of_year), event_time, weatherstation_id) 可以让您在一天内完成多次。如果时间段跨越多天,您可以根据 day_of_year 进行查询并将它们合并到应用程序中。

    然后需要采取措施按时间顺序取回

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-08-31
      • 2016-11-23
      • 1970-01-01
      • 1970-01-01
      • 2017-08-15
      • 1970-01-01
      • 2016-03-22
      相关资源
      最近更新 更多