如何在cassandra中为用户事件日志建模?

时间:2016-09-15 21:35:46

标签: database cassandra data-modeling

我给出的用例非常简单:为给定用户存储事件,并允许在以后的给定时间范围内为每个用户计算这些事件。

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

关键栏目是:

  • 用户名
  • 时间戳
  • 活动

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

(username, (timestamp, event, uuid)) 

因此,用户名将是分区键,大多数查询只能通过查询一个节点来完成。一个非常常见的查询可能如下:

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

我进一步考虑使用计数器列而不是添加单独的uuid列,以防同一用户的同一事件在同一毫秒内发生。

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

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

更新

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

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查询之后添加一个in子句,并带有以下消息:

  

无法限制聚类列“事件”(在列之前   “added_timestamp”受非EQ关系的限制)

1 个答案:

答案 0 :(得分:2)

您有两个相互矛盾的要求:您希望执行username中心查询,但您不想要宽行...此处没有太多的操作空间......

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

你说

  

可能事件的数量相当小(<1k),用户数量(<10k)也是如此。插入物的数量约为~1k / sec

但是,您没有指定事件数量每个用户,并且您没有指定插入频率是否适用于所有用户 (我假设他们从现在开始)。

基于此,您希望每天有86M个事件,这意味着每个用户平均有8600个事件。在我看来,这是一个不错的粒度级别,所以我会在yyyy-mm-dd格式中添加一个时间戳作为分区键:

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

这使您可以在特定日期查询属于特定用户的所有事件的完美情况。如果您需要跨多天查询,则需要执行多个查询(每天一个),然后通过将第一天的结果与第二天的结果相关联,在应用程序中重建结果,然后附加结果第三天......依此类推。我说追加是因为结果按群集密钥timestamp排序。

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

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