首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

基于Redis位图实现用户签到功能

背景

会员积分体系,实现前端按照日历进行签到。连续签到的7天及7天的倍数额外增加积分。可以获取之前连续签到的次数(理论上没有上限)

设计思路

如果存入到数据库中数据量巨大,且充斥很多无意义数据。了解到使用Redis的位图适合于大量存储布尔型的值。对于用户签到数据,如果每条数据都用K/V的方式存储,当用户量大的时候内存开销是非常大的。而位图(BitMap)是由一组bit位组成的,每个bit位对应0和1两个状态,虽然内部还是采用String类型存储,但Redis提供了一些指令用于直接操作位图,可以把它看作是一个bit数组,数组的下标就是偏移量。它的优点是内存开销小、效率高且操作简单,很适合用于签到这类场景。

按用户每月存一条签到数据(也可以每年存一条数据)。Key的格式为u:sign:uid:yyyyMM,Value则采用长度为4个字节(32位)的位图(最大月份只有31天)。位图的每一位代表一天的签到,1表示已签,0表示未签。

例如u:sign:1000:201902表示ID=1000的用户在2019年2月的签到记录。

实现难点

使用递归去获取最大的连续签到次数,在递归到合适的值时,在从最里面的递归方法中跳出。使用抛异常的方式去返回值,在调用时使用try catch去捕获最里面递归抛出的值。

Redis的无符号数最大只能取63位,也就是一次最多只能取63天的签到数据,例如:

超出长度就会报错:ERR Invalid bitfield type. Use something like i16 u8. Note that u64 is not supported but i64 is.

递归使用上个月的拼接的key去获取上个月最大的天数,不断循环去获取最大的连续不中断的签到次数。

实例代码

maven依赖

点在看~

捧个人场就行~

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20200823A0JB2100?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券