Previously we explained how to use Redis to implement distributed locks. It provides simple primitives to implement distributed locks based on Redis. However, Redis also has some shortcomings as an implementation of distributed locks. This article will introduce Redisson to implement distributed locks.
Portal: https://blog.csdn.net/Ascend1977/article/details/131221941
1What is Redisson
Redisson is a distributed Java framework based on Redis. It provides a wealth of functions and tools to help developers solve problems such as data sharing, concurrency control, and task scheduling in distributed systems. By using Redisson, developers can easily operate Redis distributed objects (such as collections, maps, queues, etc.), implement reliable distributed lock mechanisms, and manage and schedule tasks and services in a distributed environment.
Functions provided by Redisson
Distributed objects:
-
Distributed collection (Set, SortedSet, List)
-
Distributed mapping (Map)
-
Distributed queue (Queue, Deque)
-
Distributed lock (Lock)
-
Distributed Counter (AtomicLong)
Distributed current limit:
-
Token Bucket Algorithm (Rate Limiter)
-
Leaky Bucket Algorithm (Rate Limiter)
Distributed publish-subscribe:
-
Publish-subscribe model (Pub-Sub)
-
Message Listener Container
Distributed locks and synchronization:
-
ReentrantLock
-
FairLock
-
Interlock (MultiLock)
-
RedLock
-
ReadWriteLock (ReadWriteLock)
-
Semaphore
-
Latch (CountDownLatch)
-
CyclicBarrier
Distributed services and task scheduling:
-
Remote Service
-
Distributed task scheduler (Task Scheduler)
-
Distributed delay queue (Delayed Queue)
Distributed Geospatial Index:
-
Geolocation storage
-
Geolocation search
Distributed Bloom Filter and Bloom Filter.
Distributed cache:
-
Local caching of Redis
-
Spring cache annotation support
Distributed connection pool:
-
Support connection pool management and maintenance
Redis Cluster and Sentinel support:
-
Support Redis cluster mode
-
Support Redis sentry mode
-
For scenarios deployed using Redis clusters, Redisson can automatically identify and operate multiple nodes in the cluster to ensure high availability and scalability of data. For scenarios deployed using Redis sentinel mode, Redisson can monitor and switch to available master-slave nodes to achieve high reliability and fault tolerance.
Spring integration:
-
Seamless integration with Spring framework
-
Support Spring cache annotations
2Redisson distributed lock
Features of Redisson’s distributed lock
Thread safety: Distributed locks can ensure data consistency and reliability in multi-thread and multi-process environments.
-
Reentrancy: The same thread can acquire the same lock multiple times to avoid deadlock problems.
-
Lock timeout: Supports setting the validity period of the lock to prevent the lock from being occupied for a long time and causing system problems.
-
Blocking lock acquisition: When a thread tries to acquire a lock, if the lock is already occupied by another thread, the thread can choose to wait until the lock is released.
-
Non-blocking lock acquisition: When a thread tries to acquire a lock, if the lock is already occupied by another thread, the thread will not wait, but will immediately return information that the lock acquisition failed.
Disadvantages of Redisson’s distributed lock
Single point of failure: Redisson’s distributed lock depends on the Redis cluster. If the Redis cluster fails or is unavailable, the reliability and availability of the distributed lock may be affected. Therefore, when using Redisson distributed locks, special attention needs to be paid to the stability and high availability of the Redis cluster.
Lock competition: When multiple threads request to acquire distributed locks at the same time, lock competition may occur. If lock competition is intense, it may lead to performance degradation and request timeouts. In addition, since Redisson distributed locks are implemented based on Redis, if the processing capacity of the Redis node cannot satisfy highly concurrent lock requests, the lock requests may be delayed or blocked.
Deadlock risk: In a distributed environment, due to network communication, node failure and other factors, the lock may not be released normally, causing deadlock problems. The lock timeout, automatic release mechanism, etc. need to be properly designed and used to reduce the risk of deadlock.
Lock granularity management: In a distributed environment, lock granularity management is an important issue. Locks that are too fine-grained may cause concurrency performance to degrade, while locks that are too coarse-grained may affect the scalability and concurrency performance of the system. The lock granularity needs to be appropriately selected based on specific business scenarios and concurrent access modes.
Data consistency: Using distributed locks to ensure the atomicity of multiple operations is one of the most common application scenarios. However, distributed locks usually only provide coarse-grained mutually exclusive access and cannot guarantee complete data consistency. In some specific application scenarios, additional measures may be required to ensure the eventual consistency of the data.
Redisson distributed lock source code analysis
public interface RLock extends Lock, RLockAsync { String getName(); void lockInterruptibly(long var1, TimeUnit var3) throws InterruptedException; boolean tryLock(long var1, long var3, TimeUnit var5) throws InterruptedException; void lock(long var1, TimeUnit var3); boolean forceUnlock(); boolean isLocked(); boolean isHeldByThread(long var1); boolean isHeldByCurrentThread(); int getHoldCount(); long remainTimeToLive(); }
The RLock interface mainly inherits the Lock interface, which is the core interface provided by Redisson for distributed locks. It defines methods such as acquiring locks and releasing locks, and extends many methods.
like:
void lock(long leaseTime, TimeUnit unit)
-
Function: Get the lock and set the automatic release time of the lock.
-
parameter:
-
leaseTime: the automatic release time of the lock.
-
unit: time unit.
-
RFuture
-
Function: Acquire the lock asynchronously and set the automatic release time of the lock.
-
parameter:
-
leaseTime: the automatic release time of the lock.
-
unit: time unit.
-
-
Return value: an RFuture object representing the result of an asynchronous operation.
boolean tryLock(long waitTime, long leaseTime, TimeUnit unit) throws InterruptedException
-
Function: Try to acquire the lock within the specified waiting time and set the automatic release time of the lock.
-
parameter:
-
waitTime: The maximum amount of time to wait to acquire the lock.
-
leaseTime: the automatic release time of the lock.
-
unit: time unit.
-
-
Return value: If the lock is successfully acquired within the waiting time, true is returned; otherwise false is returned.
-
Exception: If the process of waiting to acquire the lock is interrupted, an InterruptedException is thrown.
Through the above methods, the RLock interface provides more extensions to the lock() method, allowing you to set the automatic release time or perform asynchronous operations when acquiring the lock. This allows for more flexible control of lock behavior and adapts to the needs of different scenarios.
In addition to the above expansions, the RLock interface also provides other methods to support reentrant locks, fair locks, red locks, read-write locks and other features to meet more complex distributed lock requirements.
3Spring Boot integrates Redisson distributed lock
Add Maven dependencies
<!-- Redisson dependency --> <dependency> <groupId>org.redisson</groupId> <artifactId>redisson-spring-boot-starter</artifactId> <version>3.16.2</version> </dependency> <!-- Spring Data Redis dependency --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
Configure Redisson connection application.yml
spring: redis: cluster: nodes: - 127.0.0.1:7000 - 127.0.0.1:7001 - 127.0.0.1:7002 password: yourRedisPassword
Create Redisson client
import org.redisson.Redisson; import org.redisson.api.RedissonClient; import org.redisson.config.Config; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class RedissonConfig { @Value("${spring.redis.cluster.nodes}") private String clusterNodes; @Value("${spring.redis.password}") private String password; @Bean public RedissonClient redissonClient() { Config config = new Config(); config.useClusterServers() .addNodeAddress(clusterNodes.split(",")) .setPassword(password); return Redisson.create(config); } }
Use distributed locks
Inject a RedissonClient instance where a distributed lock is required, and use the getLock method to create a distributed lock object (RLock).
import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class SomeService { @Autowired private RedissonClient redissonClient; public void doSomething() { String lockKey = "myLock"; // lock key RLock lock = redissonClient.getLock(lockKey); try { lock.lock(); // Get lock //Execute code that needs lock protection here } finally { lock.unlock(); // Release the lock } } }
RLock.lock()
When using the Rlock.lock() method, if no other thread or process currently holds the lock, the calling thread will obtain the lock immediately and continue executing subsequent code. If another thread or process already holds the lock, the calling thread will be blocked until the lock is released.
In addition, the Rlock.lock() method also has the following characteristics:
-
Reentrancy: The same thread can call the Rlock.lock() method multiple times without causing deadlock. Just make sure that each lock() call has a corresponding unlock() call and match.
-
Timeout mechanism: You can set the timeout period for waiting for the lock through the parameters in the lock() method to avoid waiting because the lock cannot be obtained.
-
Automatic renewal: When a thread holds a lock for longer than the set lock expiration time, Redisson will automatically extend the validity period of the lock to avoid lock expiration due to too long business execution time.
-
Prevent deadlocks: Redisson distinguishes different locks by uniquely identifying the lock ID to prevent deadlocks.
lock() method locking process
RLock.unlock()
The RLock.unlock() method is used to release resources protected by Redission distributed locks. It allows the thread holding the lock to actively release the lock, allowing other threads to acquire the lock and access shared resources.
Note:
The RLock.unlock() method should be called after the protected critical section code is executed to ensure that the lock is released in time.
In a multi-threaded environment, the order in which locks are released should correspond to the order in which locks are acquired to avoid deadlock or resource contention problems.
If the current thread does not hold the lock, calling the RLock.unlock() method will not throw an exception and will not affect other threads.
If the Redisson client has just been successfully locked and the leaseTime is not specified, a scheduled task watchdog will be started in the background to check the key every 10 seconds. If the key exists, it will be automatically extended to 30 seconds; if the watchdog scheduled task exists, if If the lock is not actively released, the key will always be locked by the watchdog scheduled task. But if the client goes down, the scheduled task watchdog will be gone, and there will be no lock renewal mechanism. Then after 30 seconds, the key will be automatically deleted and the lock corresponding to the key will be automatically released.
Unlock() method unlocking process
Source: blog.csdn.net/Ascend1977/
article/details/131373419
Back-end exclusive technology group
To build a high-quality technical exchange community, HR personnel engaged in programming development and technical recruitment are welcome to join the group. Everyone is also welcome to share their own company’s internal information, help each other, and make progress together!
Speech in a civilized manner, focusing on
communication technology
,recommendation of positions
, andindustry discussion
Advertisers are not allowed to enter, and do not trust private messages to prevent being deceived.