首页 > 数据库 >基于Redis实现用户签到、UV统计的功能

基于Redis实现用户签到、UV统计的功能

时间:2022-10-22 09:34:38浏览次数:52  
标签:签到 redis UV Redis 获取 key offset 统计

用户签到

在Redis中使用位图(BitMap)来存储签到信息,可以大大减小开销。同时在设计redis数据结构时,在key中加上时间、用户id等信息,可以统计该用户在某个时间段内的签到情况。(bitmap最大有2^32位bit位)

具体的数据结构设计为

{"sign:userId:yyyyMM":"bitmapValue"},是以月为单位的签到统计

如果某一天要进行签到,需要进行操作setbit key offset 1,将当天的bit位设置为1即可

统计当月的签到情况bitcount key,即可获得当月的签到天数

bitmap常用操作

setbit [key] [offset] [0/1]  #向指定位置(offset)存入一个0或1
getbit [key] [offset]  #获取指定位置的(offset)bit值
bitcount [key]  #统计bitmap中1的数量
bitfield  #操作(查询、修改、递增)bitmap中bit数据指定位置(offset)的值
#这些操作在java中被封装在opsForValue()方法中

签到业务

业务流程

1、获取当前登录用户

2、获取日期

3、拼接key

4、获取今天是本月第几天

5、写入redis setbit key offset 1

代码实现

UserServiceImpl.userSign()

@Override
public Result userSign() {
    //1、获取当前登录用户
    UserDTO user = UserHolder.getUser();
    //2、获取日期
    LocalDateTime now = LocalDateTime.now();
    String today = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));
    //3、拼接key
    String key = USER_SIGN_KEY + user.getId() + today;
    //4、获取今天是本月第几天,即redis中的offset
    int dayOfMonth = now.getDayOfMonth();
    //5、写入redis   setbit key offset 1
    stringRedisTemplate.opsForValue().setBit(key, dayOfMonth - 1, true);

    return Result.ok();
}

统计连续签到天数

统计签到天数就是利用bitfield操作实现,由于java中没有封装bitcount功能,只能用bitfield获取无符号数后再进行位运算进行统计

重点关注

1、获得本月到今天为止的签到情况,bitfield key get u[dayOfMonth] 0 ,获取bitmap中从0~dayOfMonth位的无符号整数

2、如何从右向左和每一位bit位做运算,从redis中获取的无符号数与1做与(&)运算,效果是仅获取最右边的一位数

业务流程

1、获取当前登录用户

2、获取日期

3、拼接key

4、获取今天是本月第几天,即redis中的offset

5、获取本月到今天为止的所有签到情况,获得一个无符号整数

6、循环遍历这个无符号数的每一位,位运算

7、判断这一位是否为1

8、如果为1,签到天数count++;连续签到的话如果为0就返回计数结果

代码实现

UserServiceImpl.getSign()

@Override
public Result getSign() {
    //1、获取当前登录用户
    UserDTO user = UserHolder.getUser();
    //2、获取日期
    LocalDateTime now = LocalDateTime.now();
    String today = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));
    //3、拼接key
    String key = USER_SIGN_KEY + user.getId() + today;
    //4、获取今天是本月第几天,即redis中的offset
    int dayOfMonth = now.getDayOfMonth();

    //5、获取本月到今天为止的所有签到情况,获得一个无符号整数
    List<Long> results = stringRedisTemplate.opsForValue().bitField(key, BitFieldSubCommands.create().get(BitFieldSubCommands.BitFieldType.unsigned(dayOfMonth)).valueAt(0));
    /**
         * 看业务统计的是连续签到天数还是一个月签到的总天数,
         * 如果是连续签到天数遍历到0直接退出循环即可
         * 在此处实现的是统计当月签到总天数
         */
    int count = 0;
    Long result = results.get(0);
    if(result == null || result == 0) return Result.ok(0);
    //6、循环遍历这个无符号数的每一位,位运算
    while(result != 0L){
        long bit = result & 1;
        //7、判断这一位是否为1
        //8、如果为1,签到天数count++
        if(bit == 1L) count++;
        result >>>= 1;  //long类型的无符号右移
    }

    return Result.ok(count);
}

UV统计

UV(unique visitor)和PV(page view)前者一个用户访问多次只记录一次访问后者用户多次打开网页就记录多次,用于记录网站的流量

使用HyperLogLog进行UV统计:是LogLog派生的概率算法,单个HLL的内存占用永远小于16kb,错误率约为0.81%

常用操作

pfadd [key] [element...]  #向HyperLogLog加入数据
pfcount [key]  #统计HyperLogLog中的数量
pfmerge [destkey] [sourcekey]  #合并多个HyperLogLog的统计数据

对应于java中的这些方法

Blog的UV统计业务流程

在黑马点评业务中对博客的访问量统计,只需要在处理查询单个博客的请求的时候将用户Id增加至HyperLogLog中,在页面发起统计请求时,从redis中获取HyperLogLog的size()返回即可。

redis的数据结构

{"uv:blog:blogId":"hyperLogLogData"}

标签:签到,redis,UV,Redis,获取,key,offset,统计
From: https://www.cnblogs.com/Gw-CodingWorld/p/16815059.html

相关文章

  • Redis搭建Sentinel实验环境
    环境准备在物理机上启动3台物理机,IP地址分别为:192.168.56.4,192.168.56.5,192.168.56.6。1.确保3台虚拟机的网络是相互联通的。2.确保已经在3台虚拟机上安装了redis(本示例......
  • 基于Redis实现好友动态推送、附近商铺功能
    好友动态推送基于推模式实现探店笔记,一个人发布blog,在将blog保存到数据库的同时将blog发送到每个粉丝的收信箱中;收信箱按时间戳进行排序(类似于朋友圈);收信箱查询数据时按滚......
  • Redis处理秒杀并发
     一、现公司解决秒杀方案:1. 利用Redis原子性自增接口incr2. Redis缓存+异步同步数据到数据库优点:解决超卖问题,库存读写都在内存中,故同时解决性能问题。缺点:由于......
  • 19. redis之scan
    在巨大的数据量的情况下,做类似查找符合某种规则的key的信息主要有两种方法:第一种方法使用keys 命令,然后后面带上正则匹配,比如匹配keys redis* -->匹配以redis开......
  • redis7.0主从+sentinel
    #redis7需要python3环境wgethttps://www.python.org/ftp/python/3.7.2/Python-3.7.2.tar.xztar-xv Python-3.7.2.tar.xzcdPython-3.7.2./configure--prefix=/usr/l......
  • .NET Core C#系列之XiaoFeng.Redis组件库础操作篇教程
    XiaoFeng.Redis组件库拥有丰富的API和巅峰之作的性能,下面我就先以基础的操作做如下讲解,循序渐进,慢慢提升。欢迎关注xiaofeng组件库,开源不易,多多支持。开源地址:https://git......
  • 【收藏看】关于面试常见问题:Redis有哪些数据结构?
    面试场景  Redis作为时下最火的缓存中间件之一,面试的时候面试官肯定会问Redis的相关内容,而往往问的第一个问题就是:你知道Redis有哪几种数据结构吗?你们项目中使用......
  • Redisson 大bug处理: Command xxx succesfully sent, but channel xxx has been close
    棘手的bug,无从下手使用redisson的过程中, 我们的应用程序突然报错: org.redisson.client.RedisConnectionClosedException:Command(EXISTS),params:[paypal_fee_i......
  • 基于Redis实现点赞、点赞用户按时间排序、好友关注和共同关注等业务
    点赞功能业务说明1、每个用户只能点一次赞,再次点击时取消点赞2、在Blog属性中增加isLike字段,用于判断当前用户是否点赞3、isLike的值从Redis中获取,可以用redis自带的......
  • Docker | redis集群部署实战
    前面已经简单熟悉过redis的下载安装使用,今天接着部署redis集群(cluster),简单体会一下redis集群的高可用特性。环境准备Redis是C语言开发,安装Redis需要先将Redis的源码进行......