Redis, with its high performance and rich data structures, has a wide range of application scenarios in actual projects. Here are the main application scenarios of Redis and their implementation methods.
1. Caching
Application Scenarios
- Hot data caching: Cache frequently accessed data to reduce database pressure
- Query result caching: Cache results of complex queries to improve query performance
- Page caching: Cache page rendering results to reduce server computation
Implementation
java// Read cache public User getUserById(Long id) { String key = "user:" + id; User user = redis.get(key); if (user != null) { return user; } // Cache miss, query database user = db.queryUserById(id); // Write to cache redis.set(key, user, 3600); // Cache for 1 hour return user; } // Update cache public void updateUser(User user) { db.updateUser(user); redis.del("user:" + user.getId()); // Delete cache }
Notes
- Set reasonable expiration time to avoid cache avalanche
- Use solutions for cache penetration, cache breakdown, and cache avalanche
- Monitor cache hit rate and adjust cache strategy in time
2. Session Storage
Application Scenarios
- User login status: Store user login status and session information
- Distributed session: Share session information in distributed systems
- Temporary data storage: Store temporary data like verification codes, temporary tokens, etc.
Implementation
java// User login public String login(String username, String password) { User user = db.authenticate(username, password); if (user != null) { String sessionId = generateSessionId(); String key = "session:" + sessionId; // Store session information redis.set(key, user, 1800); // Expire in 30 minutes return sessionId; } return null; } // Validate session public User validateSession(String sessionId) { String key = "session:" + sessionId; User user = redis.get(key); if (user != null) { // Refresh expiration time redis.expire(key, 1800); return user; } return null; }
3. Counters
Application Scenarios
- Article view count: Count article views
- Video play count: Count video plays
- Like count: Count likes
- Visit statistics: Count website visits
Implementation
java// Increment counter public long incrementViewCount(Long articleId) { String key = "article:view:" + articleId; return redis.incr(key); } // Get counter public long getViewCount(Long articleId) { String key = "article:view:" + articleId; return redis.get(key); } // Batch get counters public Map<Long, Long> getViewCounts(List<Long> articleIds) { String[] keys = articleIds.stream() .map(id -> "article:view:" + id) .toArray(String[]::new); return redis.mget(keys); }
4. Leaderboards
Application Scenarios
- Game leaderboard: Real-time display of player rankings
- Article leaderboard: Display popular article rankings
- Product sales ranking: Display product sales rankings
- User points ranking: Display user points rankings
Implementation
java// Add score public void addScore(Long userId, double score) { String key = "leaderboard:user"; redis.zadd(key, score, userId.toString()); } // Get leaderboard public List<User> getLeaderboard(int start, int end) { String key = "leaderboard:user"; // Get ranking and score Set<Tuple> tuples = redis.zrevrangeWithScores(key, start, end); // Convert to user list return tuples.stream() .map(tuple -> { Long userId = Long.parseLong(tuple.getElement()); User user = db.getUserById(userId); user.setScore(tuple.getScore()); user.setRank(redis.zrevrank(key, userId.toString()) + 1); return user; }) .collect(Collectors.toList()); } // Get user ranking public long getUserRank(Long userId) { String key = "leaderboard:user"; Long rank = redis.zrevrank(key, userId.toString()); return rank != null ? rank + 1 : 0; }
5. Message Queue
Application Scenarios
- Async tasks: Put time-consuming tasks into queue for async processing
- Task scheduling: Implement scheduled tasks and task scheduling
- Event notification: Implement pub-sub pattern
- Log collection: Collect and distribute logs
Implementation
java// Producer: Send message public void sendMessage(String queue, String message) { redis.lpush(queue, message); } // Consumer: Consume message public String consumeMessage(String queue) { return redis.brpop(queue, 0); // Blocking consumption } // Batch consumption public List<String> consumeMessages(String queue, int count) { List<String> messages = new ArrayList<>(); for (int i = 0; i < count; i++) { String message = redis.rpop(queue); if (message == null) { break; } messages.add(message); } return messages; }
6. Distributed Lock
Application Scenarios
- Stock deduction: Prevent overselling
- Order creation: Prevent duplicate order creation
- Resource competition: Solve concurrency competition issues
- Rate limiting: Implement API rate limiting
Implementation
java// Acquire lock public boolean tryLock(String key, String value, int expireTime) { String result = redis.set(key, value, "NX", "EX", expireTime); return "OK".equals(result); } // Release lock public void unlock(String key, String value) { String script = "if redis.call('GET', KEYS[1]) == ARGV[1] then return redis.call('DEL', KEYS[1]) else return 0 end"; redis.eval(script, Collections.singletonList(key), Collections.singletonList(value)); } // Use lock public void deductStock(Long productId, int quantity) { String lockKey = "lock:product:" + productId; String lockValue = UUID.randomUUID().toString(); try { // Acquire lock if (tryLock(lockKey, lockValue, 10)) { // Deduct stock db.deductStock(productId, quantity); } } finally { // Release lock unlock(lockKey, lockValue); } }
7. Rate Limiter
Application Scenarios
- API rate limiting: Limit API call frequency
- Anti-scraping: Prevent malicious API scraping
- User rate limiting: Limit user operation frequency
- System protection: Protect system from overload
Implementation
java// Fixed window rate limiting public boolean allowRequest(String key, int limit, int expireTime) { String count = redis.get(key); if (count == null) { redis.set(key, "1", expireTime); return true; } int currentCount = Integer.parseInt(count); if (currentCount < limit) { redis.incr(key); return true; } return false; } // Sliding window rate limiting public boolean allowRequestSliding(String key, int limit, int windowSize) { long currentTime = System.currentTimeMillis(); long windowStart = currentTime - windowSize; // Remove data outside window redis.zremrangeByScore(key, 0, windowStart); // Add current request redis.zadd(key, currentTime, UUID.randomUUID().toString()); // Count requests within window long count = redis.zcard(key); return count <= limit; }
8. Tag System
Application Scenarios
- Article tags: Add tags to articles
- User tags: Add tags to users
- Tag query: Query content by tags
- Tag recommendation: Recommend content based on tags
Implementation
java// Add tags public void addTags(Long articleId, Set<String> tags) { String key = "article:tags:" + articleId; redis.sadd(key, tags.toArray(new String[0])); } // Get tags public Set<String> getTags(Long articleId) { String key = "article:tags:" + articleId; return redis.smembers(key); } // Query articles by tag public Set<Long> getArticlesByTag(String tag) { String key = "tag:articles:" + tag; return redis.smembers(key); } // Get common tags public Set<String> getCommonTags(Long articleId1, Long articleId2) { String key1 = "article:tags:" + articleId1; String key2 = "article:tags:" + articleId2; return redis.sinter(key1, key2); }
9. Geolocation
Application Scenarios
- Nearby people: Find nearby people
- Nearby locations: Find nearby locations
- Distance calculation: Calculate distance between two locations
- Location services: Provide location-related services
Implementation
java// Add location public void addLocation(String key, double longitude, double latitude) { redis.geoadd(key, longitude, latitude, key); } // Find nearby locations public List<Location> getNearbyLocations(String key, double longitude, double latitude, double radius) { return redis.georadius(key, longitude, latitude, radius, GeoUnit.KM); } // Calculate distance public double getDistance(String key, String member1, String member2) { return redis.geodist(key, member1, member2, GeoUnit.KM); }
10. Real-time Statistics
Application Scenarios
- Online users: Count online users
- UV statistics: Count unique visitors
- PV statistics: Count page views
- Real-time data: Real-time statistics of business data
Implementation
java// UV statistics (using HyperLogLog) public long getUV(String key) { return redis.pfcount(key); } public void addUV(String key, String userId) { redis.pfadd(key, userId); } // PV statistics (using counter) public long getPV(String key) { String count = redis.get(key); return count != null ? Long.parseLong(count) : 0; } public void addPV(String key) { redis.incr(key); }
Summary
Redis has a wide range of application scenarios in actual projects, including caching, session storage, counters, leaderboards, message queues, distributed locks, rate limiters, tag systems, geolocation, real-time statistics, etc. Each application scenario has its specific implementation method and considerations. In actual development, you need to choose appropriate application scenarios and implementation methods based on specific business requirements to fully leverage Redis's advantages.