Home >Database >Redis >How Redis implements distributed lock function

How Redis implements distributed lock function

王林
王林Original
2023-11-07 15:28:55845browse

How Redis implements distributed lock function

How Redis implements the distributed lock function

Distributed lock is a synchronization mechanism commonly used in distributed systems. It can help us synchronize multiple processes or Implement mutually exclusive access to shared resources between multiple servers. As a high-performance cache and message queue middleware, Redis also provides the function of implementing distributed locks. This article will introduce how Redis implements distributed locks and provide specific code examples.

  1. Distributed lock based on SETNX command

Redis provides the SETNX command, which can set the value of the key when the key does not exist. If the key already exists, The command execution fails. We can use the SETNX command to implement the distributed lock function.

The following is a sample code for a distributed lock based on the SETNX command:

import redis

class RedisLock:
    def __init__(self, key, value, expire_time):
        self.redis = redis.Redis(host='localhost', port=6379, db=0)
        self.key = key
        self.value = value
        self.expire_time = expire_time

    def acquire(self):
        while True:
            result = self.redis.setnx(self.key, self.value)
            if result:
                self.redis.expire(self.key, self.expire_time)
                return True

    def release(self):
        self.redis.delete(self.key)

In the above code, we define a RedisLock class, which has two methods: acquire and release. The acquire method attempts to acquire the distributed lock and returns True if the acquisition is successful; the release method releases the distributed lock.

You can call it like this when using it:

lock = RedisLock('my_lock', '1', 10)
if lock.acquire():
    try:
        # 执行需要加锁的业务逻辑
        ...
    finally:
        lock.release()
  1. Distributed lock based on SET command and Lua script

The above implementation based on SETNX command is in There may be problems in some cases. For example, when the execution time of business logic is very long, it may cause lock failure. In order to solve this problem, we can use Lua script combined with SET command to implement distributed lock.

The following is a sample code for distributed lock based on SET command and Lua script:

import redis

class RedisLock:
    def __init__(self, key, value, expire_time):
        self.redis = redis.Redis(host='localhost', port=6379, db=0)
        self.key = key
        self.value = value
        self.expire_time = expire_time

    def acquire(self):
        script = '''
            if redis.call("exists", KEYS[1]) == 0 then
                redis.call("set", KEYS[1], ARGV[1])
                redis.call("expire", KEYS[1], tonumber(ARGV[2]))
                return 1
            else
                return 0
            end
        '''
        result = self.redis.eval(script, 1, self.key, self.value, self.expire_time)
        return result == 1

    def release(self):
        self.redis.delete(self.key)

In the above code, we use the eval method to call the Lua script, and the script determines whether the key is Exists to decide whether to set the key's value and expiration time. In this way, even if the business logic execution takes a long time, there will be no lock failure problem.

The usage method is the same as the above implementation based on SETNX command.

Summary:

This article introduces how Redis implements the distributed lock function, and provides code examples based on SETNX commands and two implementations based on SET commands and Lua scripts. In practical applications, we can choose a suitable implementation method to implement distributed locks according to needs to ensure mutually exclusive access to shared resources.

The above is the detailed content of How Redis implements distributed lock function. For more information, please follow other related articles on the PHP Chinese website!

Statement:
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