当前位置:首页 > 文章列表 > 数据库 > Redis > Redis Bitmap怎样统计每日签到的连续天数怎样在批处理代码中减少额外分配

Redis Bitmap怎样统计每日签到的连续天数怎样在批处理代码中减少额外分配

来源:17golang原创 2026-11-10 01:00:00 0浏览 收藏

我把签到统计做成批处理后,最稳妥的做法是:用 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 日期偏移与 Redis Bitmap 位状态的关系说明图
图1:Redis Bitmap 的日期偏移与签到位关系说明图,不是运行截图。
对象示例作用
keysignin:42:2026-11隔离用户和月份
offsetday-1定位某一天的 bit
value0 或 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 客户端返回的字节直接交给扫描函数。不要为了“零分配”牺牲可读性,先用基准测试确认热点。

批处理循环复用日期缓冲区和 Bitmap 字节缓冲区的路径说明图
图2:批量计算连续签到天数时复用缓冲区的处理路径说明图,不是运行截图。
// 复用固定容量的 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?用户量大时网络往返会成为主要成本,按月读位图后在内存扫描更适合批处理。

复用切片一定更快吗?不一定。它只减少可观的临时分配,仍应配合基准测试和客户端生命周期约束验证。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Redis Bitmap怎样统计每日签到的连续天数为什么结果为空或不符合预期Redis Bitmap怎样统计每日签到的连续天数为什么结果为空或不符合预期
上一篇
Redis Bitmap怎样统计每日签到的连续天数为什么结果为空或不符合预期
Redis HyperLogLog估算独立访客数时为什么存在误差怎样完成一个可复用的最小示例
下一篇
Redis HyperLogLog估算独立访客数时为什么存在误差怎样完成一个可复用的最小示例
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    965次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    965次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    1077次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    1055次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    887次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码