Abstract: What are the problems with locks?

A, vernacular distributed

What is distributed, in the simplest terms, is to reduce the pressure of a single server, the distribution of functions on different machines;

Such as:

It would have been possible for a programmer to complete a project: requirements -> design -> code -> test

But when there are many projects, one person can’t carry them, which requires different people to work together

This is a simple distributed collaboration;

Distributed lock

First of all, if a link is terminated or not invaded, something unknowable will happen

This will occur, the design or design of the semi-finished product will be broken, resulting in the subsequent link error;

At this point, we need to introduce the concept of distributed lock;

What is distributed locking?

  • In a distributed model, when there is only one copy of the data (or a limit), the locking technology needs to be used to control the number of processes that modify the data at a given time.
  • A lock is represented by a status value, and lock occupation and release are identified by the status value.

Conditions for distributed locks:

  • This ensures that the same method can be executed by only one thread on a machine at a time in a distributed application cluster.
  • This lock should be a reentrant lock (avoid deadlocks)
  • This lock better be a blocking lock
  • This lock better be a fair lock
  • Highly available lock acquisition and lock release capabilities
  • Lock acquisition and lock release performance is better

Implementation of distributed lock:

Distributed lock by many kinds of implementation, file lock, database, REDis and so on, more, in practice, or REDis do distributed lock performance will be higher;

Redis implements distributed locking

Let’s start with two commands:

**setnx:** Sets the value of the key to value if and only if the key does not exist. If the given key already exists, SETNX does nothing. SETNX is short for SET if Not eXists.

expire: EXPIRE key seconds

Set the lifetime for a given key. When the key expires (lifetime 0), it is automatically deleted

Process based on distributed lock:

This is a simple distributed lock implementation process, specific code implementation is very simple, not to repeat;

Fourth, Redis to achieve distributed lock problem

If setnx is successful but the expire setting fails, the lock will never be obtained and the business will be locked.

Solution: Use the set command to set both lock and expiration time

The set parameters:

Practice:

This perfectly solves the atomicity of distributed locks;

What problems have you encountered with locks? And how to solve it?

Unclosed resources

The current thread obtains the Redis lock and fails to release the lock in time after processing services. As a result, other threads will try to obtain the lock and block. For example, the following error message will be reported when using the Jedis client

1redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool There are no free threads in the redis thread pool to process client commands. Use native methods remember to turn off!

The solution is also very simple, as long as we are careful, the thread to get the lock to deal with the business timely release the lock

B’s lock is released by A

We know that the principle of Redis lock is SETNX command. Set key to value if key does not exist and return 1. If the given key already exists, SETNX does nothing and returns 0.

SETNX key value
Copy the code

Let’s imagine this scenario: thread A and thread B try to lock key myLock. Thread A takes the lock first (if the lock expires after 3 seconds), and thread B waits to try to acquire the lock.

At this time, if the business logic is time-consuming and the execution time exceeds the redis lock expiration time, the lock of thread A is automatically released (delete the key), and thread B detects that the key myLock does not exist and executes the SETNX command to obtain the lock.

However, thread A will still release the lock (delete the key) after executing the business logic, which will cause thread B to release the lock by thread A.

In order to avoid the above situation, we generally need to identify each thread lock with its own unique value value, only release the key specified value, otherwise there will be a chaotic scene of lock release

Generally, you can set value to the service prefix _ current thread ID or UUID. The lock can be released only when the current value is the same

The lock has expired and the service is not finished

The redis distributed lock expires, and the business logic is not completed, but here is another way to think about the problem, the redis lock expiration time longer not to solve it?

That’s still a problem, we can manually increase the expiration time of the redis lock while adding the lock, but how long is the appropriate time? The execution time of the business logic is not controllable, and the operation performance will be affected if the execution time is too long.

If only redis locks could be automatically renewed.

In order to solve this problem, we use redis client Redisson. Redisson well solves some difficult problems of Redis in distributed environment. Its purpose is to make users pay less attention to Redis and focus more on business logic.

Redisson does a good job of encapsulating distributed locks by simply calling the API.

1  RLock lock = redissonClient.getLock("stockLock");
Copy the code

After redisson successfully adds a lock, he registers a timed task to listen to the lock, check on it every 10 seconds, and renew the expiration if the lock is still held. The default expiration time is 30 seconds. This mechanism is also known as the “watchdog.”

Redis master slave replication pit

The most common solution for Redis high availability is master-slave, which also makes redis distributed lock difficult.

In the redis cluster environment, if client A wants to lock, it will select A master node to write key mylock according to routing rules. After the lock is successfully added, the master node will asynchronously copy the key to the corresponding slave node.

If the redis master node breaks down and the slave node fails to replicate, a master/slave switchover is performed to ensure the availability of the cluster. Client B successfully locks the new master node, and client A thinks it has successfully locked the new master node. In addition, if the master/slave replication delay is also caused by locking and unlocking delay.

In this case, multiple clients lock a distributed lock at the same time, resulting in various dirty data.

After all, Redis is a persistent AP, not a CP, so if you want consistency, you can use zooKeeper distributed locks

This article is shared from Huawei cloud community “Redis distributed lock? Easy to step on the pit”, original author: Minjie.

Click to follow, the first time to learn about Huawei cloud fresh technology ~