[Redis Practice] Use Redisson to elegantly implement 5 scenarios in project practice


insert image description here

1 Introduction

Redisson is a distributed Java object and data structure library based on Redis, which provides rich functions and easy-to-use APIs, enabling developers to easily operate and manage data in a distributed environment.

As a distributed object and data structure library, Redisson provides implementations of many common data structures and algorithms, including common object buckets, binary streams, geospatial object buckets, BitSet, atomic long integers, atomic double-precision floating-point numbers, topics (subscription distribution), bloom filters, and cardinality estimation algorithms. These data structures and algorithms provide developers with the tools to work with distributed data, reducing complexity and increasing efficiency. 简直就是一个Redis的最佳实践框架和最牛X的Redis客户端工具宝箱,基本上覆盖了所有场景.

With Redisson, developers can use a simple and consistent API to store and retrieve objects, process binary data, manage geographic location information, manipulate bit sets, perform atomic operations, perform publish-subscribe messaging, implement bloom filters, and cardinality estimation and other functions. Redisson also provides many additional functions, such as distributed locks, distributed semaphores, distributed queues, and distributed current limiters, which further enhance the capabilities of distributed applications.

Redisson's design goal is to provide high-performance, scalable and reliable distributed data operation solutions. It is tightly integrated with the Redis database and utilizes the features of Redis to realize the storage and management of distributed objects and data structures. Redisson also supports seamless integration with the Spring framework, making it easier for developers to use Redisson features in Spring applications.

So in this article, let’s take a look at the 5 most commonly used scenarios of Redisson in project practice, and set up an example for everyone to understand
insert image description here

2. How to use

1. Add Redisson dependency:

Add the Redisson dependency in the pom.xml file of the Spring Boot project.

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson-spring-boot-starter</artifactId>
    <version>3.15.5</version>
</dependency>

2. Configure Redis connection information

Configure Redis connection information in the application.properties or application.yml file of the Spring Boot project, including host address, port, password, etc. For example:

spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=

3. Usage scenarios

3.1. Distributed lock

For example, you can inject RedissonClient into Spring Boot's Service class and use it to operate:

import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class MyService {
    
    
    
    @Autowired
    private RedissonClient redissonClient;
    
   public void myMethod() {
    
    
        // 获取分布式锁
        RLock lock = redissonClient.getLock("myLock");
        try {
    
    
            // 尝试加锁,如果加锁成功,则执行加锁后的逻辑
            if (lock.tryLock()) {
    
    
                // 执行加锁后的逻辑
                // ...
            }
        } finally {
    
    
            // 释放锁
            lock.unlock();
        }
    }

}

3.2. Rate Limiter

import org.redisson.api.RRateLimiter;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class MyService {
    
    
   @Autowired
    private   RedissonClient redissonClient;
    
    public void myMethod() {
    
    
        // 获取限流器
        RRateLimiter limiter = redissonClient.getRateLimiter("myLimiter");
        // 定义限流速率,例如每秒最多允许10个操作
        limiter.trySetRate(RateType.OVERALL, 10, 1, RateIntervalUnit.SECONDS);
        
        // 尝试获取许可
        boolean acquired = limiter.tryAcquire();
        if (acquired) {
    
    
            // 执行需要限流的操作
            // ...
        } else {
    
    
            // 限流逻辑,例如返回错误信息或执行降级处理
            // ...
        }
    }
}

3.3. Expirable Objects

In Redis, the Hash structure is a data structure used to store key-value pairs. Each Hash structure can contain multiple fields (field) and corresponding values ​​(value). To set the expiration time for the secondary key in the Hash structure, you can use Redisson's RMapCache interface. If you use Redisson to set the expiration time for the value of the secondary key in the Hash structure, it is actually very simple.

We use redissonClient.getMapCache("myHash")the Hash structure to obtain an expirable object named "myHash". Then, we can use put()the method to store the secondary key-value pair with expiration time into the Hash structure, and specify the expiration time and time unit. The stored secondary key-value pairs will automatically expire after the specified expiration time.

In setHashValueWithExpiration()the method, we pass in the primary key (hashKey), secondary key (fieldKey), value (value), expiration time and time unit of the Hash structure, store the value in the secondary key in the Hash structure, and set it to Set an expiration time.

In getHashValue()the method, we obtain the corresponding value from the Hash structure according to the primary key and secondary key of the Hash structure.

By using the Redisson RMapCacheinterface, you can easily set the expiration time for the secondary key-value pairs in the Hash structure, and you don't need to manually handle the expiration logic. Redisson automatically manages expiration and cleanup operations, simplifying the development of using expirable Hash structures in a distributed environment.

import org.redisson.api.RMapCache;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Component
public class HashService {
    
    
  @Autowired
    private  RedissonClient redissonClient;
 

    public void setHashValueWithExpiration(String hashKey, String fieldKey, Object value, long expirationTime, TimeUnit timeUnit) {
    
    
        RMapCache<String, Object> hash = redissonClient.getMapCache("myHash");
        hash.put(hashKey, fieldKey, value, expirationTime, timeUnit);
    }

    public Object getHashValue(String hashKey, String fieldKey) {
    
    
        RMapCache<String, Object> hash = redissonClient.getMapCache("myHash");
        return hash.get(hashKey, fieldKey);
    }
}

3.4. Semaphore

redissonClient.getSemaphore("mySemaphore") gets a semaphore named "mySemaphore". Then, use the trySetPermits() method to set the initial number of semaphores, for example, to 10. In the myMethod() method, we use the acquire() method to try to acquire the semaphore, and if the semaphore is acquired, perform operations that need to be restricted by the semaphore. After the operation is complete, use the release() method to release the semaphore.

  • By using Redisson's semaphore function, you can control the number of concurrent access to a resource in a distributed environment and limit the ability of concurrent access, thereby protecting the stability and availability of resources.
import org.redisson.api.RSemaphore;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class ResourceService {
    
    

    private final RedissonClient redissonClient;

    @Autowired
    public ResourceService(RedissonClient redissonClient) {
    
    
        this.redissonClient = redissonClient;
    }

    public void accessResource() {
    
    
        RSemaphore resourceSemaphore = redissonClient.getSemaphore("resourceSemaphore");
        resourceSemaphore.trySetPermits(10);

        try {
    
    
            resourceSemaphore.acquire();
            // 执行需要受信号量限制的操作,访问资源
            // ...
        } catch (InterruptedException e) {
    
    
            // 处理中断异常
            // ...
        } finally {
    
    
            resourceSemaphore.release();
        }
    }
}

3.5. Distributed Scheduler

We use redissonClient.getMapCache("myHash")the Hash structure to obtain an expirable object named "myHash". Then, we can use put()the method to store the secondary key-value pair with expiration time into the Hash structure, and specify the expiration time and time unit. The stored secondary key-value pairs will automatically expire after the specified expiration time.

In setHashValueWithExpiration()the method, we pass in the primary key (hashKey), secondary key (fieldKey), value (value), expiration time and time unit of the Hash structure, store the value in the secondary key in the Hash structure, and set it to Set an expiration time.

In getHashValue()the method, we obtain the corresponding value from the Hash structure according to the primary key and secondary key of the Hash structure.

By using the Redisson RMapCacheinterface, you can easily set the expiration time for the secondary key-value pairs in the Hash structure, and you don't need to manually handle the expiration logic. Redisson automatically manages expiration and cleanup operations, simplifying the development of using expirable Hash structures in a distributed environment.

import org.redisson.api.RScheduledExecutorService;
import org.redisson.api.RedissonClient;
import org.redisson.api.annotation.RInject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Component
public class DistributedScheduler {
    
    

    private final RedissonClient redissonClient;

    @Autowired
    public DistributedScheduler(RedissonClient redissonClient) {
    
    
        this.redissonClient = redissonClient;
    }

    /**
     * 安排一个延迟执行的分布式任务
     *
     * @param task      要执行的任务
     * @param delay     延迟时间
     * @param timeUnit  时间单位
     */
    public void scheduleTask(Runnable task, long delay, TimeUnit timeUnit) {
    
    
        RScheduledExecutorService executorService = redissonClient.getExecutorService("myScheduler");
        executorService.schedule(task, delay, timeUnit);
    }

    /**
     * 安排一个以固定速率重复执行的分布式任务
     *
     * @param task          要执行的任务
     * @param initialDelay  初始延迟时间
     * @param period        重复执行的周期
     * @param timeUnit      时间单位
     */
    public void scheduleTaskAtFixedRate(Runnable task, long initialDelay, long period, TimeUnit timeUnit) {
    
    
        RScheduledExecutorService executorService = redissonClient.getExecutorService("myScheduler");
        executorService.scheduleAtFixedRate(task, initialDelay, period, timeUnit);
    }
}

5. Source address

https://github.com/wangshuai67/Redis-Tutorial-2023

6. Redis from entry to proficiency series of articles

7. Reference documents

Redisson official documentation https://github.com/redisson/redisson/wiki/Table-of-Content

Guess you like

Origin blog.csdn.net/wangshuai6707/article/details/132275110