首页 > 数据库 >常见场景题-Redis的bitmap如何实现签到功能?

常见场景题-Redis的bitmap如何实现签到功能?

时间:2023-12-09 13:31:49浏览次数:38  
标签:10 26 签到 Redis 202310 bitmap userx

Redis 的 bitmap 实现签到系统?

答: 主要讲一下 Redis 原生的 bitmap 的使用方法,以及如何使用 bitmap 来实现签到功能

先来看一下如何使用 redis bitmap 的原生命令实现签到功能:

  • 签到

我们先来设计 key:userid:yyyyMM,那么假如 usera 在2023年10月3日和2023年10月4日签到的话,使用以下命令:

setbit key offset value

在3日签到的话,偏移量应该设置为2,则签到之后为 001

在4日签到的话,偏移量应该设置为3,则3日、4日签到后为0011(第3位和第4位都是1,表示这两天签到了)

在31日签到的话,偏移量应该设置为30,表示向右偏移30位

127.0.0.1:6379> setbit userx:202310 2 1
(integer) 0
127.0.0.1:6379> setbit userx:202310 3 1
(integer) 0
127.0.0.1:6379> setbit userx:202310 30 1
(integer) 0
  • 查看2023年10月哪些天签到了,10月有31天,所以使用u31(31位无符号整数),后边偏移量为0
127.0.0.1:6379> bitfield userx:202310 get u31 0
1) (integer) 402653185

通过 bitfield [key] get u31 0 获取了31位的无符号整数,将该整数402653185转为二进制如下:(可以发现从左向右第4位和第5位位1,表示这两天签到了,也就是3号签到的时候,在setbit key value offset中,偏移量设置了为3,所以向右偏移3为,在第4位上)

402653185 十进制
0011000000000000000000000000001 二进制

通过取出来这个无符号整数,我们在代码中就可以通过位运算来判断某一天是否签到,可以看出,第3、4、31位都是1,表明在这三天都进行了签到

那么如果今天是10月26日,我们想知道10月1日-10月26日有哪些天进行签到,使用如下命令:

127.0.0.1:6379> bitfield userx:202310 get u26 0
1) (integer) 12582912

12582912 转为二进制为:

26位无符号整数:
00110000000000000000000000

那么我们在计算连续签到的次数就可以使用以下方法:

public Integer getContinuousSignCount() {
  /*
  假如今天是 10月26日
  假如通过 redis 的 bitfield userx:202310 get u26 0 命令得到了从1日-26日的签到数据为:12582912
  */
  Long v = 12582912;
  // 这里 26 为今天的日期
  Integer signCount = 0;
  for (int i = 0; i < 26; i ++) {
    if (v & 1 == 0) return signCount;
    signCount ++;
    v >>= 1;
  }
}

标签:10,26,签到,Redis,202310,bitmap,userx
From: https://blog.51cto.com/u_16186397/8748515

相关文章

  • Redis生产实战-Redis集群故障探测以及降级方案设计
    Redis集群故障探测在生产环境中,如果Redis集群崩溃了,那么会导致大量的请求打到数据库中,会导致整个系统都崩溃,所以系统需要可以识别缓存故障,限流保护数据库,并且启动接口的降级机制降级方案设计我们在系统中操作Redis一般都是通过工具类来进行操作的,假设工具类有两个RedisCache......
  • Redis基础(六)-Redis客户端
    Redis官方对Java语言的封装框架推荐的有十多种,主要是Jedis、Redisson。Jedis和Redisson都是Java中对Redis操作的封装。Jedis只是简单的封装了Redis的API库,可以看作是Redis客户端,它的方法和Redis的命令很类似。Redisson不仅封装了redis,还封装了对更多数据结构的支持,以及......
  • Redis基础(七)-Redis6的事务操作
    Redis的事务定义Redis事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。Redis的事务作用Redis事务的主要作用就是串联多个命令防止别的命令插队。Multi、Exec、discard从输入Multi命令开始,输入的命......
  • Redis数据结构分析1:Redis对象
    Redis数据结构分析本篇将涉及C语言,请确保您拥有C语言相关基础与计算机底层知识RedisObject(robj)robj是Redis对象的起点,所有的数据结构都封装到了robj之中。其源码如下:structredisObject{unsignedtype:4;unsignedencoding:4;unsignedlru:LRU_BITS;......
  • Caused by: io.lettuce.core.RedisCommandExecutionException: NOAUTH Authentication
    原文链接:https://blog.csdn.net/De_Buffer/article/details/132492287最终解决方法虽然通过更换连接客户端为jedis解决了问题,但不符合发展趋势,lettuce已成为主流redis客户端,springboot2官方推荐,因此在这个保底方案基础上继续探究。终于!!找到解决我的问题的一篇文章,跟着他的思......
  • Redis生产实战-热key、大key解决方案、数据库与缓存最终一致性解决方案
    生产环境中热key处理热key问题就是某一瞬间可能某条内容特别火爆,大量的请求去访问这个数据,那么这样的key就是热key,往往这样的key也是存储在了一个redis节点中,对该节点压力很大那么对于热key的处理就是通过热key探测系统对热key进行计数,一旦发现了热key,就将热key......
  • Redis报错:(error) DENIED Redis is running in protected mode because protected mod
    一、报错内容  (error)DENIEDRedisisrunninginprotectedmodebecauseprotectedmodeisenabledandnopasswordissetforthedefaultuser.Inthismodeconnectionsareonlyacceptedfromtheloopbackinterface.Ifyouwanttoconnectfromexternal......
  • Redis报错:WARNING: The TCP backlog setting of 511 cannot be enforced because /pro
    报错内容:1:C08Dec202305:47:33.348#oO0OoO0OoO0OoRedisisstartingoO0OoO0OoO0Oo1:C08Dec202305:47:33.348#Redisversion=7.0.5,bits=64,commit=00000000,modified=0,pid=1,juststarted1:C08Dec202305:47:33.348#Configurationloaded1:M08De......
  • redis分布式锁实现原理
    在.netcore中,可以使用StackExchange.Redis实现redis分布式锁,///<summary>///分布式锁///</summary>///<paramname="Redis">RedisDB</param>///<paramname="Key">锁标识</param>///<paramname="Seconds">过......
  • redis集群双活-数据迁移
    一、redis双活1、集群搭建(一主两从)Redis-Sentinel是redis官方推荐的高可用性解决方案,sentinel哨兵是特殊的redis服务,不提供读写服务,主要用来监控redis实例节点,当用redis作master-slave的高可用时,如果master本身宕机,redis本身或者客户端都没有实现主从切换的功能,而redis-sentine......