在cassandra存储时间范围

时间:2011-01-12 09:21:24

标签: cassandra

我正在寻找一种存储与时间范围相关的数据的好方法,以便以后能够有效地检索它。

每个数据条目都可以简化为(start time, end time, value)。我需要稍后检索属于(x, y)范围内的所有条目。在SQL中,查询类似于

SELECT value FROM data WHERE starttime <= x AND endtime >= y

你能否为Cassandra建议一个数据结构,这样我就能有效地执行这些查询?

1 个答案:

答案 0 :(得分:6)

有效建模这是一件非常困难的事情。

我认为使用Cassandra的二级索引(以及目前仍然需要的虚拟索引值)是您的最佳选择。每个事件需要使用一行,至少有三列:'start','end'和'dummy'。为每个创建二级索引。前两个可以是LongType,最后一个可以是BytesType。有关详细信息,请参阅this post on using secondary indexes。因为你必须在至少一个列上使用EQ表达式来进行二级索引查询(我提到的不幸要求),所以EQ将在'dummy'上,它总是可以设置为0.(这意味着EQ索引表达式)将匹配每一行,基本上是一个无操作。)您可以将其余的事件数据存储在开始,结束和虚拟的行中。

在{Campandra客户端的pycassa中,您的查询将如下所示:

from pycassa.index import *
start_time = 12312312000
end_time = 12312312300
start_exp = create_index_expression('start', start_time, GT)
end_exp = create_index_expression('end', end_time, LT)
dummy_exp = create_index_expression('dummy', 0, EQ)
clause = create_index_clause([start_exp, end_exp, dummy_exp], count=1000)
for result in entries.get_indexed_slices(clause):
    # do stuff with result

其他客户应该有类似的东西。

我首先考虑的替代方案是OrderPreservingPartitioner,它几乎总是一件坏事。对于索引,您可以使用开始时间作为行键,将结束时间用作列名称。然后,您可以使用start_key = start_time和column_finish = finish_time执行范围切片。这将在开始时间之后扫描每一行,并仅在finish_time之前返回具有列的行。效率不高,你必须做一个大的多重等等。内置的二级索引方法更好,因为节点只会索引本地数据,并且大多数样板索引代码都是为你处理的。