前言
set(无序,唯一)集合提供了像交集,并集,差集等方法。
可以使用set集合来统计新增用户,留存用户。
统计新增
假设系统初始五个用户,ID:1,2,3,4,5
集合A来记录用户(累计用户,即系统当前所拥有的用户)
sadd A 1
sadd A 2
sadd A 3
sadd A 4
sadd A 5
集合B来记录用户(当天登录过的用户)。
这里第一天,假设3,5登录,新注册了6,系统注册成功时默认登录到系统中,所以也会写入B中。
sadd B 3
sadd B 5
sadd B 6
第一天新增用户就是B与A的差集
顺便做一个新增用户记录,使用 sdiffstore
# 6
sdiff B A
# 将 B A 差集保存到 user_new:2022-07-28
sdiffstore user_new:2022-07-28 B A
上面得到了新增的用户是6。结下来需要把6添加到累积用户中,set提供了获取并集并保存的方法
# 第一个A 代表保存到那里
# 将 A B 集合并集 覆盖保存到A
# A 中有 1,2,3,4,5,6
sunionstore A A B
第二天,假设3,6登录,注册了7,8。这个记录写到C中,B留做历史记录(B,C 一般在项目中的名字类似于 user:2022-08-01)。按照第一天的方式处理即可(新增用户:C,A 差集,将C,A 并集保存至A)
sadd C 3
sadd C 6
sadd C 7
sadd C 8
统计留存用户
统计第一天登录了,第二天也登录的用户
求C,B 交集即可,并保存到user:keep
# 将C,B交集保存至user:keep
sinterstore user:keep C B
缺陷
由于取交集,并集,差集比较复杂。当数据量比较大时,将会非常耗时。由于redis是单进程,会导致实例阻塞。
解决一:在主从模式下,可以挑选一台从库去执行。由于从库 read only。导致无法使用sdiffstore,sinterstore,sunionstore。但是可以先使用(sdiff,sinter,sunion) 获取结果,再交给主库保存。
解决二:读出来,交给客户端程序去交,差,并集