一 缓存加速
Redis 最常见的使用场景是作为缓存来加速应用程序性能,将常用的数据存储在 Redis 中,减少对数据库的访问压力。
场景示例:在用户登录系统中,将用户会话数据存储到 Redis 缓存中,减少对数据库的频繁查询。
import redis.clients.jedis.Jedis;
public class RedisCacheExample {
public static void main(String[] args) {
// 创建 Redis 连接
Jedis jedis = new Jedis("localhost", 6379);
// 设置缓存数据 (存储用户会话信息)
String userId = "user:1001";
jedis.set(userId, "John Doe");
jedis.expire(userId, 3600); // 设置缓存过期时间为1小时
// 获取缓存数据
String userName = jedis.get(userId);
System.out.println("User Name: " + userName);
// 关闭 Redis 连接
jedis.close();
}
}
二 实现分布式锁
Redis 的原子操作和高性能特性非常适合实现分布式锁机制,以避免多个服务节点同时操作共享资源。
场景示例:在订单处理系统中,为防止同一个订单被多次处理,使用 Redis 分布式锁来同步处理。
import redis.clients.jedis.Jedis;
import redis.clients.jedis.params.SetParams;
public class RedisLockExample {
private static final String LOCK_KEY = "order:lock";
private static final int EXPIRE_TIME = 10; // 锁过期时间为10秒
private Jedis jedis;
public RedisLockExample() {
this.jedis = new Jedis("localhost", 6379);
}
public boolean acquireLock(String lockValue) {
SetParams setParams = new SetParams().nx().ex(EXPIRE_TIME);
String result = jedis.set(LOCK_KEY, lockValue, setParams);
return "OK".equals(result); // 如果获取锁成功,返回 true
}
public void releaseLock(String lockValue) {
String currentValue = jedis.get(LOCK_KEY);
if (lockValue.equals(currentValue)) {
jedis.del(LOCK_KEY); // 释放锁
}
}
public static void main(String[] args) {
RedisLockExample lockExample = new RedisLockExample();
String lockValue = String.valueOf(System.currentTimeMillis());
if (lockExample.acquireLock(lockValue)) {
System.out.println("Lock acquired, processing order...");
// 处理订单逻辑
lockExample.releaseLock(lockValue);
System.out.println("Order processed and lock released.");
} else {
System.out.println("Failed to acquire lock, try again later.");
}
}
}
三 限流器
通过 Redis,可以实现对某个接口或功能的限流,避免在短时间内超出服务处理能力。
场景示例:限制某个用户每分钟最多能发送 5 次请求,如果超过这个次数,直接拒绝请求。
import redis.clients.jedis.Jedis;
public class RedisRateLimiter {
private static final String RATE_LIMIT_KEY = "user:1001:requests";
private static final int EXPIRE_TIME = 60; // 每次限流窗口的时间为60秒
private static final int MAX_REQUESTS = 5; // 每分钟允许的最大请求数
private Jedis jedis;
public RedisRateLimiter() {
this.jedis = new Jedis("localhost", 6379);
}
public boolean isAllowed() {
Long requestCount = jedis.incr(RATE_LIMIT_KEY);
if (requestCount == 1) {
jedis.expire(RATE_LIMIT_KEY, EXPIRE_TIME); // 设置过期时间
}
return requestCount <= MAX_REQUESTS;
}
public static void main(String[] args) {
RedisRateLimiter rateLimiter = new RedisRateLimiter();
if (rateLimiter.isAllowed()) {
System.out.println("Request allowed.");
} else {
System.out.println("Too many requests, please try later.");
}
}
}
四 消息队列异步处理
Redis 提供了 List
数据结构,可以使用 LPUSH
和 BRPOP
操作实现简单的消息队列,适用于轻量级的异步任务处理。
场景示例:在电商系统中,订单生成后需要异步发送通知邮件,将邮件任务放入 Redis 消息队列。
import redis.clients.jedis.Jedis;
public class RedisMessageQueue {
private static final String QUEUE_NAME = "emailQueue";
private Jedis jedis;
public RedisMessageQueue() {
this.jedis = new Jedis("localhost", 6379);
}
public void enqueue(String message) {
jedis.lpush(QUEUE_NAME, message);
System.out.println("Message enqueued: " + message);
}
public String dequeue() {
return jedis.rpop(QUEUE_NAME);
}
public static void main(String[] args) {
RedisMessageQueue messageQueue = new RedisMessageQueue();
// 生产者 - 放入消息
messageQueue.enqueue("Send email to user: 1001");
// 消费者 - 处理消息
String message = messageQueue.dequeue();
System.out.println("Processing message: " + message);
}
}
五 排行榜/计数器
Redis 的 Sorted Set
结构可以用于实现排行榜或计数器,基于用户的得分进行排序,并快速获取排名。
场景示例:在游戏系统中,存储玩家得分,并实时展示玩家的排名。
import redis.clients.jedis.Jedis;
public class RedisLeaderboard {
private static final String LEADERBOARD_KEY = "game:leaderboard";
private Jedis jedis;
public RedisLeaderboard() {
this.jedis = new Jedis("localhost", 6379);
}
public void updateScore(String player, int score) {
jedis.zadd(LEADERBOARD_KEY, score, player);
}
public void printLeaderboard() {
System.out.println("Leaderboard:");
jedis.zrevrangeWithScores(LEADERBOARD_KEY, 0, -1).forEach(entry ->
System.out.println(entry.getElement() + ": " + entry.getScore()));
}
public static void main(String[] args) {
RedisLeaderboard leaderboard = new RedisLeaderboard();
leaderboard.updateScore("player1", 100);
leaderboard.updateScore("player2", 200);
leaderboard.updateScore("player3", 150);
leaderboard.printLeaderboard();
}
}
六 分布式会话管理
Redis 也常用于分布式环境下的会话管理,可以将用户的会话数据(如登录状态)存储在 Redis 中,保证多节点环境下的用户状态一致性。
场景示例:在一个微服务环境中,使用 Redis 来共享用户会话状态,避免用户登录信息在不同服务节点之间丢失。
import redis.clients.jedis.Jedis;
public class RedisSessionManagement {
private static final String SESSION_KEY_PREFIX = "session:";
private Jedis jedis;
public RedisSessionManagement() {
this.jedis = new Jedis("localhost", 6379);
}
public void createSession(String sessionId, String userInfo) {
jedis.set(SESSION_KEY_PREFIX + sessionId, userInfo);
jedis.expire(SESSION_KEY_PREFIX + sessionId, 3600); // 1小时过期
}
public String getSession(String sessionId) {
return jedis.get(SESSION_KEY_PREFIX + sessionId);
}
public static void main(String[] args) {
RedisSessionManagement sessionManagement = new RedisSessionManagement();
sessionManagement.createSession("12345", "John Doe");
String userInfo = sessionManagement.getSession("12345");
System.out.println("User Info: " + userInfo);
}
}
七 实时统计
Redis 的高性能读写能力,使其非常适合实时统计系统,例如记录网站访问量、API 调用次数等。通过 Redis 的 INCR
操作,能够高效地进行计数操作。
场景示例:统计网站的页面访问次数,并实时更新数据。
import redis.clients.jedis.Jedis;
public class RedisPageViewCounter {
private static final String PAGE_VIEW_KEY = "page:view:counter";
private Jedis jedis;
public RedisPageViewCounter() {
this.jedis = new Jedis("localhost", 6379);
}
public void incrementPageView(String page) {
jedis.incr(PAGE_VIEW_KEY + ":" + page); // 增加页面访问计数
}
public String getPageViewCount(String page) {
return jedis.get(PAGE_VIEW_KEY + ":" + page);
}
public static void main(String[] args) {
RedisPageViewCounter pageViewCounter = new RedisPageViewCounter();
pageViewCounter.incrementPageView("homepage");
String count = pageViewCounter.getPageViewCount("homepage");
System.out.println("Homepage view count: " + count);
}
}
八 地理位置数据存储
Redis 提供了 GEO
数据类型,可以通过经纬度存储地理位置信息,支持添加、查询、计算两点间距离等功能,非常适合基于位置的应用。
场景示例:在外卖系统中,使用 Redis 来存储和查询商家的地理位置,方便查找用户附近的商家。
import redis.clients.jedis.Jedis;
public class RedisGeoExample {
private static final String GEO_KEY = "restaurant:locations";
private Jedis jedis;
public RedisGeoExample() {
this.jedis = new Jedis("localhost", 6379);
}
public void addLocation(String name, double longitude, double latitude) {
jedis.geoadd(GEO_KEY, longitude, latitude, name);
}
public Double getDistanceBetween(String location1, String location2) {
return jedis.geodist(GEO_KEY, location1, location2);
}
public static void main(String[] args) {
RedisGeoExample geoExample = new RedisGeoExample();
geoExample.addLocation("Restaurant A", 12.9715987, 77.5945627);
geoExample.addLocation("Restaurant B", 12.2958104, 76.6393805);
Double distance = geoExample.getDistanceBetween("Restaurant A", "Restaurant B");
System.out.println("Distance between Restaurant A and B: " + distance + " meters");
}
}
九 实时日志收集
Redis 可用于收集实时日志,结合消息队列功能,可以实现对日志的即时处理和存储。通过 Redis 的 List
操作,将日志信息写入队列,并进行异步消费。
场景示例:在一个日志系统中,应用程序将日志信息写入 Redis,后续通过消费者进行日志处理和分析。
import redis.clients.jedis.Jedis;
public class RedisLogCollector {
private static final String LOG_QUEUE_KEY = "app:logs";
private Jedis jedis;
public RedisLogCollector() {
this.jedis = new Jedis("localhost", 6379);
}
public void logMessage(String log) {
jedis.lpush(LOG_QUEUE_KEY, log); // 将日志推入队列
System.out.println("Log added: " + log);
}
public String consumeLog() {
return jedis.rpop(LOG_QUEUE_KEY); // 消费日志
}
public static void main(String[] args) {
RedisLogCollector logCollector = new RedisLogCollector();
logCollector.logMessage("User A logged in");
String log = logCollector.consumeLog();
System.out.println("Processing log: " + log);
}
}
十 实时排行榜(分布式热搜)
通过 Redis 的 ZSet
数据结构,可以实现基于分数的实时排行榜,适合用于分布式系统中,如热点话题排行、热搜排行榜。
场景示例:在社交媒体平台中,根据某个话题的热度分数来动态生成热搜排行榜。
import redis.clients.jedis.Jedis;
public class RedisHotSearch {
private static final String HOT_SEARCH_KEY = "hot:search";
private Jedis jedis;
public RedisHotSearch() {
this.jedis = new Jedis("localhost", 6379);
}
public void incrementSearchCount(String topic) {
jedis.zincrby(HOT_SEARCH_KEY, 1, topic); // 增加热搜话题分数
}
public void displayTopSearches(int topN) {
System.out.println("Top " + topN + " Hot Searches:");
jedis.zrevrangeWithScores(HOT_SEARCH_KEY, 0, topN - 1).forEach(entry ->
System.out.println(entry.getElement() + ": " + entry.getScore()));
}
public static void main(String[] args) {
RedisHotSearch hotSearch = new RedisHotSearch();
hotSearch.incrementSearchCount("Redis");
hotSearch.incrementSearchCount("Java");
hotSearch.incrementSearchCount("Redis");
hotSearch.displayTopSearches(2);
}
}