Redis provides efficient counting capabilities suitable for rate limiting and access tracking. Common use cases enclude blog view counters and SMS verification code frequency limits.
Basic counters face challenges like preventing refresh-triggered increments. The solution involves tracking user access within specific time windows and storing data in memory before database synchronization.
Redis Configuration
Initialize RedisTemplate with proper serialization:
@Configuration
public class RedisConfiguration {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(RedisSerializer.string());
return template;
}
}
Rate Limiting Implementation
@RestController
public class AccessController {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@RequestMapping("/access")
public ResponseEntity<String> checkAccess() {
boolean allowed = checkRateLimit("user_access", 1, 5);
if (allowed) {
return ResponseEntity.ok("Access granted");
} else {
return ResponseEntity.status(429).body("Rate limit exceeded");
}
}
private boolean checkRateLimit(String identifier, int duration, int maxAttempts) {
String redisKey = "rate_limit:" + identifier;
if (redisTemplate.hasKey(redisKey)) {
Integer currentCount = Integer.valueOf(
(String) redisTemplate.opsForValue().get(redisKey)
);
if (currentCount >= maxAttempts) {
return false;
}
redisTemplate.opsForValue().increment(redisKey);
return true;
} else {
redisTemplate.opsForValue().set(redisKey, "1",
duration, TimeUnit.MINUTES);
return true;
}
}
}
This implementation tracks access attempts using Redis keys with expiration. When the key exists, the counter increments; if the limits reached, access is denied. New keys are created with expiration times.
Common RedisTemplate Operations
| Method | Description |
|---|---|
expire(K key, long timeout, TimeUnit unit) |
Set key expiration time |
expireAt(K key, Date date) |
Set key expiration date |
getExpire(K key) |
Get remaining TTL in seconds |
hasKey(K key) |
Check if key exists |
delete(K key) |
Remove specified key |
delete(Collection<K> keys) |
Remove multiple keys |
keys(K pattern) |
Find keys matching pattern |
opsForValue().increment(K key) |
Atomic counter increment |
Data Persistence Strategy
For production systems, implement asynchronous data synchronization:
- Store counters in Redis for fast access
- Use background jobs to persist data to databases
- Maintain data consistency through periodic synchronization
- Handle edge cases like system failures and network partitions