Redis常用的八种场景

2023年 11月 20日 76.8k 0

大家好,我是猿java。

作为一名 Java后端人员,对 Redis肯定并不陌生,Redis作为一种内存数据库,以其速度之快在编程的舞台上纵横多年,那么,Redis到底适合哪些业务场景?今天就来聊一聊。

1. 缓存/数据库

缓存(Cache)是 Redis使用最广泛的场景之一,也是很多小伙伴结识 Redis的重要原因,在 8种10倍提升API性能的方式 文章中我们也强调了Redis可以作为缓存的来加速 API性能。如下图,在 WebServer和数据库之间会增加一层 Redis缓存,这样 WebServer可以直接从Redis中快速拿到数据返回,加快了 WebServer的响应速度。

举例:

  • 电商领域,可以缓存一些热门商品的静态信息或用户数据,这样,在大流量访问时,不用查询数据库,加速访问速度。
  • 配置中心,业务开发中,经常会使用一些全局配置,而且配置更改的频率很低,因此,可以把配置都加载到 Redis内存中,加快查询数据。

需要说明的是:很多时候,我们都会把 Redis的持久化功能打开,因此,在把 Redis当作缓存的同时,同样把 Redis当作数据库在使用。

2. 分布式锁

分布式锁(Distributed Lock)也是 Redis使用最广泛的场景之一,分布式系统中,当我们在处理有并发的业务场景时,为了保证线程安全,通常通常会使用分布式锁,单机下,Redis通常使用 SET NX(if Not Exist)和 PX(过期时间)来创建锁,指令如下:

# 如果key不存,set key=value,
# 失效时间是 expiration毫秒
SET key value NX PX expiration

在 Java中,Redission是一个基于 Redis的分布式Java对象映射(Java Redis Client),它提供了丰富的特性和工具,示例代码展示了如何在 Redission框架中使用 Redis分布式锁:

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;

public class RedissonExample {
    public static void main(String[] args) {
        Config config = new Config();
        config.useSingleServer().setAddress("redis://127.0.0.1:6379");
        RedissonClient redisson = Redisson.create(config);

        // 使用分布式锁
        String lockKey = "lockKey";
        boolean isLocked = redisson.getLock(lockKey).tryLock();
        if (isLocked) {
            // 获得锁,执行相关操作
            System.out.println("Lock acquired successfully");
            redisson.getLock(lockKey).unlock(); // 释放锁
        } else {
            System.out.println("Failed to acquire lock");
        }
        redisson.shutdown(); // 关闭连接
    }
}

需要说明的是:除了Redis,Zookeeper也是实现分布式锁比较常用的一种技术方案。

3. 限流

限流(Rate Limiter)也是 Redis使用比较多的一个场景,限流是保护系统免受过载的一种方法,它可以确保在指定时间内对系统的请求进行限制。在 Redis 中,可以使用 SET、EXPIRE 和 Lua 脚本来实现简单的限流功能。

示例代码展示了Java Jedis 库实现基于令牌桶算法的 Redis 限流:


import redis.clients.jedis.Jedis;
import redis.clients.jedis.Response;
import redis.clients.jedis.Transaction;

public class RateLimiter {
private final Jedis jedis;
private final String key;
private final int capacity;
private final int tokensPerSecond;

public RateLimiter(Jedis jedis, String key, int capacity, int tokensPerSecond) {
this.jedis = jedis;
this.key = key;
this.capacity = capacity;
this.tokensPerSecond = tokensPerSecond;
}

/**
* 用于检查是否允许请求,根据当前令牌数量和容量进行判断
*/
public boolean allowRequest() {
long now = System.currentTimeMillis();
Transaction transaction = jedis.multi();
// Add current time with score
transaction.zadd(key, now, String.valueOf(now));
// Remove tokens that are older than 1 second
transaction.zremrangeByScore(key, 0, now - 1000);
// Get current number of tokens
Response sizeResponse = transaction.zcard(key);

transaction.exec();

long size = sizeResponse.get();
// Check if number of tokens is within capacity
return size

相关文章

Oracle如何使用授予和撤销权限的语法和示例
Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
社区版oceanbase安装
Oracle 导出CSV工具-sqluldr2
ETL数据集成丨快速将MySQL数据迁移至Doris数据库

发布评论