Implementing Sign‑in and Statistics with Redis BitMap in Spring Boot
This article explains how to implement a user sign‑in feature and its statistical analysis using Redis BitMap within a Spring Boot backend, covering basic BitMap commands, integration steps, core source code, continuous sign‑in calculation, and a bitmap‑based solution for cache penetration.
1. Redis BitMap Basic Usage
BitMap Syntax and Commands
The article first compares a traditional MySQL table for storing sign‑in records with the memory‑efficient Redis BitMap approach, highlighting that each sign‑in can be represented by a single bit, reducing storage to a few bytes per user.
SETBIT : Set a bit at a given offset to 0 or 1.
GETBIT : Retrieve the bit value at a given offset.
BITCOUNT : Count the number of bits set to 1.
BITFIELD : Query, modify or increment values in a bit array.
BITFIELD_RO : Read bit array values in decimal.
BITOP : Perform bitwise operations (AND, OR, XOR) on multiple BitMaps.
BITPOS : Find the first occurrence of 0 or 1 within a range.
Implementing the Feature with BitMap
Using Redis 6.2, the article demonstrates the SETBIT, GETBIT, BITFIELD and BITPOS commands through screenshots, showing how to create a key, set a sign‑in bit, query its state, and retrieve bit fields.
2. Spring Boot Integration with Redis for Sign‑in
Requirement
Provide an API that records the current user's daily sign‑in status in Redis using a BitMap.
Design
The year‑month string is used as part of the Redis key, and the day of month determines the bit offset; setting the bit to 1 marks a successful sign‑in.
Core Source Code
UserController
@PostMapping("sign")
public Result sign() {
return userService.sign();
}UserServiceImpl
public Result sign() {
// 1. Get logged‑in user
Long userId = UserHolder.getUser().getId();
// 2. Current date
LocalDateTime now = LocalDateTime.now();
// 3. Build key
String keySuffix = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));
String key = RedisConstants.USER_SIGN_KEY + userId + keySuffix;
// 4. Day of month
int dayOfMonth = now.getDayOfMonth();
// 5. Set bit to 1
stringRedisTemplate.opsForValue().setBit(key, dayOfMonth - 1, true);
return Result.ok();
}Testing
ApiFox is used to invoke the sign‑in endpoint, and Redis data is inspected to verify the bit has been set.
3. Sign‑in Statistics
Problem 1: Consecutive Sign‑in Days
The algorithm retrieves the last sign‑in of the current month and walks backwards until the first zero bit is encountered, counting the number of consecutive ones.
Problem 2: Retrieve All Sign‑in Data for the Current Month
BITFIELD key GET u[dayOfMonth] 0This command returns a decimal number representing the bits for the days up to today; counting the number of 1 bits yields the total sign‑ins.
Problem 3: Iterate Bits Backwards
By repeatedly performing a bitwise AND with 1 and right‑shifting the number, each bit can be examined from the least‑significant side.
Core Source Code for Statistics
UserController
@GetMapping("/signCount")
public Result signCount() {
return userService.signCount();
}UserServiceImpl
public Result signCount() {
// 1. Get user
Long userId = UserHolder.getUser().getId();
// 2. Current date
LocalDateTime now = LocalDateTime.now();
// 3. Build key
String keySuffix = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));
String key = RedisConstants.USER_SIGN_KEY + userId + keySuffix;
// 4. Day of month
int dayOfMonth = now.getDayOfMonth();
// 5. Get bitmap as decimal
List
result = stringRedisTemplate.opsForValue().bitField(
key,
BitFieldSubCommands.create()
.get(BitFieldSubCommands.BitFieldType.unsigned(dayOfMonth)).valueAt(0));
if (result == null || result.isEmpty()) {
return Result.ok(0);
}
Long num = result.get(0);
if (num == null || num == 0) {
return Result.ok(0);
}
int count = 0;
while (true) {
if ((num & 1) == 0) {
break;
} else {
count++;
}
num >>>= 1;
}
return Result.ok(count);
}4. Using BitMap to Mitigate Cache Penetration
The article proposes storing hashed IDs in a large BitMap instead of a list, allowing constant‑time existence checks while accepting a configurable false‑positive rate.
Conclusion
Redis BitMap combined with Spring Boot provides a lightweight, memory‑efficient solution for user sign‑in tracking and statistical analysis, and can also be leveraged to address cache‑penetration problems.
Code Ape Tech Column
Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.