Redis Bitmap 签到与 HyperLogLog UV 统计
Redis Bitmap 签到与 UV 统计
当数据能表达为“某位置是否发生过”时,位图可以用很少的空间保存大量布尔状态。用户每日是否签到、活动是否参与过,都可以映射成某个 bit。独立访客 UV 则是另一类问题:需要对大量用户去重,适合考虑 HyperLogLog 这类近似计数结构。
1. 用 Bitmap 保存签到
一个常见设计是每个用户每月一张位图:键名包含用户和年月,日期偏移量对应某一天。比如把 1 号映射到 offset 0,31 号映射到 offset 30。
1 | |
按月拆键能让键的语义和生命周期更清晰。写代码时要处理月份长度、时区和日期边界;签到规则如果允许补签,还要单独定义可修改范围。
2. 连续签到天数
把当月位图按日期读取后,从今天或昨天开始向前检查连续的 1,即可计算连续签到天数。若用 BITFIELD 一次读取多个位,注意位偏移方向和字节序;初学时可以先读取后在应用中按明确的日期顺序计算,并用跨月例子验证。
3. UV 与 HyperLogLog
精确统计某段时间内的唯一用户,可以用集合保存用户标识并查询集合基数,但内存随用户数量增长。HyperLogLog 使用概率算法估算基数,内存开销较小,但结果有误差,适合总体 UV 估算,不适合需要精确名单或逐个判断用户是否访问过的场景。
每日统计可以按日期设置键,例如 stats:uv:2026-10-17,把经过业务定义的匿名访客标识加入 HyperLogLog,再读取估算基数。标识应避免直接存储可识别个人的信息;跨日合并和隐私保留策略也要按业务需要设计。
4. 选择结构前先问的问题
| 需求 | 合适的思路 |
|---|---|
| 判断某用户某天是否签到 | Bitmap |
| 统计某用户当月签到次数 | Bitmap 的位统计 |
| 精确列出签到用户 | Set 或数据库记录 |
| 估算大量访客的去重总数 | HyperLogLog |
| 精确判断某用户是否访问过 | Set、数据库或其他精确索引 |
5. 小结
Bitmap 适合把离散事件映射到紧凑的位序列;HyperLogLog 适合低内存的近似去重计数。两者解决的问题不同,不能因为都“省空间”就互相替代。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 GuMing的殿堂!
评论




