How to use Redis achieve Distributed Lock

Lock us around, but in the design and implementation of most systems topic. Once appeared competitive conditions, operating under the premise of no protection, and unpredictable problems may occur.

The most modern systems for the distributed system, which introduces a distributed lock, requires the ability to protect resources in the distribution throughout the service.

The implementation of distributed locks, most currently has the following three ways:

  • Use the database to achieve.
  • Use Redis cache and other system implementation.
  • Zookeeper using a distributed coordination system implementation.

Redis which is simple and flexible, highly available distributed, and support for persistence. This paper describes implementation of distributed lock Redis based.

SETNX semantics

Redis achieved using a distributed lock, fundamental principle is SETNX instruction. The semantics is as follows:

SETNX key value
复制代码

When the command is executed, if keynot present, then the set keyvalue value(same set); if keyalready present, assignment is not performed. And use a different return value identification. Command Description Document

You can also use the SET command NX options:

SET key value [expiration EX seconds|PX milliseconds] [NX|XX]
复制代码

NX - execute an assignment only if the key does not exist. Command description document and as described below, by using the SET NX option, other options can be used simultaneously, such as EX / PX disposed timeout better way.

SETNX achieve Distributed Lock

Here we compare the next several specific implementations.

Scheme 1: SETNX + delete

Pseudo-code as follows:

setnx lock_a random_value
// do sth
delete lock_a
复制代码

The problem with this implementation is that: Once the service to acquire the lock, hang up for some reason, it has been unable to lock automatically released. Resulting in a deadlock.

Scheme 2: SETNX + SETEX

Pseudo-code as follows:

setnx lock_a random_value
setex lock_a 10 random_value // 10s超时
// do sth
delete lock_a
复制代码

Set the timeout on demand. This program solves the problem of deadlock Scenario 1, but at the same time introduced a new deadlock: If after setnx, hang up before setex service, will fall into a deadlock. The root causes of setnx / setex divided into two steps, the non-atomic operation.

Program 3: SET NX PX

Pseudo-code as follows:

SET lock_a random_value NX PX 10000 // 10s超时
// do sth
delete lock_a
复制代码

By this embodiment NX / PX option is set, the lock, two steps are combined to set a timeout an atomic operation, so solutions to problems 1 and 2. (PX same semantic and EX option, the difference is only in the unit.) This program is currently most sdk, redis deployment scenarios are supported, and therefore is the recommended way to use. But this program also has the following problems:

If the lock is released errors (such as time-out), or to seize the wrong, or because redis problems as a result of loss of lock, you can not quickly perceive.

Program 4: SET key randomvalue NX PX

Option 4 on the basis of 3 on the increased value of the check, just add their own lift lock. Similar to the CAS, but a compare-and-delete. This program does not support native command redis, in order to ensure atomicity, the need to achieve by lua script:

Pseudo-code as follows:

SET lock_a random_value NX PX 10000
// do sth
eval "if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end" 1 lock_a random_value
复制代码

This program is more rigorous: Even as some abnormalities cause the lock is wrong to seize, but also part of the guarantee of the right to release the lock. When the lock is released and able to detect whether the lock is preempted error, the error is released, so that special handling.

Precautions

overtime time

As can be seen from the above description, a time-out time is important variables:

Timeout is not too short, otherwise, prior to the completion of tasks performed automatically releases the lock, resulting in exposure to resources outside the lock protection. Timeout time not too long, otherwise it will lead to long wait after an unexpected deadlock. And, unless the access process. Therefore recommendations are based on the content of the task, a reasonable measure of the timeout, the timeout several times to the task content. If it can not be determined yet more stringent requirements, can be used on a regular basis setex / expire update timeout implementation.

Retry

If you can not get the lock, it is recommended to wait for polling task based on the nature of business forms. Waiting times need to refer to the task execution time.

Compared with redis affairs

setnx use more flexible scheme. multi / exec transactions realized in the form of more complex. Redis clusters and some programs (such as codis), does not support multi / exec affairs.

Follow us

Follow us

Guess you like

Origin juejin.im/post/5e00c92b6fb9a016194b0aa0