如何在Redis中使用BitMap实现亿级用户的每日签到功能

雨浩姑娘_9299

雨浩姑娘_9299

2026-09-20

427人浏览

原创

bitmap在redis中通过setbit命令存签到数据,以日期为key(如sign:20240410)、用户id映射的非负整数为offset、签到状态(0或1)为值;offset必须是紧凑唯一整数,禁用字符串或稀疏id以防错误或空间浪费;统计当日签到人数用bitcount key,亿级用户需按日分片、合理设置过期并避免单key过大。

如何在redis中使用bitmap实现亿级用户的每日签到功能

BitMap在Redis里怎么存签到数据

直接用 SETBIT 存,用户ID作为偏移量(offset),当天是否签到为值(0 或 1)。比如用户ID为12345,今天是今年第100天,就执行:

SETBIT sign:20240410 12345 1
。注意:sign:20240410 是key,按日期分片;12345 是偏移量,不是用户ID字符串,必须转成整数且全局唯一、非负、尽量紧凑。

为什么不能直接用用户ID字符串当offset

因为 SETBIT 的 offset 参数只接受非负整数,最大支持约 2³²−1(约42亿),但必须是数字类型。如果用户ID是UUID或带字母的字符串,SETBIT 会报错 (error) ERR bit offset is not an integer or out of range。常见踩坑点:

  • hash(userId) % N 做映射 → 可能冲突,导致A和B用户签到互相覆盖
  • 用数据库自增ID直接当offset → 看似可行,但如果ID稀疏(比如删过大量用户),位图空间浪费严重,1亿用户实际占用可能远超12.5MB
  • 没做ID归一化,不同业务线用户ID重复 → offset 冲突,签到状态错乱

如何统计某天有多少人签到

BITCOUNT 最直接:

Redis Skill - 高性能缓存管理
Redis Skill - 高性能缓存管理

Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。

下载
BITCOUNT sign:20240410
。它返回该key下所有bit为1的数量,就是当日签到总人数。但要注意:
  • 如果key不存在,BITCOUNT 返回0,不会报错,适合日常统计
  • 不要对超大key(比如偏移量跨度几亿)频繁调用 BITCOUNT,虽然O(N)但N是内存中已分配的字节长度,不是逻辑用户数;若用户ID稀疏,Redis仍需扫描整个分配区域
  • 想查「连续签到7天」?不能只靠单个key,得组合多个日期key用 BITOP AND,再 BITCOUNT,但要注意key数量多时延迟上升

亿级用户下Key设计和内存控制的关键点

一个key存一天,比用一个key存所有日期更可控。否则单key位图过大(比如存365天 × 1亿用户 ≈ 4.5GB),不仅内存爆炸,BITCOUNTBITOP 都变慢,且无法过期清理某天数据。

  • key命名建议用 sign:{yyyymmdd},方便用 SCAN 批量清理过期key
  • 每天凌晨用 EXPIRE sign:20240409 2592000(30天)自动过期,避免手动删
  • 如果用户量真到上亿,且ID不连续,可考虑分桶:比如按 userId % 100 分100个子key,sign:20240410:00sign:20240410:99,查总数时用 BITOP OR 合并再统计,平衡单key大小与操作复杂度

真正难的不是命令怎么写,而是ID映射策略和key生命周期管理——这两处出问题,后面所有统计都不可信。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

redis

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

相关专题

更多
golang map内存释放
golang map内存释放

本专题整合了golang map内存相关教程,阅读专题下面的文章了解更多相关内容。

2025.09.05

390

5

golang map相关教程
golang map相关教程

本专题整合了golang map相关教程,阅读专题下面的文章了解更多详细内容。

2025.11.16

323

7

golang map原理
golang map原理

本专题整合了golang map相关内容,阅读专题下面的文章了解更多详细内容。

2025.11.17

473

20

java判断map相关教程
java判断map相关教程

本专题整合了java判断map相关教程,阅读专题下面的文章了解更多详细内容。

2025.11.27

223

6

常用的数据库软件
常用的数据库软件

常用的数据库软件有MySQL、Oracle、SQL Server、PostgreSQL、MongoDB、Redis、Cassandra、Hadoop、Spark和Amazon DynamoDB。更多关于数据库软件的内容详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.02

3969

19

内存数据库有哪些
内存数据库有哪些

内存数据库有Redis、Memcached、Apache Ignite、VoltDB、TimesTen、H2 Database、Aerospike、Oracle TimesTen In-Memory Database、SAP HANA和ache Cassandra。更多关于内存数据库相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.14

3435

11

mongodb和redis哪个读取速度快
mongodb和redis哪个读取速度快

redis 的读取速度比 mongodb 更快。原因包括:1. redis 使用简单的键值存储,而 mongodb 存储 json 格式的数据,需要解析和反序列化。2. redis 使用哈希表快速查找数据,而 mongodb 使用 b-tree 索引。因此,redis 在需要高性能读取操作的应用程序中是一个更好的选择。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.02

6092

6

redis怎么做缓存服务器
redis怎么做缓存服务器

redis 作为缓存服务器的答案:redis 是一款开源、高性能、分布式的键值存储,可作为缓存服务器使用。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.07

583

6

redis怎么解决数据一致性
redis怎么解决数据一致性

redis 提供了两种一致性模型,以维护副本数据一致性:强一致性 (sync) 确保写操作仅在复制到所有从节点后才完成;最终一致性 (async) 则在主节点上写操作后认为已完成,牺牲一致性换取性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.07

696

6

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
phpEnv手册
phpEnv手册

共0课时 | 0人学习

进程与SOCKET
进程与SOCKET

共6课时 | 0.5万人学习