preface

Redis knowledge summarized a map, share with you:

Common implementation

Most people think of Redis as setnx+lua, or set key value PX milliseconds nx. The core implementation commands for the latter approach are as follows:

There are three main points to this approach (and the interview probability is very high) :

1. Run set key value px milliseconds nx.

2. Value must be unique;

3. Verify the value of the lock when releasing the lock.

In fact, the biggest disadvantage of this type of lock is that it only works on one Redis node. Even though Redis guarantees high availability through sentinel, if the master node has a master/slave switchover for some reason, the lock will be lost:

1. Get the lock on the master node of Redis

2. The locked key is not synchronized to the slave node.

3. The master fails and failover occurs. The slave node is upgraded to the master node.

4. Lock loss occurs.

Because of this, Antirez, the author of Redis, proposed a more advanced distributed lock implementation method based on distributed environment: Redlock. Redlock is also, in my opinion, the only Redis distributed lock implementation that gives an interviewer an orgasm.

Redlock implementation

The Redlock algorithm proposed by Antirez looks something like this:

In a distributed Redis environment, we assume that there are N Redis masters. These nodes are completely independent of each other and there is no master-slave replication or other cluster coordination mechanism. We ensured that locks would be acquired and released on N instances using the same method as under Redis single instances. Now let’s say we have five Redis master nodes and we need to run these Redis instances on five servers at the same time so that they don’t all go down at the same time.

To get the lock, the client should do the following:

Gets the current Unix time in milliseconds.

Try to get locks from five instances in turn, using the same key and a unique value (such as UUID). When requesting a lock from Redis, the client should set a network connection and response timeout that is less than the lock expiration time.

For example, if your lock expires automatically in 10 seconds, the timeout should be between 5 and 50 milliseconds. This prevents the client from waiting for a response when Redis has already failed on the server. If the server does not respond within the specified time, the client should try to obtain the lock from another Redis instance as soon as possible.

The client obtains the lock usage time by subtracting the current time from the time it started acquiring the lock (the time recorded in Step 1). The lock is successful if and only if it is taken from most of the Redis nodes (N/2+1, here 3 nodes) and used for less than the lock expiration time.

If a lock is obtained, the true validity time of the key is equal to the validity time minus the time used to obtain the lock (as calculated in Step 3).

If, for some reason, the lock fails to be acquired (not in at least N/2+1 Redis instances or the lock has been acquired for an extended period of time), the client should unlock all Redis instances (even if some Redis instances are not locked at all). Prevents some node from acquiring the lock but the client does not get the response so that the lock cannot be reacquired for a later period of time. Redlock source

Redisson has already wrapped the Redlock algorithm, so here is a brief introduction to its usage and an analysis of the core source code (assuming five instances of Redis).

POM depends on

<! -- https://mvnrepository.com/artifact/org.redisson/redisson --> <dependency> <groupId>org.redisson</groupId> < artifactId > redisson < / artifactId > < version > 3.3.2 rainfall distribution on 10-12 < / version > < / dependency >

usage

First, let’s take a look at the distributed lock usage implemented by RedLock’s algorithm encapsulated by Redission, which is very simple and somewhat similar to ReentrantLock:

A unique ID

A very important point to implement distributed locking is that the value of a set must be unique. How to ensure that the value of redisson is unique? The answer is UUID+threadId. The redissonclient.getLock (“REDLOCK_KEY”) entry is in redisson.java and redissonlock. Java source code:

protected final UUID id = UUID.randomUUID(); String getLockName(long threadId) { return id + ":" + threadId; }

Acquiring a lock

The code to retrieve the lock is either redlock. tryLock() or redlock. tryLock(500, 10000, timeunit.milliseconds), and the final core source for both is this: The default leaseTime for a lock is LOCK_EXPIRATION_INTERVAL_SECONDS.

In the command to obtain the lock,

1. KEYS. [1] is the Collections singletonList (getName ()), said distributed lock key, namely REDLOCK_KEY;

ARGV[1] is internalLockLeaseTime.ARGV[1] is internalLockLeaseTime.

ARGV[2] = getLockName(threadId); ARGV[2] = getLockName(threadId);

Release the lock

Unlock (redlock. unlock());

The last

I here organized a JVM related information documents, Spring series of family barrel, Java systematic information :(including Java core knowledge points, interview topics and the latest 20 years of the Internet real questions, e-books, etc.) friends who need to pay attention to the public number [procedures yuan xiao wan] can obtain.