Redis Bitmap怎样统计每日签到的连续天数怎样在批处理代码中减少额外分配
我把签到统计做成批处理后,最稳妥的做法是:用 Redis Bitmap 的一个 bit 表示一天,按“用户 + 月份”拆 key;计算连续天数时从截止日向前扫描,遇到第一个 0 就停止。批量处理多个用户时,日期缓冲区、月份 key 和读取字节都在循环外复用,避免每个用户都新建临时对象。
官方地址:https://redis.io/docs/latest/develop/data-types/bitmaps/
这个方案适合“某天签没签到”和“连续多少天”这类布尔状态,不适合直接保存签到时间、设备或备注。
先把日期和位偏移定死
不要把全年日期直接塞进一个无限增长的 key。这里按月建立 key,例如 signin:{userID}:2026-11,1 日对应偏移 0,2 日对应偏移 1。月初、月末和时区必须由业务统一,否则凌晨切日时会出现“多一天”或“少一天”。

| 对象 | 示例 | 作用 |
|---|---|---|
| key | signin:42:2026-11 | 隔离用户和月份 |
| offset | day-1 | 定位某一天的 bit |
| value | 0 或 1 | 未签到或已签到 |
用 SETBIT 写入,用 GETBIT 验证
写入签到是幂等的,同一天重复执行仍然只是把同一位设为 1。下面的命令用于理解数据形状,行首注释说明每一步的目的。
# 第 1 天签到,偏移量是 0 redis-cli SETBIT signin:42:2026-11 0 1 # 第 3 天签到,偏移量是 2 redis-cli SETBIT signin:42:2026-11 2 1 # 验证第 2 天是否签到,返回 0 redis-cli GETBIT signin:42:2026-11 1 # 统计整个月已经签到的天数,不等于连续天数 redis-cli BITCOUNT signin:42:2026-11
BITCOUNT只能回答“总共签了几天”,连续天数仍要围绕截止日判断相邻 bit。若要一次处理很多天,可以读取位图字节后在内存中扫描,避免每天单独发一个命令。
从截止日向前扫描连续天数
下面的小函数把一个月的 Bitmap 字节作为输入。它不访问 Redis,因此便于在批处理中复用读取结果;跨月时由调用方再读取上一个月,不能把不存在的位误当成已签到。
package main
import "fmt"
// streakFromBytes 从截止日向前数连续的 1;截止日按 1-based 传入。
func streakFromBytes(bitmap []byte, cutoffDay int) int {
if cutoffDay = 1; day-- {
offset := day - 1
byteIndex, bitIndex := offset/8, uint(offset%8)
if byteIndex >= len(bitmap) {
break // 位图没有覆盖到这一天
}
if bitmap[byteIndex]&(1
批处理时复用缓冲区
性能问题通常不在一次 GET,而在几万名用户循环里反复拼 key、格式化日期、复制结果。可以把月份字符串和 key 缓冲放在循环外;每个用户只替换 ID 区段,并让 Redis 客户端返回的字节直接交给扫描函数。不要为了“零分配”牺牲可读性,先用基准测试确认热点。

// 复用固定容量的 key 缓冲,避免每个用户都重新分配完整字符串。
keyBuf := make([]byte, 0, 64)
month := "2026-11"
for _, userID := range userIDs {
keyBuf = keyBuf[:0] // 保留容量,只清空本轮长度
keyBuf = append(keyBuf, "signin:"...)
keyBuf = append(keyBuf, userID...)
keyBuf = append(keyBuf, ':')
keyBuf = append(keyBuf, month...)
key := string(keyBuf) // Redis 客户端需要稳定的字符串参数
// bytesFromRedis 是当前用户 Bitmap 的读取结果;实际项目中按客户端 API 获取。
streak := streakFromBytes(bytesFromRedis(key), cutoffDay)
_ = streak // 将结果写入批量更新或报告
}
如果客户端会异步持有参数,不能把仍会变化的字节切片直接交给它;此时转换成字符串或使用客户端提供的安全批量接口更稳妥。减少分配的前提是参数生命周期清楚。
验收四个边界
第一,截止日未签到时结果必须是 0;第二,连续签到从月初开始时,向前只能扫描当前月;第三,未来日期不能被当作已签到;第四,空 key 的读取结果要按全 0 处理。用 BITCOUNT 做总数核对,用几个已知日期做连续区间核对,二者不能混为一个指标。
我会把这个方案用于“签到是否连续”而不是奖励账本。需要记录补签原因、时间戳或多种状态时,应增加明细表或 Hash;Bitmap 的优势是位密度高、读写简单,代价是表达能力有限。
相关问题
Bitmap 能直接统计连续天数吗?不能。它能存位和统计 1 的总数,连续天数需要从截止日扫描相邻位。
为什么不每天调用一次 GETBIT?用户量大时网络往返会成为主要成本,按月读位图后在内存扫描更适合批处理。
复用切片一定更快吗?不一定。它只减少可观的临时分配,仍应配合基准测试和客户端生命周期约束验证。
Redis Bitmap怎样统计每日签到的连续天数为什么结果为空或不符合预期
- 上一篇
- Redis Bitmap怎样统计每日签到的连续天数为什么结果为空或不符合预期
- 下一篇
- Redis HyperLogLog估算独立访客数时为什么存在误差怎样完成一个可复用的最小示例
-
- 数据库 · Redis | 13分钟前 | Redis · 事务 · 集群 · 故障排查 · redis Redis Cluster CROSSSLOT Hash Tag CLUSTER KEYSLOT 多键事务
- Redis Cluster hash tag多键事务为什么没有落到同一节点为什么结果为空或不符合预期
- 480浏览 收藏
-
- 数据库 · Redis | 16分钟前 |
- Redis Cluster hash tag多键事务为什么没有落到同一节点怎样完成一个可复用的最小示例
- 255浏览 收藏
-
- 数据库 · Redis | 19分钟前 |
- Redis GEO怎样按距离查询附近门店并控制结果数怎样在批处理代码中减少额外分配
- 227浏览 收藏
-
- 数据库 · Redis | 22分钟前 |
- Redis GEO怎样按距离查询附近门店并控制结果数为什么结果为空或不符合预期
- 357浏览 收藏
-
- 数据库 · Redis | 31分钟前 |
- Redis HyperLogLog估算独立访客数时为什么存在误差怎样在批处理代码中减少额外分配
- 397浏览 收藏
-
- 数据库 · Redis | 34分钟前 |
- Redis HyperLogLog估算独立访客数时为什么存在误差为什么结果为空或不符合预期
- 346浏览 收藏
-
- 数据库 · Redis | 37分钟前 |
- Redis HyperLogLog估算独立访客数时为什么存在误差怎样完成一个可复用的最小示例
- 449浏览 收藏
-
- 数据库 · Redis | 50分钟前 |
- Redis Bitmap怎样统计每日签到的连续天数怎样完成一个可复用的最小示例
- 363浏览 收藏
-
- 数据库 · Redis | 2天前 | redis redis_version 版本兼容 COMMAND DOCS Redis 8.10 命令文档
- Redis 8.10 命令文档怎样按版本查看
- 275浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 965次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 965次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 1077次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 1055次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 887次使用
-
- Redis Stream XTRIM 如何避免消费组积压无限增长
- 2026-09-12 501浏览
-
- Redis AOF rewrite 期间如何判断磁盘与内存压力
- 2026-09-12 501浏览
-
- Redis RDB 和 AOF 怎么按可接受数据丢失量选择
- 2026-09-08 501浏览
-
- Redis XAUTOCLAIM 之后为什么仍有 pending:JUSTID、PEL 与消息删除边界
- 2026-08-29 501浏览
-
- Redis SET 的 GET 与 KEEPTTL 怎么一起验收:旧值返回、续期与回滚边界
- 2026-08-20 501浏览

