我在cassandra 1.2中有一个家庭如下:
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
);
任何人都可以帮忙吗?
谢谢:)
答案 0 :(得分: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之间选择一个随机碎片(如果你喜欢2的倍数,则选择0和255,确切的范围并不重要,它只需要一个数量级或大于数量的数量级每个插入的节点),并在您回读时从所有分片中读取:SELECT * FROM LogTM WHERE shard IN (0,1,2,...)
(您需要在列表中包含所有分片,代替...
)。
您也可以通过散列消息来选择分片,这样您就不必担心重复了。
您需要告诉我们更多关于您正在尝试做什么的信息,特别是您打算如何查询数据。不要去做我上面描述的事情,对你的用例来说可能是完全错误的,我只是想给你一个例子,这样我就可以解释Cassandra里面发生了什么。