0

0

Redis如何记录用户连续签到_通过Bitmap的SETBIT指令高效存储状态

P粉602998670

P粉602998670

发布时间:2026-03-16 09:02:31

|

850人浏览过

|

来源于php中文网

原创

Bitmap用1bit存每日签到状态,1万用户年数据仅13KB,String存“1”/“0”需3.6MB;需按年分key、用BITPOS+BITCOUNT算连续天数,offset须为小整数且避免客户端溢出。

redis如何记录用户连续签到_通过bitmap的setbit指令高效存储状态

SETBIT 存连续签到为什么比用 String 或 Hash 节省 90%+ 内存

因为 Bitmap 把每个用户每天的签到状态压缩成 1 个 bit,1 万个用户一年签到数据不到 13KB;而用 String 存 “1”/“0” 字符串,光一年就要近 3.6MB,差两个数量级。

实际用法是:以用户 ID 为 key,日期偏移量为 offset,调用 SETBIT 标记当天是否签到:

SETBIT user:sign:1001 0 1   # 第 0 天(比如 2024-01-01)签到
SETBIT user:sign:1001 1 1   # 第 1 天(2024-01-02)签到
SETBIT user:sign:1001 5 0   # 第 5 天未签到
  • offset 从 0 开始,建议统一用「距基准日的天数」计算,比如基准日定为 2024-01-01,那么 2024-01-10 对应 offset = 9
  • 不要用日期字符串(如 "20240110")当 offset —— SETBIT 只接受整数,非数字会报错 (error) ERR bit is not an integer or out of range
  • Redis 默认对不存在的 key 自动创建,但位图长度按需扩展;高位未设置的 bit 默认为 0,GETBIT 查询时无需预初始化整段

查连续签到天数得用 BITPOS + BITCOUNT 组合,不能只靠 GETBIT

GETBIT 只能查单日状态,要算「当前最长连续签到」必须定位到最近一个 0 的位置,再减去上一个 0 的位置 —— 这事得靠 BITPOS 扫描。

典型做法是:从今天往前找第一个未签到日(即值为 0 的 bit),再用 BITCOUNT 统计这段区间内 1 的个数:

Gambo
Gambo

世界上首个游戏氛围编程智能体

下载
BITPOS user:sign:1001 0 -1    # 从末尾向前找第一个 0,返回 offset
BITCOUNT user:sign:1001 0 9   # 统计 offset 0 到 9(共 10 天)里有几个 1
  • BITPOS key 0 -1 中的 -1 表示从右往左扫描,适合查「最近断签日」;若用正数(如 100),则只在前 100 位里找
  • BITCOUNT 的 range 参数是字节范围,不是 bit 偏移!如果想统计第 5~14 天(共 10 天),offset 是 5~14,对应字节范围是 5/814/8 向上取整,容易算错 —— 更稳妥是用 Lua 脚本封装逻辑
  • 注意:BITPOS 找不到目标值时返回 -1,别直接拿它做减法,否则连续天数变成负数

跨年或长期运行时,key 过期和分片必须手动处理

Bitmap 不支持按 bit 设置过期,整个 key 只能共用一个 TTL。签到数据若跨多年,不清理旧 key 会导致内存持续增长,且 BITCOUNT 会把历史无效位全算进去。

  • 方案一:按年分 key,比如 user:sign:1001:2024user:sign:1001:2025,每年初用 EXPIRE 设 366 天过期
  • 方案二:用 BITFIELD 配合 INCRBY 记录最后签到日,再结合定时任务清理早于某日期的 key —— 但 BITFIELD 不支持位图区间清零,删 key 是最干脆的方式
  • 切记:不要依赖 Redis 自动淘汰策略来“保活”签到 key,LRU/LFU 对 bitmap 无效,冷 key 仍占内存

PHP/Python 客户端调用 SETBIT 时,offset 超过 2³²−1 会静默失败

Redis 协议限制 SETBIT 的 offset 最大为 2^32 - 1(约 42.9 亿),换算成天数就是 1170 万年 —— 理论够用,但客户端语言可能提前截断。

  • PHP 的 redis->setBit() 在 32 位系统或某些旧扩展里,传入大整数会被转成 float,导致精度丢失,SETBIT key 2147483648 1 可能变成 SETBIT key 2147483647 1
  • Python 的 redis-py 通常没问题,但若用 int(time.time()) 直接当 offset(误以为是时间戳),会远超范围 —— offset 必须是小整数(建议控制在 0~1095 内,即三年)
  • 调试技巧:用 DEBUG OBJECT key 查看底层编码是否为 raw(正常)或 embstr(小 key 优化),异常时可能是 offset 写崩了结构

offset 算错、key 没分年、客户端整数溢出 —— 这三处出问题,表现都是查不到签到记录或连续天数突然归零,但错误日志里几乎不报,得靠 BITCOUNTSTRLEN 对比验证位图实际长度。

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1071

2023.08.02

css中float用法
css中float用法

css中float属性允许元素脱离文档流并沿其父元素边缘排列,用于创建并排列、对齐文本图像、浮动菜单边栏和重叠元素。想了解更多float的相关内容,可以阅读本专题下面的文章。

597

2024.04.28

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

108

2025.10.23

scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

513

2023.10.18

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

384

2023.10.25

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

761

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

221

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1570

2023.10.24

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

69

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号