0

我在 cassandra 1.2 中有一个 coulmn 家庭,如下所示:

 time            | class_name                  | level_log | message       | thread_name
-----------------+-----------------------------+-----------+---------------+-------------
 121118135945759 | ir.apk.tm.test.LoggerSimple |     DEBUG | This is DEBUG |        main
 121118135947310 | ir.apk.tm.test.LoggerSimple |     ERROR | This is ERROR |        main
 121118135947855 | ir.apk.tm.test.LoggerSimple |      WARN |  This is WARN |        main
 121118135946221 | ir.apk.tm.test.LoggerSimple |     DEBUG | This is DEBUG |        main
 121118135951461 | ir.apk.tm.test.LoggerSimple |      WARN |  This is WARN |        main

当我使用此查询时:

SELECT * FROM LogTM WHERE token(time) > token(0);

我什么都得不到!!!但正如您所见,所有时间值都大于零!

这是 CF 模式:

  CREATE TABLE logtm(
        time bigint PRIMARY KEY ,
        level_log text ,
        thread_name text ,
        class_name text ,
        msg text 
  );

任何身体都可以帮忙吗?

谢谢 :)

4

1 回答 1

4

如果您没有使用有序分区器(如果您不知道这意味着您不使用),那么该查询不会按照您的想法进行。仅仅因为两个时间戳以一种方式排序并不意味着它们的令牌可以。令牌是单元格值的 (Murmur3) 散列(除非您更改了分区器)。

如果您需要进行范围查询,则不能在分区键上进行,只能在集群键上进行。一种方法是使用这样的模式:

CREATE TABLE LogTM (
  shard INT,
  time INT,
  class_name ASCII,
  level_log ASCII,
  thread_name ASCII,
  message TEXT,
  PRIMARY KEY (shard, time, class_name, level_log, thread_name)
)

如果您设置shard为零,架构将大致等同于您现在正在执行的操作,但查询SELECT * FROM LogTM WHERE timestamp > 0将为您提供您期望的结果。

但是,性能会很糟糕。将仅创建单个分区/行的单个值shard,并且您将仅使用集群的单个节点(并且该节点将非常忙于尝试压缩该单行)。

所以你需要想办法把负载分散到更多的节点上。一种方法是在 0 到 359 之间(或者 0 到 255,如果你喜欢 2 的倍数,确切的范围并不重要,它只需要比节点),并在您回读时从所有分片中读取:(SELECT * FROM LogTM WHERE shard IN (0,1,2,...)您需要在列表中包含所有分片,代替...)。

您还可以通过散列消息来选择分片,这样您就不必担心重复。

您需要告诉我们更多关于您正在尝试做什么,尤其是您打算如何查询数据。不要去做我上面描述的事情,这对你的用例来说可能是完全错误的,我只是想给你一个例子,这样我就可以解释 Cassandra 内部发生了什么。

于 2013-06-18T10:22:16.150 回答