Redis:Redis的常见使用场景及代码示例

一  缓存加速

        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 数据结构,可以使用 LPUSHBRPOP 操作实现简单的消息队列,适用于轻量级的异步任务处理。

        场景示例:在电商系统中,订单生成后需要异步发送通知邮件,将邮件任务放入 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);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值