讲师中心 微信公众号
AI工具推荐 视频效率加速

如何在Redis中用Lua脚本实现基于Bitmap的活跃用户统计?

胖丽吖_2441

胖丽吖_2441

发布时间:2026-09-19 06:00:28

|

576人浏览过

|

来源于php中文网

原创

不能直接用SETBIT+BITCOUNT完事,因“判断是否首次活跃”需读-判-写三步原子化,而GETBIT返回0时并发SETBIT会导致重复计数;必须用Lua脚本将逻辑封装为原子操作,如EVAL中先GETBIT再SETBIT并返回新老标识与统计值。

如何在redis中用lua脚本实现基于bitmap的活跃用户统计?

为什么不能直接用 SETBIT + BITCOUNT 就完事?

因为并发写入时,多个客户端同时对同一个 bitmap 位做 SETBIT key offset 1,虽然操作本身是原子的,但「判断用户是否首次活跃」这个逻辑无法原子化。比如两个请求同时发现 GETBIT key offset 返回 0,都会执行 SETBIT,导致重复计数或业务误判。必须把「读-判-写」三步收进一个 Lua 脚本里。

EVAL 脚本里怎么安全设置位并返回是否为新用户?

核心是用 redis.call("GETBIT", ...) 先查,再用 redis.call("SETBIT", ...) 写,全程在服务端原子执行。注意:Lua 中 bitmap 的 offset 是 number 类型,不能传字符串;key 名建议带日期前缀(如 "active:20240615")方便归档。

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

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

下载
  • 脚本返回值建议用 {is_new = 1, old_count = N} 这类 table,但 Redis 只支持返回 number/string/boolean/table → 实际要用 return {new_flag, old_count},客户端按顺序取
  • 避免在脚本里调用耗时命令(如 KEYS),否则阻塞整个 Redis
  • 如果 key 不存在,GETBIT 默认返回 0,不用提前 SET
eval "local b = redis.call('GETBIT', KEYS[1], ARGV[1]); if b == 0 then redis.call('SETBIT', KEYS[1], ARGV[1], 1) end; local c = redis.call('BITCOUNT', KEYS[1]); return {b == 0 and 1 or 0, c}" 1 active:20240615 12345

统计日活时,BITCOUNT 的性能和精度要注意什么?

BITCOUNT 是 O(N) 复杂度,但 Redis 对 bitmap 做了优化(如稀疏 bitmap 使用 run-length encoding),实际在百万级用户、单 key 占几 MB 的情况下仍很快(通常

  • 不要对跨天的 key 做 BITOP AND/OR 后再 BITCOUNT——这会生成新 key,内存翻倍且不可控
  • 如果需小时级统计,别用单个 key 存全天,改用 active:20240615:hour12 分片,用 BITOP OR 合并时显式指定目标 key 避免覆盖
  • Bitmap 最大支持 2^32 位(约 42.9 亿),用户 ID 超过此范围需哈希映射到合法 offset(如 user_id % 4294967296),但会引入哈希冲突,慎用

如何避免 Lua 脚本被频繁重载影响性能?

每次 EVAL 都要解析脚本,高并发下开销明显。应该用 EVALSHA + SCRIPT LOAD 缓存脚本 SHA1。但注意:SCRIPT FLUSH 会清空所有缓存,运维操作可能意外触发;生产环境建议用 redis.register_script(Python redis-py)或 ScriptingCommands.evalSha(Java Lettuce)自动管理。

  • 脚本内容变更后,SHA1 改变,旧 EVALSHA 会报错 (error) NOSCRIPT No matching script. Please use EVAL.,需捕获该错误并 fallback 到 EVAL
  • Redis Cluster 下,key 必须落在同一 slot,所以 KEYS[1] 要确保 hash tag,例如用 {active}:20240615 让所有日期 key 落同一 slot
实际部署时,最易被忽略的是 offset 映射的可靠性——用户 ID 直接当 offset 用只适用于 ID 稳定且稀疏度可控的场景;ID 过大或分布不均时,必须加一层布隆过滤器或分桶映射,否则 bitmap 浪费严重或触发 Redis 内存上限。

热门AI工具

更多
讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

Lovart
Lovart Hot

一款面向视觉设计创作的AI设计平台,可通过智能体和画布工作流辅助制作海报、Logo、网页、PPT及其他视觉内容。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

相关专题

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

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

390

2025.09.05

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

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

323

2025.11.16

golang map原理
golang map原理

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

473

2025.11.17

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

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

223

2025.11.27

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

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

3969

2023.11.02

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

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

3435

2023.11.14

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

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

6092

2024.04.02

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

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

583

2024.04.07

AI视频生成软件推荐
AI视频生成软件推荐

本专题汇总了当前主流的AI视频生成软件推荐与排行榜单,涵盖seko、AniShort、剧云、Lovart、LiblibAI及立刻mv等热门工具。同时整理了各软件在文生视频、图生视频、时长限制、画质表现及免费额度等方面的差异对比,助您快速选对适合创作需求的AI视频生成工具。

140

2026.09.16

热门下载

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

精品课程

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

共0课时 | 0人学习

进程与SOCKET
进程与SOCKET

共6课时 | 0.5万人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn