2016-09-15 30 views
0

我给出的用例非常简单:存储给定用户的事件,并允许在给定的时间范围内对这些用户进行计数。如何在cassandra中建模用户事件日志?

可能发生的事件数量相当小(< 1k),用户数量也是如此(< 10k)。插入件的数量大约为〜1k /秒。查询相当以用户为中心,因此基本上在给定时间范围内为给定用户选择全部或特定事件。

的主要栏目有:

  • 用户名
  • 时间戳
  • 事件

目前我的模型看起来像此列将被用作此:

(username, (timestamp, event, uuid)) 

因此用户名woul d是分区键,大多数查询可以通过仅查询一个节点来完成。一个非常普遍的查询可能看起来像:

select * from user_events where username=? and timestamp>? and timestamp<? 

我还想过使用计数器列,而不是增加的情况下,单独的UUID列在同一用户在同一事件发生在同一毫秒内。

因此,表格也会保持较小。

如果有人能分享他/她对这个模型的想法,我将不胜感激。

UPDATE

我创建了以下主要表来存储用户事件

CREATE TABLE IF NOT EXISTS events.events_by_user(
     user text, 
     added_week int, 
     added_timestamp timestamp, 
     event text, 
     uuid uuid, 
     PRIMARY KEY((user, added_week), added_timestamp, event)) 
    WITH CLUSTERING ORDER BY(added_timestamp DESC) 

这个工作相当不错,我开始通过查询来查询该表是这样的:

SELECT event,added_timestamp FROM events_by_user WHERE user=? AND added_week=? AND added_timestamp>=? AND added_timestamp<?; 

之后,我创建了第二个查询以筛选出特定事件:

SELECT event,added_timestamp FROM events_by_user WHERE user=? AND added_week=? AND added_timestamp>=? AND added_timestamp<? AND event IN ?; 

这一次虽然没有工作,因为我不允许有以下消息做GTE和LT查询上的时间戳后添加的子句:

群集列“事件”不能限制

+1

这可能会导致宽行。 –

+0

我明白了,但是我怎么能通过给定的要求通过这个?大多数查询都包含用户名和给定的时间范围,但偶尔还会执行仅用户名查询。 – u6f6o

回答

2

(前一列 “added_timestamp”由非均衡关系的限制)有两个相互矛盾的要求:要执行username中心查询,但你不想宽行...没有太多这里的经营空间...

我会先解决宽行。你真的不想要宽行,他们会杀死你(r节点)。所以,你需要找到一些东西加入username。从我所看到的情况来看,由于大多数查询都基于usernametimestamp,因此我会选择良好的时间粒度来控制行的宽度。

你说

可能发生的事件的数量相当小(< 1K)等是用户数量(< 10K)。刀片的数量大约是1K〜/秒

但是你不指定,如果事件的数量是每用户,如果插入频率是所有用户没有指定(我假设他们从现在开始)。

基于此,您预计每天有86个事件,这意味着每个用户平均有8600个事件。在我看来,一个体面的粒度级别,所以我会在形式yyyy-mm-dd添加时间戳作为分区键:

CREATE TABLE myevents (
    username text, 
    day timestamp, 
    timestamp timestamp, 
    event int 
    uuid uuid, 
    ... 
    PRIMARY KEY ((username, day), timestamp, event, uuid) 
); 

这可以让你查询flawlessy都属于一个特定的用户在特定的一天的事件。如果您需要跨多天查询,则需要执行多个查询(每天一次),然后通过将第一天的结果附加到第二天的结果中,然后在应用程序中重新构建结果,然后将结果第三天......等等。我说append是因为结果按集群密钥timestamp排序。

您可以通过更改day值来为您的需要选择最合适的粒度级别。如果您希望小时粒度将格式更改为yyyy-mm-dd HH:00,这将允许您拥有较小的行,但您需要执行24个查询才能获取一天的数据。或者,您可以选择以两天为一步,现在您的行数是原来的两倍,但您会执行一半的查询。

现在一切都取决于您的需求和您的群集。考虑到C *可扩展性高的特性,我会使用更多的查询和更小的行,即使这意味着在应用程序级别执行更多的编码。它可以让你更好地扩展。

+0

我基本上按照建议做的,但现在我有问题,我需要查询给定时间范围内的特定事件,但情况并非总是如此。当我尝试查询时,当我执行y> ts> = x和其他事件时,会得到一个异常。你会建议为这种情况添加一个特殊的表格吗? – u6f6o

+0

对不起,我不明白你想要做什么。你能写你的查询吗? – xmas79

+0

'SELECT * FROM events_by_user WHERE user =? AND added_week =? AND added_timestamp> =? AND added_timestamp <? AND event IN?;' vs'SELECT * FROM events_by_user WHERE user =? AND added_week =? AND added_timestamp> =? AND added_timestamp u6f6o