【问题标题】:Schema for writing and querying Monthly Active Users (MAU) and Daily Active Users (DAU)?用于编写和查询每月活跃用户 (MAU) 和每日活跃用户 (DAU) 的架构?
【发布时间】:2016-03-23 13:24:38
【问题描述】:

我在 Cassandra 中使用两个单独的表来跟踪 MAU 和 DAU。每张桌子的设计都是一样的:

create table log.MAU(d timestamp, userId varchar, primary key (d, userId));

每次用户登录或恢复会话时,我都会插入表中。对于时间戳,我使用各自的 UTC“零小时”(例如 DAU 为当天的 UTC 午夜,MAU 为当月第一天的 UTC 午夜)。

我当前设计的好处是简单(例如select count(*) from DAU where d = ?)和大小(如果用户处于活动状态,则每天/每月只保留一条记录)。

但是,缺点是我无法进行滚动周期(例如过去 24 小时内的活跃用户),而且我也无法跟踪每天或每月每一天的每个小时的活动(尽管我还有其他如果我添加了必要的二级索引,我可能会争吵 cassandra 日志)。

考虑到我提到的或我没有考虑过的具体缺点,我是否可以更好地跟踪 DAU 和 MAU?也许另一个像 postgres 这样的数据库会更合适?谢谢!

【问题讨论】:

    标签: cassandra


    【解决方案1】:

    我认为您可以通过键入另一个不太精确的日期列来解决此问题。

    对于月度用户,这样的事情会起作用:

    CREATE TABLE mau(
      month bigint,
      d timestamp,
      userid text,
      PRIMARY KEY (month,d,userId));
    

    然后您可以查询特定月份:

    SELECT d, userid FROM may WHERE month=201603;
    

    您还可以查询以下范围:

    SELECT d, userid FROM mau WHERE month=201603
      AND d>'2016-03-21 19:40:00+0000' AND d<'2016-03-21 19:50:00+0000';
    
     d                        | userid
    --------------------------+--------
     2016-03-21 19:40:13+0000 |   tron
     2016-03-21 19:40:20+0000 |   yori
     2016-03-21 19:40:28+0000 | quorra
     2016-03-21 19:40:36+0000 |  paige
    
    (4 rows)
    

    month 是否适合您,取决于您希望每月访问多少行,以及这将使您接近 Cassandra 对每个分区 20 亿个单元的限制。考虑到这一点,最好也按day 进行分区,如下所示:

    CREATE TABLE mau(
      month bigint,
      day bigint,
      d timestamp,
      userid text,
      PRIMARY KEY ((month,day),d,userId));
    

    当然,您将无法一次查询整个月。但是用这种方法搞乱,看看你是否能找到适合你的应用程序的 PRIMARY KEY 策略。

    编辑 20160323

    因此,为了计算“唯一”登录,我需要执行“选择计数(*)不同的用户 ID”或类似的操作。我对 Cassandra 中的 distinct 不是很熟悉,但我知道它适用于分区键。鉴于此架构中的分区键是三列 (month,d,userId) 的组合,是否允许单独对 userId 进行计数?

    不,count 将无法通过iteslf 处理用户ID。首先,您不能跳过 PRIMARY KEY 组件。其次,使用 Cassandra,您需要采用基于查询的建模方法。如果您需要查询已登录的不同用户 ID,那么您需要新建一个表来支持它。

    CREATE TABLE logins_by_user (
      userid text,
      d timestamp,
      PRIMARY KEY(userid,d))
    WITH CLUSTERING ORDER BY (d DESC);
    

    假设我有和上面一样的数据,除了用户“tron”第二次登录:

    SELECT * FROM logins_by_user ;
    
     userid | d
    --------+--------------------------
     quorra | 2016-03-21 19:40:28+0000
      paige | 2016-03-21 19:40:36+0000
       tron | 2016-03-22 19:37:53+0000
       tron | 2016-03-21 19:40:13+0000
       yori | 2016-03-21 19:40:20+0000
    
    (5 rows)
    

    查询唯一的用户 ID 会产生:

    SELECT DISTINCT userid FROM logins_by_user ;
    
     userid
    --------
     quorra
      paige
       tron
       yori
    
    (4 rows)
    

    不确定这是否正是您正在寻找的,但我希望这个想法能够引导您朝着正确的方向前进。

    【讨论】:

    • 因此,为了计算“唯一”登录次数,我需要执行“选择计数(*)不同的用户 ID”或类似的操作。我对 Cassandra 中的 distinct 不是很熟悉,但我知道它适用于分区键。鉴于此架构中的分区键是三列(月、d、userId)的组合,单独在 userId 上是否允许计数不同?谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-17
    • 1970-01-01
    • 2022-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-25
    相关资源
    最近更新 更多