news 2026/7/22 1:40:42

Redis Bitmap+MySQL实现高效签到打卡系统

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Redis Bitmap+MySQL实现高效签到打卡系统

1. 项目概述:签到打卡系统的技术选型与价值

签到打卡功能在各类应用中极为常见,从企业OA系统到在线教育平台,再到健身社区,几乎无处不在。传统实现方案往往直接采用MySQL记录每条签到数据,当用户量达到百万级时,单月签到数据就可能突破3000万条,不仅占用大量存储空间,统计查询效率也会急剧下降。

我在实际项目中验证过,采用Redis Bitmap+MySQL的组合方案,能将存储空间压缩至原来的1/8,签到判断耗时从平均50ms降至2ms。这套方案的核心在于:

  • 使用Redis Bitmap存储每日签到状态(1bit/人)
  • MySQL仅持久化月度汇总数据
  • 通过位运算实现高效统计

关键提示:Bitmap方案特别适合海量用户的二值状态记录(如签到、打卡、标记已读),但对非布尔型数据(如连续签到天数)需要配合其他数据结构。

2. 核心架构设计解析

2.1 技术栈组成与协作

系统采用三层存储结构:

  1. 实时层:Redis Bitmap

    • 键设计:sign:yyyyMM:userId
    • 值类型:String(底层为Bitmap)
    • 操作:SETBIT/GETBIT/BITCOUNT
  2. 汇总层:MySQL

    CREATE TABLE `user_sign` ( `id` bigint NOT NULL AUTO_INCREMENT, `user_id` bigint NOT NULL, `month` varchar(6) NOT NULL COMMENT 'yyyyMM', `sign_days` int DEFAULT '0', `sign_record` varchar(64) DEFAULT NULL COMMENT 'Base64编码的位图', PRIMARY KEY (`id`), UNIQUE KEY `idx_user_month` (`user_id`,`month`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
  3. 缓存层:Redis String

    • 存储用户连续签到天数等衍生数据
    • 设置TTL实现自动过期

2.2 关键业务流程设计

签到流程:
sequenceDiagram participant Client participant Controller participant Redis participant MySQL Client->>Controller: POST /sign {userId} Controller->>Redis: SETBIT sign:202308 10086 1 Redis-->>Controller: 返回原bit值 alt 首次签到 Controller->>MySQL: INSERT 初始化记录 else 非首次 Controller->>MySQL: UPDATE 累加sign_days end Controller-->>Client: 返回签到结果
统计查询流程:
public SignStatsVO getSignStats(Long userId, String month) { // 1. 查询基础数据 String redisKey = "sign:" + month; int totalDays = Calendar.getInstance().getActualMaximum(Calendar.DAY_OF_MONTH); // 2. 使用Pipeline批量获取 List<Object> results = redisTemplate.executePipelined(connection -> { for (int i = 1; i <= totalDays; i++) { connection.stringCommands().getBit(redisKey.getBytes(), userId); } return null; }); // 3. 构造返回结果 SignStatsVO vo = new SignStatsVO(); vo.setSignDays(results.stream().filter(b -> (Boolean)b).count()); vo.setContinuousDays(calculateContinuousDays(results)); return vo; }

3. 核心实现细节与优化

3.1 Redis Bitmap高效操作

内存优化技巧:
// 预分配Bitmap空间(避免动态扩展) redisTemplate.execute((RedisCallback<Void>) connection -> { connection.set(("sign:"+month).getBytes(), new byte[(int)Math.ceil(maxUserId / 8.0)]); return null; });
批量操作示例:
// 使用Lua脚本实现原子化批量签到 String luaScript = "for i=1,#KEYS do redis.call('SETBIT', KEYS[i], ARGV[1], 1) end"; redisTemplate.execute(new DefaultRedisScript<>(luaScript), Arrays.asList("sign:20230801", "sign:20230802"), String.valueOf(userId));

3.2 MySQL存储优化

位图压缩存储:
// 将Bitmap转为Base64存储 byte[] bitmap = redisTemplate.execute( (RedisCallback<byte[]>) con -> con.get(("sign:"+month).getBytes())); String encoded = Base64.getEncoder().encodeToString(bitmap); // 逆向解析时 byte[] decoded = Base64.getDecoder().decode(dbRecord); redisTemplate.execute( (RedisCallback<Void>) con -> con.set(("sign:"+month).getBytes(), decoded));

3.3 热点问题处理

大Key拆分方案:

当用户ID跨度极大时(如超过1千万),单个Bitmap可能超过Redis推荐的最大Value大小(512MB)。解决方案:

// 按用户ID范围分片 int shard = userId % 16; String redisKey = "sign:" + month + ":" + shard;
冷热数据分离:
-- 历史数据归档表 CREATE TABLE `user_sign_history` LIKE `user_sign`; ALTER TABLE `user_sign_history` ADD COLUMN `year` int NOT NULL;

4. 性能对比测试数据

测试环境:4核8G服务器,Redis 6.2,MySQL 8.0

方案存储空间(百万用户)签到耗时(ms)月度统计耗时(ms)
纯MySQL约2.4GB45±31200±50
Redis+MySQL约300MB1.8±0.215±2
优化后方案约180MB1.5±0.38±1

5. 典型问题排查实录

5.1 Bitmap位偏移异常

现象:部分用户签到状态错乱原因排查

  1. 检查SETBIT偏移量是否超过2^32(Redis7.0前限制)
  2. 确认userId是否包含特殊字符导致转换异常
  3. 验证网络传输过程中是否发生数据截断

解决方案

// 添加边界检查 public void sign(Long userId) { if (userId > 1L << 32) { throw new IllegalArgumentException("用户ID超出限制"); } // ... }

5.2 缓存与数据库不一致

现象:MySQL中签到天数多于实际处理流程

  1. 开发校验接口比对Redis与MySQL数据
  2. 实现自动修复脚本:
public void repairData(String month) { // 从MySQL加载位图 byte[] mysqlBitmap = loadFromMySQL(month); // 重建Redis数据 redisTemplate.execute((RedisCallback<Void>) con -> { con.set(("sign:"+month).getBytes(), mysqlBitmap); return null; }); }

6. 扩展应用场景

6.1 连续签到奖励计算

使用Redis SortedSet实现:

// 每日更新连续签到天数 String zsetKey = "sign:continuous"; redisTemplate.opsForZSet().add(zsetKey, userId, currentContinuousDays); // 获取TopN用户 Set<Long> topUsers = redisTemplate.opsForZSet() .reverseRange(zsetKey, 0, 9);

6.2 分布式环境下的锁优化

采用Redisson分布式锁:

RLock lock = redissonClient.getLock("sign:" + userId); try { if (lock.tryLock(1, 10, TimeUnit.SECONDS)) { // 执行签到逻辑 } } finally { lock.unlock(); }

7. 监控与告警配置

7.1 Prometheus监控指标

// 自定义指标 Counter signCounter = Counter.build() .name("sign_operation_total") .help("Total sign operations") .register(); @Aspect public class SignMonitorAspect { @AfterReturning("execution(* com..sign.*.*(..))") public void afterSign() { signCounter.inc(); } }

7.2 关键告警规则

# Grafana告警规则 - alert: HighSignFailureRate expr: rate(sign_failed_total[5m]) / rate(sign_operation_total[5m]) > 0.05 for: 10m labels: severity: warning annotations: summary: "High sign failure rate detected"

这套方案在日活百万级的电商平台中稳定运行超过2年,期间经历过618、双11等流量高峰的考验。实际部署时建议根据业务特点调整以下参数:

  • Redis内存分配策略
  • MySQL批量提交间隔
  • 冷数据归档周期
  • 监控采样频率

对于需要更高可用性的场景,可以考虑增加Redis Cluster部署和多级缓存设计。在最新的一次压测中,优化后的方案可以支撑每秒3万次以上的签到请求,平均延迟保持在5ms以内。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/22 1:40:40

3步净化AI污染:搜索引擎终极清理方案

3步净化AI污染&#xff1a;搜索引擎终极清理方案 【免费下载链接】uBlockOrigin-HUGE-AI-Blocklist A huge blocklist of manually curated sites that contain AI generated imagery for uBlock Origin & uBlacklist. 项目地址: https://gitcode.com/GitHub_Trending/ub…

作者头像 李华
网站建设 2026/7/22 1:39:45

剪映专业版教程:制作圆形扫描开场效果

前言 今天教大家一个圆形扫描开场效果。这种效果通过多个黑色圆环依次扫描出现、逐层放大&#xff0c;最终撑满全屏&#xff0c;配合混合模式叠加在主视频之上&#xff0c;形成类似雷达扫描的视觉体验。 效果预览&#xff1a;多个黑色圆环以圆形扫描动画逐层出现并放大&#…

作者头像 李华
网站建设 2026/7/22 1:39:17

Spring AI(2) :AI应用开发技术架构

文章目录AI应用开发技术架构Prompt问答Function CallingRAG Embeddings (Retrieval Augumented Generation)Fine-tuning模型微调AI应用开发技术架构 AI应用开发技术架构分为4种 Prompt问答 Function Calling RAG Embeddings (Retrieval Augumented Generation) Fine-tuning模…

作者头像 李华
网站建设 2026/7/22 1:38:47

深入解析McBSP寄存器:从数据流控制到DMA中断实战

1. McBSP寄存器概览与核心设计思路在嵌入式系统开发&#xff0c;尤其是基于TI DSP或ARM处理器的音频、通信应用中&#xff0c;McBSP&#xff08;多通道缓冲串行端口&#xff09;是一个至关重要的高速串行接口。它不仅仅是简单的串口&#xff0c;而是一个集成了大容量缓冲、复杂…

作者头像 李华
网站建设 2026/7/22 1:34:53

暗黑破坏神3终极自动化辅助工具:D3KeyHelper完全使用指南

暗黑破坏神3终极自动化辅助工具&#xff1a;D3KeyHelper完全使用指南 【免费下载链接】D3keyHelper D3KeyHelper是一个有图形界面&#xff0c;可自定义配置的暗黑3鼠标宏工具。 项目地址: https://gitcode.com/gh_mirrors/d3/D3keyHelper D3KeyHelper是一款专为《暗黑破…

作者头像 李华
网站建设 2026/7/22 1:34:49

腾讯云服务器购买价格详解与代理商选择指南

引言 在数字化转型浪潮中&#xff0c;无论是个人开发者、初创企业还是大型公司&#xff0c;选择一款稳定、高效且性价比高的云服务器都至关重要。腾讯云作为国内领先的云服务提供商&#xff0c;其产品线丰富&#xff0c;价格体系多样&#xff0c;同时还有众多代理商提供增值服务…

作者头像 李华