Redis BitMap 用户签到

Redis Bitmap
Bitmap(位图)是 Redis 提供的一种用于处理二进制位(bit)的特殊数据结构,它基于 String 类型,每个 bit 代表一个布尔值(0 或 1),可以用于存储大规模的二值状态数据,如签到、活跃用户统计、去重等。
1. Bitmap 基本原理
- Bitmap 本质上是一个二进制数组,每个 bit 仅占 1 位,相比普通的 String 存储方式(每个字符 8 位),能大幅节省空间。
- Redis 并没有单独的数据类型 Bitmap,它是基于
String结构的。 - 通过 位运算(
SETBIT、GETBIT、BITCOUNT、BITOP等)高效存取数据。
2. Bitmap 常用命令
(1)SETBIT:设置某一位的值
SETBIT key offset value
key:键名offset:bit 偏移量(从 0 开始)value:0或1
📌 示例
SETBIT user:1001 1 1 # 将 user:1001 的第 1 位设置为 1
SETBIT user:1001 2 0 # 将 user:1001 的第 2 位设置为 0
SETBIT user:1001 5 1 # 将 user:1001 的第 5 位设置为 1
假设 user:1001 初始状态是:(每个 0 代表 1 bit,总共 32 bit = 4 字节)
00000000 00000000 00000000 00000000
执行:
SETBIT user:1001 5 1 # 将 user:1001 的第 5 位设置为 1
SETBIT user:1001 5 1
结果变成:
00000100 00000000 00000000 00000000
第 5 位(从 0 开始计数,即第 6 个 bit)被设置为 1。
作用:类似于一个布尔数组,可用于表示某个用户在不同时间点的状态(如签到)。
(2)GETBIT:获取某一位的值
GETBIT key offset
key:键名offset:bit 偏移量
📌 示例
GETBIT user:1001 1 # 返回 1
GETBIT user:1001 2 # 返回 0
GETBIT user:1001 5 # 返回 1
作用:查询某个状态,如某用户是否签到。
(3)BITCOUNT:统计 bit 为 1 的个数
BITCOUNT key [start end]
key:键名[start end](可选):字节范围(默认统计整个 key)
📌 示例
BITCOUNT user:1001 # 统计 user:1001 中 bit 为 1 的个数
作用:
- 统计某个用户的签到次数
- 统计一段时间内活跃用户数量
(4)BITOP:对多个 Bitmap 进行位运算
BITOP operation destKey key1 key2 ...
operation:AND(与)OR(或)XOR(异或)NOT(非)
destKey:存储结果的 keykey1 key2 ...:参与运算的 key
📌 示例
BITOP AND active_users today yesterday # 统计连续两天都活跃的用户
BITOP OR total_active day1 day2 day3 # 统计三天内活跃过的用户
作用:
- 计算多天签到的交集、并集
- 统计活跃用户
3. Bitmap 典型应用
(1)用户签到
场景:每个用户有一个 31 位的 Bitmap(对应 31 天),bit 为 1 表示已签到,0 表示未签到。
📌 示例
SETBIT sign:1001:20240301 0 1 # 用户 1001 在 3 月 1 日签到
SETBIT sign:1001:20240302 1 1 # 3 月 2 日签到
SETBIT sign:1001:20240303 2 1 # 3 月 3 日签到
GETBIT sign:1001:20240303 2 # 查询 3 月 3 日是否签到(返回 1)
BITCOUNT sign:1001:202403 # 查询用户 1001 3 月签到次数
(2)统计活跃用户
场景:每天创建一个 Bitmap,记录活跃用户(bit 位置对应用户 ID)。
📌 示例
SETBIT active:20240301 1001 1 # 用户 1001 3 月 1 日活跃
SETBIT active:20240301 1002 1 # 用户 1002 3 月 1 日活跃
SETBIT active:20240302 1002 1 # 用户 1002 3 月 2 日活跃
BITCOUNT active:20240301 # 统计 3 月 1 日活跃用户数
BITOP AND active_both active:20240301 active:20240302 # 统计连续两天活跃的用户
(3)A/B 测试 & 用户权限控制
场景:用 Bitmap 存储用户是否属于 A/B 测试组或是否拥有某个权限。
📌 示例
SETBIT experiment:groupA 1001 1 # 用户 1001 参与 A 组测试
SETBIT experiment:groupB 1002 1 # 用户 1002 参与 B 组测试
GETBIT experiment:groupA 1001 # 查询用户 1001 是否在 A 组
4. Bitmap 优势
✅ 节省空间:1 个 bit 仅占 1/8 字节,非常适合存储大规模用户数据(如千万级别用户签到情况)。
✅ 高效查询:GETBIT 和 SETBIT 操作时间复杂度为 O(1),快速读写。
✅ 支持批量运算:BITCOUNT、BITOP 等可进行高效统计。
5. Bitmap 限制
❌ 不支持删除某个 bit(只能置 0,无法真正删除)。
❌ 不支持范围查询(需要配合 BITCOUNT 和 GETBIT)。
❌ 偏移量有限制(Redis 最大 String 长度约 512MB,即支持 2^32 个 bit)。
6. 总结
| 功能 | 命令 | 作用 |
|---|---|---|
| 设置 bit | SETBIT key offset value | 设置指定偏移量的 bit |
| 获取 bit | GETBIT key offset | 获取指定偏移量的 bit |
| 统计 1 的数量 | BITCOUNT key | 统计 key 中 bit 为 1 的个数 |
| 位运算 | BITOP operation destKey key1 key2 | 对多个 Bitmap 进行 AND/OR/XOR/NOT 运算 |
Bitmap 非常适合用于海量用户数据的布尔状态存储,如签到、活跃用户、权限控制等场景。
参考文献
[1] https://redis.io/docs/latest/develop/data-types/bitmaps/
相关文章:
Redis BitMap 用户签到
Redis Bitmap Bitmap(位图)是 Redis 提供的一种用于处理二进制位(bit)的特殊数据结构,它基于 String 类型,每个 bit 代表一个布尔值(0 或 1),可以用于存储大规模的二值状…...
未来办公与生活的新范式——智慧园区
在信息化与智能化技术飞速发展的今天,智慧园区作为一种新兴的城市发展形态,正逐步成为推动产业升级、提升城市管理效率、改善居民生活质量的重要力量。智慧园区不仅融合了先进的信息技术,还深刻体现了可持续发展的理念,为园区内的…...
Hugging Face预训练GPT微调ChatGPT(微调入门!新手友好!)
Hugging Face预训练GPT微调ChatGPT(微调入门!新手友好!) 在实战中,⼤多数情况下都不需要从0开始训练模型,⽽是使⽤“⼤⼚”或者其他研究者开源的已经训练好的⼤模型。 在各种⼤模型开源库中,最…...
【CSS3】化神篇
目录 平面转换平移旋转改变旋转原点多重转换缩放倾斜 渐变线性渐变径向渐变 空间转换平移视距旋转立体呈现缩放 动画使现步骤animation 复合属性animation 属性拆分逐帧动画多组动画 平面转换 作用:为元素添加动态效果,一般与过渡配合使用 概念&#x…...
Unity音频混合器如何暴露参数
音频混合器是Unity推荐管理音效混音的工具,那么如何使用代码对它进行管理呢? 首先我在AudioMixer的Master组中创建了BGM和SFX的分组,你也可以直接用Master没有问题。 这里我以BGM为例,如果要在代码中进行使用就需要将参数暴露出去…...
Vue keepalive学习用法
在Vue中,<keep-alive>的include属性用于指定需要缓存的组件,其实现方式如下: 1. 基本用法 • 字符串形式:通过逗号分隔组件名称,匹配到的组件会被缓存。 <keep-alive include"ComponentA,ComponentB&…...
5-1 使用ECharts将MySQL数据库中的数据可视化
方法一:使用Python Flask框架搭建API 对于技术小白来说,使用ECharts将MySQL数据库中的数据可视化需要分步骤完成。以下是详细的实现流程: 一、技术架构 后端服务:使用Python Flask框架搭建API(简单易学ÿ…...
构建下一代AI Agent:自动化开发与行业落地全解析
1. 下一代AI Agent:概念与核心能力 核心能力描述技术支撑应用价值自主性独立规划与执行任务,无需持续人工干预决策树、强化学习、目标导向规划减少人工干预,提高任务执行效率决策能力评估多种方案并选择最优解决方案贝叶斯决策、多目标优化、…...
如何理解分布式光纤传感器?
关键词:OFDR、分布式光纤传感、光纤传感器 分布式光纤传感器是近年来备受关注的前沿技术,其核心在于将光纤本身作为传感介质和信号传输介质,通过解析光信号在光纤中的散射效应,实现对温度、应变、振动等物理量的连续、无盲区、高…...
四、小白学JAVA-石头剪刀布游戏
1、如何从控制台获取用户输入 import java.util.Scanner;public class Main {public static void main(String[] args) {// 石头剪刀布的思路// 1 2 3 石头 剪刀 布Scanner scanner new Scanner(System.in);System.out.println("请出拳:1.石头 2.剪刀 3.布【…...
【一起来学kubernetes】21、Secret使用详解
Secret 的详细介绍 Secret 是 Kubernetes 中用于存储和管理敏感信息(如密码、令牌、密钥等)的资源对象。Secret的设计目的是为了安全地存储和传输敏感信息,如密码、API密钥、证书等。这些信息通常不应该直接硬编码在配置文件或镜像中&#x…...
css重点知识汇总(一)
css重点知识汇总(一) 引入css的不同方式 link 通过src来获取相应的css资源。除了获取css之外还可以获取其他资源,例如js在页面载入是同步下载可以通过js对dom操作来改变css import css3引入的新方法只能引入css资源需要页面完全载入后才…...
PMP-项目运行环境
你好!我是 Lydia-穎穎 ♥感谢你的陪伴与支持 ~~~ 欢迎一起探索未知的知识和未来,现在lets go go go!!! 1. 影响项目的要素 项目存在在不同的环境下,环境对于项目的交付产生不同的影响。需了解环境对于项目的影响,采取相应措施应对…...
shell 脚本搭建apache
#!/bin/bash # Set Apache version to install ## author: yuan# 检查外网连接 echo "检查外网连接..." ping www.baidu.com -c 3 > /dev/null 2>&1 if [ $? -eq 0 ]; thenecho "外网通讯良好!" elseecho "网络连接失败&#x…...
Huawei 鲲鹏(ARM/Aarch64)服务器安装KVM虚拟机(非桌面视图)
提出问题 因需要进行ARM架构适配,需要在Huawei Taishan 200k(CPU: Kunpeng 920 5231K)上,创建几台虚拟机做为开发测试环境。 无奈好久没搞了,看了一下自己多年前写的文章:Huawei 鲲鹏…...
《Python实战进阶》No28: 使用 Paramiko 实现远程服务器管理
No28: 使用 Paramiko 实现远程服务器管理 摘要 在现代开发与运维中,远程服务器管理是必不可少的一环。通过 SSH 协议,我们可以安全地连接到远程服务器并执行各种操作。Python 的 Paramiko 模块是一个强大的工具,能够帮助我们实现自动化任务&…...
备赛蓝桥杯之第十六届模拟赛3期职业院校组
提示:本篇文章仅仅是作者自己目前在备赛蓝桥杯中,自己学习与刷题的学习笔记,写的不好,欢迎大家批评与建议 由于个别题目代码量与题目量偏大,请大家自己去蓝桥杯官网【连接高校和企业 - 蓝桥云课】去寻找原题࿰…...
【Kafka】深入了解Kafka
集群的成员关系 Kafka使用Zookeeper维护集群的成员信息。 每一个broker都有一个唯一的标识,这个标识可以在配置文件中指定,也可以自动生成。当broker在启动时通过创建Zookeeper的临时节点把自己的ID注册到Zookeeper中。broker、控制器和其他一些动态系…...
C++特性——RAII、智能指针
RAII 就像new一个需要delete,fopen之后需要fclose,但这样会有隐形问题(忘记释放)。RAII即用对象把这个过程给包起来,对象构造的时候,new或者fopen,析构的时候delete. 为什么需要智能指针 对于…...
C++异常处理时的异常类型抛出选择
在 C 中选择抛出哪种异常类型,主要取决于错误的性质以及希望传达的语义信息。以下是一些指导原则,帮助在可能发生异常的地方选择合适的异常类型进行抛出: 1. std::exception 适用场景:作为所有标准异常的基类,std::e…...
elsticsearch 通过reindex修改shards
elasticsearch reindex 索引。 背景: 索引test1 reindex到test2 修改sharding数量 程序是通过别名test1_alias访问索引 1、创建目标索引test2 索引需要手动提前创建自动创建可能会有mapping 不一致性的风险。 The destination should be configured as wanted …...
CentOS系类普通挂载磁盘挂载命令
检查磁盘是否有分区 lsblk如果 vdb 下面没有分区(比如 vdb1),你需要先创建分区。 创建分区(如果需要) fdisk /dev/vdb然后在 fdisk 交互界面: 输入 n 创建新分区 选择 p 创建主分区 默认分区号和大小 输…...
Kafka自定义分区机制
文章目录 1.如何自定义分区机制2.示例 1.如何自定义分区机制 若需要使用自定义分区机制,需要完成两件事: 1)在 producer 程序中创建一个类,实现 org.apache.kafka.clients.producer.Partitioner 接口主要分区逻辑在 Partitioner.partition中…...
【HarmonyOS NEXT】关键资产存储开发案例
在 iOS 开发中 Keychain 是一个非常安全的存储系统,用于保存敏感信息,如密码、证书、密钥等。与文件系统不同,Keychain 提供了更高的安全性,因为它对数据进行了加密,并且只有经过授权的应用程序才能访问存储的数据。那…...
强化学习(赵世钰版)-学习笔记(9.策略梯度法)
本章是课程的导数第二章,旨在讲解策略的函数化形式。 之前的方法,描述一个策略都是用表格的形式,每一行代表一个状态,每一列代表一个行为,表格中的元素对应相关状态下执行相关行为的概率。 函数化的策略表征形式是指&a…...
ModuleNotFoundError: No module named ‘flask‘ 错误
要解决 ModuleNotFoundError: No module named ‘flask’ 错误,需确保已正确安装 Flask 库。以下是详细步骤: 1. 安装 Flask 在终端或命令行中执行以下命令(注意权限问题): 使用 pip 安装 pip install flask 若…...
【c++】【STL】unordered_set 底层实现(简略版)
【c】【STL】unordered_set 底层实现(简略版) ps:这个是我自己看的不保证正确,觉得太长的后面会总结整个调用逻辑 unordered_set 内部实现 template <class _Kty, class _Hasher hash<_Kty>, class _Keyeq equal_to<_Kty>…...
【Zephyr】【一】学习笔记
Zephyr RTOS 示例代码集 1. 基础示例 1.0 基础配置 每个示例都需要一个 prj.conf 文件来配置项目。以下是各个示例所需的配置: 基础示例 prj.conf # 控制台输出 CONFIG_PRINTKy CONFIG_SERIALy CONFIG_UART_CONSOLEy# 日志系统 CONFIG_LOGy CONFIG_LOG_DEFAULT…...
网络安全设备配置与管理-实验4-防火墙AAA服务配置
实验4-p118防火墙AAA服务配置 从这个实验开始,每一个实验都是长篇大论😓 不过有好兄弟会替我出手 注意:1. gns3.exe必须以管理员身份打开,否则ping不通虚拟机。 win10虚拟机无法做本次实验,必须用学校给的虚拟机。首…...
后端框架模块化
后端框架的模块化设计旨在简化开发流程、提高可维护性,并通过分层解耦降低复杂性。以下是常见的后端模块及其在不同语言(Node.js、Java、Python)中的实现方式: 目录 1. 路由(Routing)2. 中间件(…...
