Redis bitmap应用
Redis bitmap应用
-
需求:存储用户今年已签到的天数,如在1月3日签到,则存 3 。。。以此类推
-
每秒300次请求压力测试
1、使用数据库存储
查询代码与时间
-
public List<Integer> selectSignRecord(long userId, Integer year) { if (year == null) { year = LocalDate.now().getYear(); } int currentYear = LocalDate.now().getYear(); if (year != currentYear) { throw new BusinessException(ErrorCode.PARAMS_ERROR, "年份不是当前年份"); } //查询签到记录 QueryWrapper<UserSign> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("userId", userId); queryWrapper.select("signDay"); List<Integer> result = userSignMapper.selectObjs(queryWrapper) .stream() .filter(Objects::nonNull) // 确保过滤掉可能的 null 值 .map(item -> Integer.parseInt(item.toString())) // 转换为 Integer .collect(Collectors.toList()); return result; } }
-
耗时最少时间:879ms
2、使用Redis中的bitmap存储
查询代码与时间
-
@Override public List<Integer> selectSignRecord(long userId, Integer year) { if (year == null) { year = LocalDate.now().getYear(); } int currentYear = LocalDate.now().getYear(); if (year != currentYear) { throw new BusinessException(ErrorCode.PARAMS_ERROR, "年份不是当前年份"); } // 拼接签到记录的key String key = RedisConstant.getUserSignKey(year, userId); // 获取redis中的bitset RBitSet bitSet = redissonClient.getBitSet(key); // 获取bitset中的所有值 BitSet signInBitSet = bitSet.asBitSet(); // 构造返回结果,保证返回值有序 List<Integer> result = new ArrayList<>(); // 获取当前bitset中已签到的天数 // 从第一个被设置为1的位置开始遍历,直到没有被设置为1的位置 int index = signInBitSet.nextSetBit(0); while (index >= 0) { result.add(index); // 获取下一个被设置为1的位置 index = signInBitSet.nextSetBit(index + 1); } return result; }
-
耗时最少时间:292ms,190条数据查询,平均响应时间减少了:61.7%,提升还是蛮大的