Table of Contents
Why distributed locks are needed
Implementation method
RedLock
Home Database Redis Why is distributed lock needed in Redis? How to achieve?

Why is distributed lock needed in Redis? How to achieve?

Oct 20, 2021 am 10:37 AM
redis Distributed lock

This article will introduce you to distributed locks in Redis, why distributed locks are needed, and how Redis implements distributed locks. I hope it will be helpful to you!

Why is distributed lock needed in Redis? How to achieve?

Why distributed locks are needed

Why distributed locks are needed

Use The purpose of distributed locks is nothing more than to ensure that only one client can operate on shared resources at the same time.

We often encounter concurrency problems when performing logical processing in distributed applications. [Related recommendations: Redis Video Tutorial]

For example, an operation requires modifying the user's status. To modify the status, you need to read the user's status first, modify it in the memory, and then save it back after the modification. . If such operations are performed at the same time, concurrency problems will arise because the two operations of reading and saving state are not atomic.

At this time, distributed locks are used to limit the concurrent execution of the program. As a caching middleware system, redis can provide this kind of distributed lock mechanism.

The essence is to occupy a pit in redis. When other processes want to occupy the pit, they find that they have already occupied the pit. If it is occupied, just wait and try again later

Generally speaking, the distributed locks available in the production environment need to meet the following points:

  • Mutual exclusion, mutual exclusion is the basic feature of the lock. Only one thread can hold the lock at the same time and perform critical operations;
  • Timeout release, timeout release is another necessary feature of the lock, you can Compare the innodb_lock_wait_timeout configuration in the MySQL InnoDB engine to prevent unnecessary thread waiting and resource waste through timeout release;
  • Reentrancy, in a distributed environment, on the same node If the same thread acquires the lock, the request can still be successful again;

Implementation method

Use SETNX to implement

The usage method of SETNX is: SETNX key value. Only when the key key does not exist, the value of the key key is set to value. If the key key exists, SETNX does not take any action. .

boolean result = jedis.setnx("lock-key",true)== 1L;
if  (result) {
    try {
        // do something
    } finally {
        jedis.del("lock-key");
    }
 }
Copy after login

This solution has a fatal problem, that is, after a thread acquires the lock and cannot perform the unlocking operation normally due to some abnormal factors (such as downtime), then the lock will never be released. .

To this end, we can add a timeout period to this lock

The effect of executing SET key value EX seconds is equivalent to executing SETEX key seconds value

The effect of executing SET key value PX milliseconds is equivalent to executing PSETEX key milliseconds value

String result = jedis.set("lock-key",true, 5);
if ("OK".equals(result)) {
    try {
        // do something
    } finally {
        jedis.del("lock-key");
    }
}
Copy after login

The solution looks perfect , but in fact there will still be problems

Just imagine that a certain thread A acquires the lock and sets the expiration time to 10s, and then it takes 15s to execute the business logic. At this time, thread A acquires The lock has already been automatically released by the expiration mechanism of Redis

After thread A acquires the lock and 10 seconds have passed, the changed lock may have been acquired by other threads. When thread A finishes executing the business logic and prepares to unlock (DEL key), it is possible to delete the lock that has been acquired by other threads.

So the best way is to determine whether the lock belongs to you when unlocking. We can set the value to a unique value when setting keyuniqueValue ( It can be a random value, UUID, or a combination of machine number and thread number, signature, etc.).

When unlocking, that is, when deleting the key, first determine whether the value corresponding to the key is equal to the previously set value. If it is equal, the key can be deleted

String velue= String.valueOf(System.currentTimeMillis())
String result = jedis.set("lock-key",velue, 5);
if ("OK".equals(result)) {
    try {
        // do something
    } finally {
      	//非原子操作
	      if(jedis.get("lock-key")==value){
		        jedis.del("lock-key");
        }    
    }
}
Copy after login

We can see the problem at a glance here Come on: GET and DEL are two separate operations. An exception may occur in the gap between GET execution and before DEL execution.

If we only need to ensure that the unlocking code is atomic we can solve the problem

Here we introduce a new method, which is Lua script, the example is as follows :

if redis.call("get",KEYS[1]) == ARGV[1] then
    return redis.call("del",KEYS[1])
else
    return 0
end
Copy after login

where ARGV[1] represents the unique value specified when setting the key.

Due to the atomicity of the Lua script, during the process of Redis executing the script, other client commands need to wait for the Lua script to be executed before they can be executed.

Ensure that the expiration time is greater than the business execution time

In order to prevent multiple threads from executing business code at the same time, it is necessary to ensure that the expiration time is greater than the business execution time

Add A boolean type attribute isOpenExpirationRenewal, used to identify whether to enable scheduled refresh expiration time

In addition, a scheduleExpirationRenewal method is used to enable the thread to refresh the expiration time

The locking code sets isOpenExpirationRenewal to true after successfully acquiring the lock, and calls the scheduleExpirationRenewal method to start the thread that refreshes the expiration time.

The unlocking code adds a line of code and sets the isOpenExpirationRenewal attribute. If false, stop the thread polling for refreshing the expiration time

Redisson implementation

If the lock is successfully acquired, a scheduled task will be started, and the scheduled task will be checked regularly for renewal

The time difference between each call of this scheduled schedule is internalLockLeaseTime / 3, which is 10 seconds

By default, the locking time is 30 seconds. If the locked business does not After execution, when 30-10 = 20 seconds, a renewal will be performed and the lock will be reset to 30 seconds

RedLock

In the cluster, when the master node hangs up, the slave node will take its place, but there is no obvious perception on the client. It turns out that the first client successfully applied for a lock on the master node, but before the lock could be synchronized to the slave node, the master node suddenly died. Then the slave node becomes the master node. This new node does not have this lock inside, so when another client comes to request a lock, it is approved immediately. This will cause the same lock in the system to be held by two clients at the same time, resulting in insecurity

The Redlock algorithm is to solve this problem

To use Redlock, you need to provide multiple Redis instances. These instances were previously independent of each other and had no master-slave relationship. Like many distributed algorithms, redlock also uses most mechanisms

When locking, it will send set instructions to more than half of the nodes. As long as more than half of the nodesset succeed, the lock is considered successful. . When releasing the lock, a del instruction needs to be sent to all nodes. However, the Redlock algorithm also needs to consider many detailed issues such as error retry and clock drift. At the same time, because Redlock needs to read and write to multiple nodes, it means that the performance of Redis will be lower than that of a single instance.

Redlock algorithm is a high-availability mode introduced on the basis of a single Redis node. Redlock is based on N completely independent Redis nodes, usually an odd number greater than 3 (usually N can be set to 5), which can basically ensure that the cluster Each node will not go down at the same time.

Assuming that the current cluster has 5 nodes, the client running the Redlock algorithm performs the following steps in order to complete the operation of acquiring the lock

  • Client record Current system time, in milliseconds;
  • Try to obtain locks from 5 Redis instances using the same key in sequence. When requesting to obtain a lock from Redis, the client should set a network connection and response timeout. , the timeout should be less than the expiration time of the lock to avoid problems due to network failures;
  • The client uses the current time minus the time to start acquiring the lock to get the time to acquire the lock, if and only if from half The above Redis node acquires the lock, and when the time used is less than the lock expiration time, the lock is successfully acquired;
  • If the lock is acquired, the real effective time of the key is equal to the effective time minus the time used to acquire the lock. time to reduce the chance of timeout;
  • If the lock acquisition fails, the client should unlock it on all Redis instances, even the node where the previous operation request failed, to prevent the server response message from being lost, but Inconsistency caused by successful addition of actual data.

In other words, assuming that the lock expires in 30 seconds and it takes 31 seconds to lock the three nodes, naturally the locking failed

In the Java client officially recommended by RedisRedisson has a built-in implementation of RedLock

https://redis.io/topics/distlock

https:// github.com/redisson/redisson/wiki

RedLock problem:

RedLock only ensures the high availability of the lock, but does not guarantee the correctness of the lock

RedLock is a distributed system that relies heavily on the system clock

Martin’s criticism of RedLock:

  • For efficiency improvement scenarios, RedLock is too heavy.
  • For scenarios that require extremely high accuracy, RedLock cannot guarantee accuracy.

This article is reproduced from: https://juejin.cn/post/7018968452136173576

Author: With a distant heart

More programming related For knowledge, please visit: programming video! !

The above is the detailed content of Why is distributed lock needed in Redis? How to achieve?. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Roblox: Bubble Gum Simulator Infinity - How To Get And Use Royal Keys
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Nordhold: Fusion System, Explained
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Mandragora: Whispers Of The Witch Tree - How To Unlock The Grappling Hook
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Hot Topics

Java Tutorial
1666
14
PHP Tutorial
1273
29
C# Tutorial
1253
24
How to build the redis cluster mode How to build the redis cluster mode Apr 10, 2025 pm 10:15 PM

Redis cluster mode deploys Redis instances to multiple servers through sharding, improving scalability and availability. The construction steps are as follows: Create odd Redis instances with different ports; Create 3 sentinel instances, monitor Redis instances and failover; configure sentinel configuration files, add monitoring Redis instance information and failover settings; configure Redis instance configuration files, enable cluster mode and specify the cluster information file path; create nodes.conf file, containing information of each Redis instance; start the cluster, execute the create command to create a cluster and specify the number of replicas; log in to the cluster to execute the CLUSTER INFO command to verify the cluster status; make

How to clear redis data How to clear redis data Apr 10, 2025 pm 10:06 PM

How to clear Redis data: Use the FLUSHALL command to clear all key values. Use the FLUSHDB command to clear the key value of the currently selected database. Use SELECT to switch databases, and then use FLUSHDB to clear multiple databases. Use the DEL command to delete a specific key. Use the redis-cli tool to clear the data.

How to read redis queue How to read redis queue Apr 10, 2025 pm 10:12 PM

To read a queue from Redis, you need to get the queue name, read the elements using the LPOP command, and process the empty queue. The specific steps are as follows: Get the queue name: name it with the prefix of "queue:" such as "queue:my-queue". Use the LPOP command: Eject the element from the head of the queue and return its value, such as LPOP queue:my-queue. Processing empty queues: If the queue is empty, LPOP returns nil, and you can check whether the queue exists before reading the element.

How to configure Lua script execution time in centos redis How to configure Lua script execution time in centos redis Apr 14, 2025 pm 02:12 PM

On CentOS systems, you can limit the execution time of Lua scripts by modifying Redis configuration files or using Redis commands to prevent malicious scripts from consuming too much resources. Method 1: Modify the Redis configuration file and locate the Redis configuration file: The Redis configuration file is usually located in /etc/redis/redis.conf. Edit configuration file: Open the configuration file using a text editor (such as vi or nano): sudovi/etc/redis/redis.conf Set the Lua script execution time limit: Add or modify the following lines in the configuration file to set the maximum execution time of the Lua script (unit: milliseconds)

How to use the redis command line How to use the redis command line Apr 10, 2025 pm 10:18 PM

Use the Redis command line tool (redis-cli) to manage and operate Redis through the following steps: Connect to the server, specify the address and port. Send commands to the server using the command name and parameters. Use the HELP command to view help information for a specific command. Use the QUIT command to exit the command line tool.

How to implement redis counter How to implement redis counter Apr 10, 2025 pm 10:21 PM

Redis counter is a mechanism that uses Redis key-value pair storage to implement counting operations, including the following steps: creating counter keys, increasing counts, decreasing counts, resetting counts, and obtaining counts. The advantages of Redis counters include fast speed, high concurrency, durability and simplicity and ease of use. It can be used in scenarios such as user access counting, real-time metric tracking, game scores and rankings, and order processing counting.

How to set the redis expiration policy How to set the redis expiration policy Apr 10, 2025 pm 10:03 PM

There are two types of Redis data expiration strategies: periodic deletion: periodic scan to delete the expired key, which can be set through expired-time-cap-remove-count and expired-time-cap-remove-delay parameters. Lazy Deletion: Check for deletion expired keys only when keys are read or written. They can be set through lazyfree-lazy-eviction, lazyfree-lazy-expire, lazyfree-lazy-user-del parameters.

How to optimize the performance of debian readdir How to optimize the performance of debian readdir Apr 13, 2025 am 08:48 AM

In Debian systems, readdir system calls are used to read directory contents. If its performance is not good, try the following optimization strategy: Simplify the number of directory files: Split large directories into multiple small directories as much as possible, reducing the number of items processed per readdir call. Enable directory content caching: build a cache mechanism, update the cache regularly or when directory content changes, and reduce frequent calls to readdir. Memory caches (such as Memcached or Redis) or local caches (such as files or databases) can be considered. Adopt efficient data structure: If you implement directory traversal by yourself, select more efficient data structures (such as hash tables instead of linear search) to store and access directory information

See all articles