登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  数据库 >  Redis

Redis Bitmap 用户签到实战:SETBIT、GETBIT 和 BITCOUNT 怎么用

来源:17golang原创

时间:2026-06-13 17:44:19 464浏览 收藏

用户签到是很常见的活动功能:今天是否签到、这个月签了几天、是否连续签到。用普通集合或明细表当然能做,但如果只是保存“某一天是否签到”这种布尔状态,Redis Bitmap 会更轻量。

Bitmap 本质上是把字符串当成一排二进制位来用。一个用户一个月份只需要几十个位,就能表达整月签到状态,非常适合签到、打卡、活跃天数这类场景。

适合人群

适合正在做签到、活跃统计、轻量状态标记的后端开发者。你需要了解 Redis 基本命令和 key 设计。

目录

  • 签到数据怎么设计成 Bitmap
  • 用 SETBIT 写入当天签到
  • 用 GETBIT 查询当天状态
  • 用 BITCOUNT 统计月签到天数
  • 连续签到和常见坑位

签到数据怎么设计成 Bitmap

一个简单的 key 设计可以按用户和月份拆分:

sign:{user_id}:{yyyyMM}

示例:
sign:10086:202606

月份里的第几天可以转换成位偏移。例如 6 月 1 日是偏移 0,6 月 13 日是偏移 12。当天签到就把对应位置为 1,没签到就是 0

Redis Bitmap 用户签到写入流程:用户签到、计算偏移、SETBIT 写入、位图行保存、GETBIT 查询状态

用 SETBIT 写入当天签到

写入签到状态时,只需要把对应偏移位设置为 1

SETBIT sign:10086:202606 12 1

这个命令表示:用户 10086 在 2026 年 6 月第 13 天已签到。为了减少重复签到带来的业务争议,可以先用 GETBIT 判断今天是否已经签过,再决定是否发放奖励。

GETBIT sign:10086:202606 12

返回 1 说明今天已签到,返回 0 说明还没有签到。

用 BITCOUNT 统计月签到天数

统计这个月签了几天,直接用 BITCOUNT

BITCOUNT sign:10086:202606

Redis 会统计这个 key 里值为 1 的位数量。对于一个月 31 天以内的签到状态,这种统计非常直接,也不用把每天明细全部取回应用层再循环判断。

Redis Bitmap 月度统计流程:月度位图进入 BITCOUNT,得到签到天数,再结合倒序检查计算连续签到

连续签到怎么计算

连续签到通常从今天往前倒着查,遇到第一个 0 就停止。比如今天是第 13 天,可以从偏移 12 开始往前检查:

def continuous_days(redis_client, key: str, today_offset: int) -> int:
    days = 0
    for offset in range(today_offset, -1, -1):
        signed = redis_client.getbit(key, offset)
        if signed != 1:
            break
        days += 1
    return days

如果只做月内连续签到,这段逻辑已经足够清楚。若要跨月连续,就需要在查到当月第 1 天仍然签到时,继续切到上个月的 key 往前查。

常见坑位和上线建议

1. 偏移从 0 开始

第 1 天对应偏移 0,不是 1。这点很容易写错,建议把“日期转偏移”的逻辑封装成函数并加单元测试。

2. key 要设置合理过期时间

如果只查最近几个月的签到,可以给月度 key 设置较长过期时间,例如保留 12 到 18 个月。历史数据需要长期留存时,再考虑异步归档到数据库。

3. 重复签到要在业务层处理

SETBIT 会返回旧值。旧值如果已经是 1,说明用户重复签到,此时不要重复发奖励。

4. 统计口径要提前定好

活动页常见口径有“本月签到天数”“连续签到天数”“累计签到天数”。Bitmap 很适合月度和短周期状态统计,累计长期总数可以配合普通计数器或数据库明细一起维护。

小结

Redis Bitmap 适合保存大量布尔状态。用户签到场景里,用 SETBIT 写入当天状态,用 GETBIT 判断是否已签到,用 BITCOUNT 统计月签到天数,既节省空间,也能保持命令逻辑简单。真正上线时,重点关注偏移计算、重复签到奖励和历史数据保留策略。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>