实践《Redis聚合统计使用》

Posted 韦静春

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实践《Redis聚合统计使用》相关的知识,希望对你有一定的参考价值。

统计需求场景

1、统计每天的新增用户数和第二天的留存用户数;

场景:聚合统计

所谓的聚合统计,就是指统计多个集合元素的聚合结果

统计多个集合的共有元素(交集统计);

把两个集合相比,统计其中一个集合独有的元素(差集统计);

统计多个集合的所有元素(并集统计)

在刚才提到的场景中,统计每天的新增用户数和第二天的留存用户数,正好对应了聚合统计。

要完成这个统计任务,我们需要两种集合。

  • 用一个集合记录所有登录过 App 的用户 ID;
    • 使用 Set 类型记录所有登录过 App 的用户 ID,把 key 设置为 alluser,表示记录的是用户 ID,value 就是一个 Set 集合,里面是所有登录过 App 的用户 ID,我们可以把这个 Set 叫作累计用户 Set。
  • 用另一个集合记录每一天登录过 App 的用户 ID。
    • 每日用户 Set记录到一个新集合Set中,key 是 user 以及当天日期,例如 user:20210802; value 是 Set 集合,记录当天登录的用户 ID。

在统计每天的新增用户时,我们只用计算每日用户 Set 和累计用户 Set 的差集就行。

示例

假设有一个新用户 2021年8月2日上线,那么,8月2日前是没有用户的。

此时,累计用户Set 是空集,当天登录的用户 ID 会被记录到 key 为 user:20210802的 Set 中。所以,user:20210802这个 Set 中的用户就是当天的新增用户。

累计用户计算

然后,我们计算累计用户 Set 和 user:20210802 Set 的并集结果,结果保存在 alluser 这个累计用户 Set 中,如下所示:

SUNIONSTORE  alluser alluser  user:20210802

这个时候,user:id 这个累计用户 Set 中就有了 8 月 2 日的用户 ID。等到 8 月 3 日再统计时, 我们把 8 月 3 日登录的用户 ID 记录到 user:20210803 的 Set 中。

新增用户计算

接下来,我们执行SDIFFSTORE 命令计算累计用户 Set 和 user:20210803 Set 的差集,结果保存在 key 为 user:new 的 Set 中,如下所示:

SDIFFSTORE  user_new  user:20210803 alluser

user_new 这个 Set 中记录的就是 8 月 3 日的新增用户

留存用户计算

计算8 月 3 日的留存用户时,我们只需要再计算 user:20210802 和 user:20210803 两个 Set 的交集,就可以得到同时在这两个集合中的用户 ID 了,这些就是在 8 月 2 日登录,并且在 8 月 3 日留存的用户。执行的命令如下:

SINTERSTORE user_rem user:20210802 user:20210803

缺点

当需要对多个集合进行聚合计算时,Set 类型会是一个非常不错的选择。不过,这里有一个潜在的风险。
Set 的差集、并集和交集的计算复杂度较高,在数据量较大的情况下,如果直接执行这些计算,会导致 Redis 实例阻塞。所以,建议:

  • 从主从集群中选择一个从库,让它专门负责聚合计算,
  • 或者是把数据读取到客户端,在客户端来完成聚合统计,这样就可以规避阻塞主库实例和其他从库实例的风险了。

以上是关于实践《Redis聚合统计使用》的主要内容,如果未能解决你的问题,请参考以下文章

REDIS08_bitmap的概述用途setbitgetbitbigcountbittopstrlen命令使用

REDIS08_bitmap的概述用途setbitgetbitbigcountbittopstrlen命令使用

Redis学习笔记—— 有一亿个keys要统计,应该用哪种集合?

MongoDB高级查询多级分组聚合及时间计算应用实践案例

ElasticSearch6.x版本聚合统计在Kibana上的实操和在SpringBoot上的实操

风控系统实践之感: drools 和 redis