暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

如何使用Redis实现记录和统计用户连续签到天数

龙虾编程 2024-12-12
172

    在我们日常玩的游戏中或一些银行类app上,他们为了提高用户的活跃度,设计了签到领取奖励的功能,当用户连续签到多少天之后我们可以获得相应的奖励,如下是某个app中签到页面:

    用户签到的数据如果直接存到数据库中是不推荐的,因为需要一张签到表来单独的记录每个用户的每天签到数据,随着业务的发展,一旦用户量非常大的时候,那么签到表的数据会急剧的增长,到最后会存在性能的问题。下面我们来介绍使用redis的bitmap来实现记录和统计用户连续签到的方案。

1、认识redis的bimap

    bitmap实际上就是由一个一个的二进制位所组成的,在bitmap中每一个位只存放0或者1,如下所示的bitmap结构图:

    Redis的bitmap是字符串类型实现的,我们知道字符串类型最大支持512M,换算成二进位可以存放大约42亿个bit位,如下的换算过程:

    所以即使网站中有几亿日活的用户,当需要统计他们的连续签到时,bitmap也是可以记录的并且所占的内存也是很小的。

2、bitmap实现用户连续签到功能

    使用bitmap存储用户的连续签到功能有两个存储维度,第一个是按照日期的维度统计,第二个是按照用户的维度来统计。

2.1 日期维度统计

    如果要统计用户在12月份的连续签到次数,我们设置key为日期,用户的id作为bitmap上的偏移位,如下所示:

    这里要求用户的id必须是数字的,如果用户的id不是数字的话,可以使用用户id的hash值加随机数的方式将用户id映射成数字,然后存放到bitmap上。

    如果以日期为维度来存储签到数据,要统计12月份所有用户的连续签到,那么就需要31个bitmap就是可以实现。假设用户id等于8的用户签到了,我们将bitmap上8这个位置的0修改成1,如下所示:

    同样的道理,id为8的用户在12月份每天的签到数据都存储到这31个bitmap上,如下图所示:

    现在要统计id=8的这个用户在12月份的签到次数,我们可以通过最后一个key(2024-12-31)为起点,依次向上进行统计,如下图所示:

    如果只是统计用户在12月份签到的天数,我们依次向上遍历,遇到1就增加签到的次数,遇到0就不统计。如果是连续签到的次数,那么遇1就累加签到的次数,遇0则重新统计。

    按照日期为维度的式统计每天的所有用户签到的次数,效率是比较高,但是如果要统计单个用户的话,还是要去循环每一个日期的key。

   这种方式适用于用户量比较大的场景,当然建议统计不超过一个月的数据,因为统计的日期太长的话,对应的key数量也是越来越多的,需要的内存也会增加。如果只统计一个月的签到数据,只需要将当前的这个key过期时间设置为一个月,当超过一个月会自动的过期,这样可以有效的利用redis的内存。

2.2 用户维度的统计

    这种方式为每个用户分配一个bitmap,用户id为key,将日期映射到bitmap上,如下图所示:

    假设id为8的用户连续5天签到了,那么我们记录在bitmap中的数据如下所示:

    这种方式很适合统计单个用户的连续签到情况,但是要统计每天所有用户的签到就需要遍历每个用户的bitmap,此时的效率比较低。

总结:

(1)bitmap底层是由二进制位组成的,其bit位上非0即1。

(2)像记录和统计登录、签到,点赞等二值场景并且涉及到海量数据都可以使用bitmap来实现,因为bitmap不仅占用的内存非常小,而且统计速度非常快。

文章转载自龙虾编程,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论