BitMap实现用户签到、UV统计

1. Redis 的 BitMap 概述

在 Redis 中,BitMap 并非一种独立的数据结构,而是基于 String 类型数据结构实现的一种存储方式。由于 String 类型的最大上限是 512M,换算成 bit 位就是 2^32 个,这决定了 BitMap 可操作的最大范围。BitMap 非常适合用于处理大量的布尔值,能以极小的空间存储大量的标志位信息,常用于签到统计、活跃用户统计等场景。

2. BitMap 常用操作命令

SETBIT:用于向指定位置(offset)存入一个 0 或 1,例如 SETBIT key offset value

GETBIT:获取指定位置(offset)的 bit 值,即 GETBIT key offset

BITCOUNT:统计 BitMap 中值为 1 的 bit 位的数量,命令为 BITCOUNT key

BITFIELD:可对 BitMap 中 bit 数组的指定位置(offset)的值进行查询、修改、自增等操作。

BITFIELD_RO:获取 BitMap 中 bit 数组,并以十进制形式返回。

BITOP:能将多个 BitMap 的结果做位运算(与、或、异或),如 BITOP AND result_key key1 key2

BITPOS:查找 bit 数组中指定范围内第一个 0 或 1 出现的位置,例如 BITPOS key 1

3. 基于 BitMap 的签到功能实现

签到实现
  • 业务逻辑:获取当前登录用户的 ID 和日期,根据用户 ID 和日期拼接 Redis 的 key,确定今天是本月的第几天,然后使用 SETBIT 命令将该位置的 bit 位设置为 1 表示签到。
@Override
public Result sign() {Long userId = UserHolder.getUser().getId();LocalDateTime now = LocalDateTime.now();String keySuffix = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));String key = USER_SIGN_KEY + userId + keySuffix;int dayOfMonth = now.getDayOfMonth();stringRedisTemplate.opsForValue().setBit(key, dayOfMonth - 1, true);return Result.ok();
}
签到统计
  • 业务逻辑:同样先获取当前登录用户的 ID 和日期,拼接 Redis 的 key 并确定今天是本月的第几天。使用 BITFIELD 命令获取本月截止今天为止的所有签到记录,返回一个十进制数字。通过循环对该数字进行位运算,从右向左逐位检查,统计连续签到的天数,直到遇到第一个 0 为止。
@Override
public Result signCount() {Long userId = UserHolder.getUser().getId();LocalDateTime now = LocalDateTime.now();String keySuffix = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));String key = USER_SIGN_KEY + userId + keySuffix;int dayOfMonth = now.getDayOfMonth();List<Long> result = stringRedisTemplate.opsForValue().bitField(key, BitFieldSubCommands.create().get(BitFieldSubCommands.BitFieldType.unsigned(dayOfMonth)).valueAt(0));if (result == null || result.isEmpty() || result.get(0) == null || result.get(0) == 0) {return Result.ok(0);}Long num = result.get(0);int count = 0;while (num > 0) {if ((num & 1) == 0) {break;} else {count++;}num >>>= 1;}return Result.ok(count);
}

四、BitMap总结

Redis 的 BitMap 利用 String 类型的特性,以高效的方式处理大量布尔值信息。在签到功能的实现中,通过合理使用 SETBIT 和 BITFIELD 等命令,能轻松完成签到记录和签到统计的操作,不仅节省了存储空间,还提高了操作效率。

五、UV统计

UV:全称Unique Visitor,也叫独立访客量,是指通过互联网访问、浏览这个网页的自然人。1天内同一个用户多次访问该网站,只记录1次。
PV:全称Page View,也叫页面访问量或点击量,用户每访问网站的一个页面,记录1次PV,用户多次打开页面,则记录多次PV。往往用来衡量网站的流量。

在 UV 统计场景中,由于需要统计大量独立访客,使用传统方式存储所有访客信息会占用大量内存。而 Redis 的 HyperLogLog 以其低内存占用和可接受的误差,成为了 UV 统计的理想选择,能够高效地完成大规模数据的基数统计任务。

HyperLogLog(HLL)是从 Loglog 算法派生的概率算法,用于确定非常大的集合的基数(集合中不同元素的数量),无需存储集合中的所有值。

Redis 中 HyperLogLog 的特点

        数据结构:基于 string 结构实现。

        内存占用:单个 HLL 的内存永远小于 16kb,内存占用极低。

        误差:测量结果是概率性的,存在小于 0.81%的误差,但对于 UV 统计来说,此误差可忽略不计。

对于百万级别的数据,使用 HyperLogLog 进行统计时,内存占用仅十几 kb,充分体现了 HyperLogLog 在处理大规模数据基数统计时内存占用低的优势。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/71509.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

共享模型之管程(悲观锁)

共享模型之管程&#xff08;悲观锁&#xff09; 文章目录 共享模型之管程&#xff08;悲观锁&#xff09;一、常见线程安全的类二、对象头三、Monitor&#xff08;监视器 / 管程&#xff09;四、偏向锁偏向锁的实现原理撤销偏向锁 五、轻量级锁轻量级锁的释放 六、重量级锁七、…

网络安全ctf试题 ctf网络安全大赛真题

MISC 1 签到 难度 签到 复制给出的flag输入即可 2 range_download 难度 中等 flag{6095B134-5437-4B21-BE52-EDC46A276297} 0x01 分析dns流量&#xff0c;发现dns && ip.addr1.1.1.1存在dns隧道数据&#xff0c;整理后得到base64: cGFzc3dvcmQ6IG5zc195eWRzIQ 解…

centos7操作系统下安装docker,及查看docker进程是否启动

centos7下安装docker&#xff0c;需要用到的yun命令 &#xff08;yum命令用于添加卸载程序&#xff09; 1.设置仓库&#xff1a; yum-config-manager \--add-repo \http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 2.安装 Docker Engine-Community yum in…

私有云基础架构与运维(二)

二.私有云基础架构 【项目概述】 经过云计算基础知识及核心技术的学习后&#xff0c;希望进一步了解 IT 基础架构的演变过 程&#xff0c;通过学习传统架构、集群架构以及私有云基础架构的相关知识&#xff0c;认识企业从传统 IT 基 础架构到私有云基础架构转型的必要性。…

Linux 系统不同分类的操作命令区别

Linux 系统有多种发行版,每种发行版都有其独特的操作命令和工具。以下是一些常见的分类及其操作命令的区别: 1. 基于 Red Hat 的发行版 (RHEL, CentOS, Fedora) 1.1 包管理 安装软件包: bash复制 sudo yum install <package> 更新软件包: bash复制 sudo yum update…

‌PLC数据类型和‌C#数据类型的数据类型映射表

数据类型映射表 ‌PLC数据类型‌C#数据类型读取方式‌补充说明BitboolDBX布尔值BytebyteDBB单字节无符号整数WordushortDBW16位无符号整数DWorduintDBD32位无符号整数Intshort16位有符号整数DIntint32位有符号整数RealfloatDBR单精度浮点数LRealdoubleDBL双精度浮点数Stringstr…

windows部署spleeter 版本2.4.0:分离音频的人声和背景音乐

windows部署spleeter 版本2.4.0&#xff1a;分离音频的人声和背景音乐 一、Spleeter 是什么&#xff1f; Spleeter 是由法国音乐流媒体公司 Deezer 开发并开源的一款基于深度学习的音频分离工具。它能够将音乐中的不同音轨&#xff08;如人声、鼓、贝斯、钢琴等&#xff09;分…

QTS单元测试框架

1.QTS单元测试框架介绍 目前QTS项目采用C/C语言,而CppUnit就是xUnit家族中的一员,它是一个专门面向C的单元测试框架。因此,QTS采用CppUnit测试框架是比较理想的选择。 CppUnit按照层次来管理测试,最底层的就是TestCase,当有了几个TestCase以后&#xff0c;可以将它们组织成Te…

dify + ollama + deepseek-r1+ stable-diffusion 构建绘画智能体

故事背景 stable-diffusion 集成进 dify 后&#xff0c;我们搭建一个小智能体&#xff0c;验证下文生图功能 业务流程 #mermaid-svg-6nSwwp69eMizP6bt {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-6nSwwp69eMiz…

分享几个论文校对相关的deepseek提示词

论文校对 1.检查这段文字是否有语法或风格错误&#xff1a;[在此处粘贴您的文本]。 2.审查我的[文件类型&#xff0c;例如&#xff0c;“论文”]中的这一段落是否有语法或风格错误&#xff1a;[在此处粘贴您的文本]。 3.请审查我关于[具体主题&#xff0c;例如&#xff0c;…

【极光 Orbit•STC8A-8H】02. STC8 单片机工程模板创建

【极光 Orbit•STC8A-8H】02. STC8 单片机工程模板创建 七律 单片机 小小芯片大乾坤&#xff0c;集成世界在其中。 初学虽感千重难&#xff0c;实践方知奥妙通。 今天的讲法和过去不同&#xff0c;直接来一个多文件模块化的工程模板创建&#xff0c;万事开头难&#xff0c;…

mac安装nvm=>node=>nrm

下载并安装 NVM 运行以下命令下载并安装 NVM&#xff1a; curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.4/install.sh | bash 配置环境变量 vim ~/.zshrc 按 i 将如下代码复制进去&#xff0c;controlc &#xff0c;再按 :wq完成编辑 export NVM_DIR…

K8S学习之基础十一:k8s中容器钩子

容器钩子 容器钩子分为post-start和pre-stop post-start&#xff1a;容器启动后执行的命令 pre-stop&#xff1a;容器关闭前执行的命令&#xff0c;可用于优雅关闭 # 分别定义两个钩子&#xff0c;启动pod后更新index.html&#xff0c;关闭pod前正常关闭服务 vi post-pre.…

K8s 1.27.1 实战系列(三)安装网络插件

Kubernetes 的网络插件常见的有 Flannel 和 Calico ,这是两种主流的 CNI(容器网络接口)解决方案,它们在设计理念、实现方式、性能特征及适用场景上有显著差异。以下是两者的综合对比分析: 一、Flannel 和 Calico 1. 技术基础与网络实现 Flannel 核心机制:基于 Overlay …

【五.LangChain技术与应用】【24.LangChain RAG文本向量化与存储:智能检索的核心技术】

凌晨三点,北京中关村的某栋办公楼依然灯火通明。28岁的算法工程师小李盯着屏幕上的代码,突然拍案而起:"终于成了!"他开发的智能客服系统在连续失败78次后,首次准确识别出用户"我想换个能打游戏的便宜手机"的真实需求——需要兼顾游戏性能和价格的机型…

深度学习五大模型:CNN、Transformer、BERT、RNN、GAN详细解析

卷积神经网络&#xff08;Convolutional Neural Network, CNN&#xff09; 原理 &#xff1a;CNN主要由卷积层、池化层和全连接层组成。卷积层通过卷积核在输入数据上进行卷积运算&#xff0c;提取局部特征&#xff1b;池化层则对特征图进行下采样&#xff0c;降低特征维度&…

特征分解(Eigen decomposition)在深度学习中的应用与理解

特征分解在深度学习中的应用与理解 特征分解&#xff08;Eigendecomposition&#xff09;是线性代数中的一个核心工具&#xff0c;在深度学习领域有着广泛的应用&#xff0c;尤其是在涉及矩阵操作和概率模型时。对于研究者来说&#xff0c;理解特征分解不仅有助于掌握数学基础…

分布式ID生成方案:数据库号段、Redis与第三方开源实现

分布式ID生成方案&#xff1a;数据库号段、Redis与第三方开源实现 引言 在分布式系统中&#xff0c;全局唯一ID生成是核心基础能力之一。本文针对三种主流分布式ID生成方案&#xff08;数据库号段模式、Redis方案、第三方开源框架&#xff09;进行解析&#xff0c;从实现原理…

rabbitmq-amqp事务消息+消费失败重试机制+prefetch限流

1. 安装和配置 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency><dependency> <groupId>com.fasterxml.jackson.core</groupId> <arti…

【Python】05、Python运算符

文章目录 1.算术运算符2.赋值运算符3.关系运算符4.逻辑运算符4.1 布尔值逻辑运算4.2 非布尔值的逻辑运算符 5.条件运算符6.运算符优先级 运算符也称为操作符&#xff0c;可以对一个或多个值进行运算或各种操作。比如、-、都属于运算符 1.算术运算符 加法 如果是两个字符串之间…