【问题标题】:Timestamp / date as key for cassandra column family / hector时间戳/日期作为 cassandra 列族/赫克托的关键
【发布时间】:2012-11-21 22:11:17
【问题描述】:

我必须使用复合键作为 [timestamp,long] 创建和查询列族。还, 查询时我想触发时间戳范围查询(例如 xxx 和 yyy 之间的时间戳)这可能吗?

目前我正在做一些非常有趣的事情(我知道这不正确)。我为给定范围创建带有时间戳字符串的键,并与 long 连接。

like ,
1254345345435-1234
3423432423432-1234
1231231231231-9999

并将一组键传递给 hector api。 (所以如果我有 1 个月的日期范围并且我想要每分钟的数据,我创建 30 * 24 * 60 * [辅助键的数量 - 长])

我可以用复合键解决连接问题。但查询部分是我想要理解的。

据我了解,由于我们使用的是 RandomPartitioner,我们无法真正根据范围进行查询,因为键是 MD5 校验和。这种用例的理想设计是什么?

我的架构和要求如下:(实际csh)

    CREATE TABLE report(
        ts timestamp,
        user_id long,
        svc1 long,
        svc2 long,
        svc3 long,
        PRIMARY KEY(ts, user_id));

select from report where ts between (123445345435 and 32423423424) and user_id is in (123,567,987)

【问题讨论】:

  • 你理解正确 - 没有随机分区器的行键范围查询。
  • @tysonjh 这种情况有什么替代方案?我认为这是很常见的情况……简单的时间线图。
  • 您需要根据计划查询的方式对架构进行建模,因此请使用允许查询的合适粒度对您希望范围查询的值创建反向(也称为反向、倒排)索引它们以您想要的精度。
  • 我添加了一个答案,因为任何进一步的解释都会涉及到

标签: cassandra hector


【解决方案1】:

您不能对复合键的第一个组件进行范围查询。相反,您应该写入一个标记值,例如 daystamp(当天午夜的 unix 纪元)作为键,然后将复合列写入 timestamp:long。通过这种方式,您可以提供构成您的范围的键,并对复合列的时间戳组件进行切片。

【讨论】:

    【解决方案2】:

    反规范化!您必须以能够启用您希望执行的查询类型的方式对您的模式进行建模。我们为此类场景创建了一个反向(也称为倒置、反向)索引。

    CREATE TABLE report(
        KEY uuid PRIMARY KEY,
        svc1 bigint,
        svc2 bigint,
        svc3 bigint
    );
    
    CREATE TABLE ReportsByTime(
        KEY ascii PRIMARY KEY
    ) with default_validation=uuid AND comparator=uuid;
    
    CREATE TABLE ReportsByUser(
        KEY bigint PRIMARY KEY
    )with default_validation=uuid AND comparator=uuid;
    

    请参阅here 以获得很好的解释。您现在正在做的是在times 表中生成您自己的ascii 键,以使您自己能够执行您想要的范围切片查询 - 它不必是ascii,尽管您可以使用它以编程方式生成您自己的切片键。

    您可以使用这种方法来简化您的所有查询,这可能不会直接适合您的应用程序,但想法是相同的。您可以通过向上面每个表的列键添加有意义的值来从中挤出更多信息。

    cqlsh:tester> select * from report;
     KEY                                  | svc1 | svc2 | svc3
    --------------------------------------+------+------+------
     1381b530-1dd2-11b2-0000-242d50cf1fb5 |  332 |  333 |  334
     13818e20-1dd2-11b2-0000-242d50cf1fb5 |  222 |  223 |  224
     13816710-1dd2-11b2-0000-242d50cf1fb5 |  112 |  113 |  114
    
    
    cqlsh:tester> select * from times;
     KEY,1212051037 | 13818e20-1dd2-11b2-0000-242d50cf1fb5,13818e20-1dd2-11b2-0000-242d50cf1fb5 | 1381b530-1dd2-11b2-0000-242d50cf1fb5,1381b530-1dd2-11b2-0000-242d50cf1fb5
     KEY,1212051035 | 13816710-1dd2-11b2-0000-242d50cf1fb5,13816710-1dd2-11b2-0000-242d50cf1fb5 | 13818e20-1dd2-11b2-0000-242d50cf1fb5,13818e20-1dd2-11b2-0000-242d50cf1fb5
     KEY,1212051036 | 13818e20-1dd2-11b2-0000-242d50cf1fb5,13818e20-1dd2-11b2-0000-242d50cf1fb5
    
    cqlsh:tester> select * from users;
     KEY         | 13816710-1dd2-11b2-0000-242d50cf1fb5 | 13818e20-1dd2-11b2-0000-242d50cf1fb5
    -------------+--------------------------------------+--------------------------------------
     23123123231 | 13816710-1dd2-11b2-0000-242d50cf1fb5 | 13818e20-1dd2-11b2-0000-242d50cf1fb5
    

    【讨论】:

      【解决方案3】:

      你为什么不使用宽行,其中键是时间戳,列名作为长值,那么你可以将多个键(时间戳)传递给 getKeySlice,并通过那里的名称(即 id)选择多个列到 withColumnSlice。

      由于我不知道什么是列名和值,我觉得这可以帮助你。您能否提供有关列族定义的更多详细信息。

      【讨论】:

      • 他想对时间戳做范围查询,所以这行不通。
      • @rs_atl 据我了解,我将无法触发范围查询,因为键是 md5 ...是否正确?或者是否有替代方案....这里的简单场景是显示时间线图。有没有更好的方法来设计列族? @ user1793389 所以无论如何我都必须通过所有的键吗?
      • 你是对的。您可以使用 ByteOrderedPartitioner 对键进行范围查询,但这是一个坏主意,因为集群几乎肯定会变得不平衡。另一种方法是我在回答中建议的。
      • @rs_atl 如果他定义了一个复合列,他可以在第一列上创建查询范围,但他如何才能只获取 LonType In (v1, v2, v3) 的列? 他可以传递第二个组件的值列表吗? Jigar,rs_atl 要求您创建复合列的而不是复合键。 我的解决方案要求您将多个键传递给 getKeySlice。
      猜你喜欢
      • 2013-03-17
      • 2011-09-17
      • 2013-02-23
      • 1970-01-01
      • 2021-10-15
      • 2013-07-10
      • 2012-05-02
      • 2013-05-01
      • 1970-01-01
      相关资源
      最近更新 更多