美文网首页系统架构redis专题Java 程序员
阿里面试:使用Redis的Bitmaps位图手写用户签到功能

阿里面试:使用Redis的Bitmaps位图手写用户签到功能

作者: 马小莫QAQ | 来源:发表于2021-01-29 22:22 被阅读0次

很多应用比如签到送积分、签到领取奖励:

  • 签到 1 天送 10 积分,连续签到 2 天送 20 积分,3 天送 30 积分,4 天以上均送 50 积分等
  • 如果连续签到中断,则重置计数,每月初重置计数
  • 显示用户某个月的签到次数
  • 在日历控件上展示用户每月签到情况,可以切换年月显示

最简单的设计思路就是利用MySQL保存签到数据(t_user_sign),如下:

  • 用户签到:往此表插入一条数据,并更新连续签到天数
  • 查询根据签到日期查询
  • 统计根据 amount 统计

如果这样存数据,对于用户量大的应用,db可能扛不住,比如 1000W 用户,一天一条,那么一个月就是 3 亿数据,非常庞大。

使用bitmap

Bitmaps,位图,不是 Redis 的基本数据类型(比如 Strings、Lists、Sets、Hashes),而是基于 String 数据类型的按位操作,高阶数据类型的一种。Bitmaps 支持最大位数 232 位。使用 512M 内存就可以存储多达 42.9 亿的字节信息(232 = 4,294,967,296)。

它由一组 bit 位组成,每个 bit 位对应 0 和 1 两个状态,虽然内部还是采用 String 类型存储,但 Redis 提供了一些指令用于直接操作位图,可以把它看作是一个 bit 数组,数组的下标就是偏移量。

优点

内存开销小、效率高且操作简单,很适合用于签到这类场景。比如按月进行存储,一个月最多 31 天,那么我们将该月用户的签到缓存二进制就是 00000000000000000000000000000000,当某天签到将 0 改成 1 即可,而且 Redis 提供对 bitmap 的很多操作比如存储、获取、统计等指令,使用起来非常方便。

常用命令

代码实现

位运算判断是否签到

统计用户签到情况

获取用户某月签到情况,默认当前月,返回当前月的所有日期以及该日期的签到情况。

SignController

SignService: 获取某月签到情况,默认当月:

  • 获取登录用户信息
  • 构建 Redis 保存的 Key
  • 获取月份的总天数(考虑 2 月闰、平年)
  • 通过 BITFIELD 指令获取当前月的所有签到数据
  • 遍历进行判断是否签到,并存入 TreeMap 方便排序

总结

由于 String 数据类型的最大长度是 512M,所以 String 支持的位数是 2^32 位。512M 表示字节 Byte 长度,换算成位 bit 需要乘以 8,即 512 2^10 2^10 * 8=2^32; Strings 的最大长度是 512M,还能存更大的数据?当然不能,但是我们可以换种实现思路,就是将大 key 换成小 key,这样存储的大小完全不受限制。

作者:JavaEdge在掘金
链接:https://juejin.cn/post/6922745138066227214
来源:掘金

相关文章

  • 阿里面试:使用Redis的Bitmaps位图手写用户签到功能

    很多应用比如签到送积分、签到领取奖励: 签到 1 天送 10 积分,连续签到 2 天送 20 积分,3 天送 30...

  • redis的bitmaps的应用-网站签到的设计和网站的数据统计

    在使用redis设计签到系统,我们可以使用集合和bitmaps两种数据结构。这边我们来说明一下bitmaps。 1...

  • 位图与HyperLogLog的使用场景是什么? 二者各自的原理?

    位图的使用当接到这样的需求时,第一时间我想到的就是使用Redis来应对这样的需求,用户一年的签到记录, 签了是 1...

  • No.5 Redis 操作hash

    业务方可能需要对用户进行签到,由于存在并发的可能,使用redis 对用户id 进行hash后分组,再放入redis...

  • redis面试题

    redis数据结构有哪些? 对象类型字符串列表集合有序集合(排名)字典 位图(签到)地理空间=-=========...

  • 使用redis的bitmap实现签到功能

    一、签到功能的实现思路 最常规的思路,一般我们会选择每个用户,每天的签到作为一条mysql表的数据,然后一条一条的...

  • Redis数据类型之Bitmaps

    本文介绍redis的新数据类型之一:bitmaps。它在当今的互联网环境当中有很多的应用场景,比如常见的签到、点赞...

  • Java实现布隆过滤器

    记得前段时间的文章么?redis使用位图法记录在线用户的状态,还是需要自己实现一个IM在线用户状态的记录,今天来讲...

  • Redis Bitmaps

    Redis位图:位图并不是一种实际的数据类型,而是在字符串数据类型上定义的按位操作集合(对普通的字符串键也可以进行...

  • java实现加减乘除法

    难易程度:★★★ 重要性:★★★★★ 阿里蚂蚁金服的面试中出现:要求手写实现“乘除法” 快手的面试中曾出现:使用位...

网友评论

    本文标题:阿里面试:使用Redis的Bitmaps位图手写用户签到功能

    本文链接:https://www.haomeiwen.com/subject/nrwctltx.html