Redis作为缓存的常见使用场景包括数据库查询缓存、会话管理、分布式锁、缓存热点数据、计数器和限流等。以下是详细的说明和代码示例:
1. 数据库查询缓存
数据库查询缓存是最常见的使用场景之一,缓存数据库查询结果以减少直接访问数据库的频率,从而提升系统性能。
示例代码:
1import redis.clients.jedis.Jedis; 2import com.fasterxml.jackson.databind.ObjectMapper; 3 4public class DatabaseQueryCache { 5 private Jedis jedis; 6 private static final ObjectMapper objectMapper = new ObjectMapper(); 7 8 public DatabaseQueryCache(Jedis jedis) { 9 this.jedis = jedis; 10 } 11 12 public <T> T getCachedData(String key, Class<T> clazz, DataProvider<T> provider, int cacheTime) { 13 try { 14 // 尝试从缓存中获取数据 15 String cacheValue = jedis.get(key); 16 if (cacheValue != null) { 17 return objectMapper.readValue(cacheValue, clazz); 18 } 19 20 // 如果缓存中没有数据,则从数据源中获取数据 21 T data = provider.getData(); 22 // 将数据序列化后存储到缓存中,并设置缓存过期时间 23 jedis.setex(key, cacheTime, objectMapper.writeValueAsString(data)); 24 return data; 25 } catch (Exception e) { 26 e.printStackTrace(); 27 return null; 28 } 29 } 30 31 public interface DataProvider<T> { 32 T getData(); 33 } 34 35 public static void main(String[] args) { 36 Jedis jedis = new Jedis("localhost", 6379); 37 DatabaseQueryCache cache = new DatabaseQueryCache(jedis); 38 39 String userId = "123"; 40 String cacheKey = "user:" + userId; 41 int cacheTime = 3600; // 缓存 1 小时 42 43 User user = cache.getCachedData(cacheKey, User.class, () -> { 44 // 模拟从数据库查询用户数据 45 return getUserFromDatabase(userId); 46 }, cacheTime); 47 48 System.out.println("User: " + user); 49 jedis.close(); 50 } 51 52 private static User getUserFromDatabase(String userId) { 53 // 模拟数据库查询 54 User user = new User(); 55 user.setId(userId); 56 user.setName("John Doe"); 57 user.setEmail("[email protected]"); 58 return user; 59 } 60 61 static class User { 62 private String id; 63 private String name; 64 private String email; 65 66 // Getters and Setters 67 68 @Override 69 public String toString() { 70 return "User{id='" + id + "', name='" + name + "', email='" + email + "'}"; 71 } 72 } 73} 74
2. 会话管理
将用户会话信息存储在Redis中,以实现分布式会话管理。这样可以在多个服务器之间共享会话信息,提高系统的可扩展性和高可用性。
示例代码:
1import redis.clients.jedis.Jedis; 2 3import java.util.UUID; 4 5public class SessionManager { 6 private Jedis jedis; 7 8 public SessionManager(Jedis jedis) { 9 this.jedis = jedis; 10 } 11 12 public String createSession(String userId) { 13 String sessionId = UUID.randomUUID().toString(); 14 String key = "session:" + sessionId; 15 jedis.hset(key, "userId", userId); 16 jedis.expire(key, 3600); // 会话过期时间为1小时 17 return sessionId; 18 } 19 20 public String getUserIdBySessionId(String sessionId) { 21 String key = "session:" + sessionId; 22 return jedis.hget(key, "userId"); 23 } 24 25 public void destroySession(String sessionId) { 26 String key = "session:" + sessionId; 27 jedis.del(key); 28 } 29 30 public static void main(String[] args) { 31 Jedis jedis = new Jedis("localhost", 6379); 32 SessionManager sessionManager = new SessionManager(jedis); 33 34 // 创建会话 35 String sessionId = sessionManager.createSession("user123"); 36 System.out.println("Session created: " + sessionId); 37 38 // 获取用户ID 39 String userId = sessionManager.getUserIdBySessionId(sessionId); 40 System.out.println("User ID: " + userId); 41 42 // 销毁会话 43 sessionManager.destroySession(sessionId); 44 System.out.println("Session destroyed."); 45 46 jedis.close(); 47 } 48} 49
3. 分布式锁
Redis提供了便捷的分布式锁功能,用于在分布式系统中实现互斥访问共享资源。
示例代码:
1import redis.clients.jedis.Jedis; 2import redis.clients.jedis.params.SetParams; 3 4public class RedisDistributedLock { 5 private Jedis jedis; 6 private String lockKey; 7 private String lockValue; 8 private int expireTime; 9 10 public RedisDistributedLock(Jedis jedis, String lockKey, int expireTime) { 11 this.jedis = jedis; 12 this.lockKey = lockKey; 13 this.expireTime = expireTime; 14 this.lockValue = String.valueOf(Thread.currentThread().getId()); 15 } 16 17 public boolean acquireLock() { 18 SetParams params = new SetParams().nx().px(expireTime); 19 String result = jedis.set(lockKey, lockValue, params); 20 return "OK".equals(result); 21 } 22 23 public boolean releaseLock() { 24 String luaScript = "if redis.call('get', KEYS[1]) == ARGV[1] then " + 25 "return redis.call('del', KEYS[1]) else return 0 end"; 26 Object result = jedis.eval(luaScript, 1, lockKey, lockValue); 27 return result.equals(1L); 28 } 29 30 public void executeWithLock(Runnable task) { 31 if (acquireLock()) { 32 try { 33 task.run(); 34 } finally { 35 boolean released = releaseLock(); 36 if (!released) { 37 System.out.println("Failed to release lock."); 38 } 39 } 40 } else { 41 System.out.println("Failed to acquire lock, try again later."); 42 } 43 } 44 45 public static void main(String[] args) { 46 Jedis jedis = new Jedis("localhost", 6379); 47 RedisDistributedLock lock = new RedisDistributedLock(jedis, "resource_lock", 10000); 48 49 lock.executeWithLock(() -> { 50 System.out.println("Executing critical section."); 51 try { 52 Thread.sleep(5000); 53 } catch (InterruptedException e) { 54 Thread.currentThread().interrupt(); 55 } 56 System.out.println("Critical section completed."); 57 }); 58 59 jedis.close(); 60 } 61} 62
4. 缓存热点数据
将频繁访问的热点数据缓存到Redis中,以提高响应速度和系统吞吐量。
示例代码:
1import redis.clients.jedis.Jedis; 2 3import java.util.HashMap; 4import java.util.Map; 5 6public class HotDataCache { 7 private Jedis jedis; 8 9 public HotDataCache(Jedis jedis) { 10 this.jedis = jedis; 11 } 12 13 public Map<String, String> getHotData(String key) { 14 Map<String, String> data = jedis.hgetAll(key); 15 if (data.isEmpty()) { 16 data = fetchDataFromDatabase(key); 17 jedis.hmset(key, data); 18 jedis.expire(key, 3600); // 设置缓存过期时间1小时 19 } 20 return data; 21 } 22 23 private Map<String, String> fetchDataFromDatabase(String key) { 24 // 模拟从数据库获取热点数据 25 Map<String, String> data = new HashMap<>(); 26 data.put("field1", "value1"); 27 data.put("field2", "value2"); 28 return data; 29 } 30 31 public static void main(String[] args) { 32 Jedis jedis = new Jedis("localhost", 6379); 33 HotDataCache cache = new HotDataCache(jedis); 34 35 String key = "hot_data:123"; 36 Map<String, String> data = cache.getHotData(key); 37 System.out.println("Hot data: " + data); 38 39 jedis.close(); 40 } 41} 42
5. 计数器和限流
使用Redis的原子操作实现计数器和限流功能,如实现API请求限流、访问计数等。
示例代码:
1import redis.clients.jedis.Jedis; 2 3public class RateLimiter { 4 private Jedis jedis; 5 private String key; 6 private int limit; 7 private int expireTime; 8 9 public RateLimiter(Jedis jedis, String key, int limit, int expireTime) { 10 this.jedis = jedis; 11 this.key = key; 12 this.limit = limit; 13 this.expireTime = expireTime; 14 } 15 16 public boolean isAllowed() { 17 long count = jedis.incr(key); 18 if (count == 1) { 19 jedis.expire(key, expireTime); // 设置过期时间 20 } 21 return count <= limit; 22 } 23 24 public static void main(String[] args) { 25 Jedis jedis = new Jedis("localhost", 6379); 26 RateLimiter limiter = new RateLimiter(jedis, "api_rate_limiter", 100, 60); // 每分钟限制100次请求 27 28 for (int i = 0; i < 120; i++) { 29 if (limiter.isAllowed()) { 30 System.out.println("Request " + (i + 1) + ": allowed"); 31 } else { 32 System.out.println("Request " + (i 33
《Redis(76)Redis作为缓存的常见使用场景有哪些?》 是转载文章,点击查看原文。
