Home >Database >Redis >The principles and implementation of common distributed locks in Redis (summary sharing)

The principles and implementation of common distributed locks in Redis (summary sharing)

WBOY
WBOYforward
2022-08-25 11:53:502470browse

Recommended learning: Redis video tutorial

Locks in Java mainly include synchronized locks and locks in the JUC package. These locks They are all for locks on a single JVM instance and are invalid for distributed environments. So how to implement distributed locks?

The implementation of common distributed locks is as follows:

Based on database

Pessimistic lock

Pessimistic Lock (Pessimistic Lock), as the name suggests, is a very pessimistic lock. It will be locked every time when data is retrieved. In this way, others who want to get the data will be blocked until the pessimistic lock is released. The shared resources in the pessimistic lock are only used by one thread at a time, and other threads are blocked. After use, the resources are transferred to other threads. However, in terms of efficiency, the processing The locking mechanism generates additional overhead and is prone to deadlocks.

Implementation Principle

Pessimistic concurrency control is actually a conservative strategy of "get the lock first and then access", which provides a guarantee for the security of data processing.

Specific implementation

For example, the pseudo code to achieve inventory deduction through pessimistic locking is as follows:

// 对于库存记录进行行锁

SELECT *FROM sys_goods s WHERE s.Id='1' FOR UPDATE;

//执行库存扣减
update sys_stock s set s.stockQty=s.stockQty-#{number} where s.goodId=1 and s.stockQty>0;

//提交事务,自动释放悲观锁。

Optimistic lock

Introduction

Optimistic locking is implemented based on the data version number (version) mechanism. Add a "version" field to the database table. When reading the data, this version number is read out. During the update process, the version numbers are compared. If they are consistent, the operation will be executed successfully and the version number will be incremented. 1. If the version numbers are inconsistent, the update will fail.

Implementation Principle

Compared with pessimistic locking, the implementation of optimistic locking does not use the locking mechanism of the database. The principle of optimistic locking is implemented using the CAS mechanism. CAS (Compare-and- Swap) means compare and replace.

  • 1, Comparison: Read a value A, before updating it to B, Check whether the original value is still A (not changed by other threads).
  • 2. Settings: If the change is not sent, update A to B and end. If a change occurs, do nothing.

Specific implementation

For example, the pseudo code for optimistic locking to implement inventory deduction is as follows:

// 查询库存记录,获取版本号
SELECT stockQty,version FROM sys_goods s WHERE s.Id='1'

//执行库存扣减,防止出现超卖
update sys_stock s set 
  s.stockQty=s.stockQty-#{number},
  s.version=version+1
  where s.goodId=1 and s.stockQty>0 and version=#{version};

Redis implements distributed lock

The implementation of Redis distributed lock has been explained in previous articles. You can refer to the following article

Spring Boot implements the principle of Redis distributed lock

Spring Boot integration Detailed case of Redisson implementing distributed locks

Zooker implementing distributed locks

Zookper implements distributed locks, mainly by applying the temporary and orderly nature of zookeeper nodes.

Lock process

When client 1 requests, the Zookeeper client will create a persistent node Locks node. If client 1 wants to obtain the lock, it will create a temporary node under the locks node/ node_000000, if you find all temporary ordered child nodes under Locks, when you are the smallest node, you will successfully acquire the lock.

When client 2 tries to acquire the lock, it will also check the temporary nodes under locks to determine whether its own node/node_000001 is the smallest. If it is not the smallest, it will fail to acquire the lock. , client 2 will register a watch event with its top-ranked node node_000000 to monitor whether node_000000 exists. Although the lock grab fails, node_000001 enters the waiting state.

The process of releasing the lock

When the Zookeeper client service is completed or the client fails, the temporary node will be deleted and the lock will be released. If the task is completed, client 1 will also explicitly call the instruction to delete node_000000.

For example, in the above figure, client 1 is disconnected and the temporary node node_000000 has been deleted. At this time, node_000001 finds itself as the smallest temporary node through watcher monitoring, so it gets Lock successful.

异常场景分析

客户端1创建临时节点后,会与Zookeeper服务器维护一个Session,这个Session会依赖客户端 定时心跳来维持连接。由于网路异常原因,Zookeeper长时间收不到客户端1的心跳,就认为这个Session过期了,也会把这个临时节点删除,此时客户端2创建临时节点能够获取锁成功。当客户端网络恢复正常后,它仍然认为持有锁,此时就会造成锁冲突。

具体实现

Zookeeper实现分布式锁,可以采用Curator实现分布式锁,关于SpringBoot如何集成Curator,大家可以参考如下文章:

Java Spring Boot 集成Zookeeper

Zookpeer实现分布式锁实现库存扣减

 @RequestMapping("/lockStock")
    public void lockStock()
    {
       zooKeeperUtil.lock("/Locks", 1000, TimeUnit.SECONDS, ()->{
           //业务逻辑
       });
    }

小结:

关于分布式锁的实现的对比,详情请查看下图:

推荐学习:Redis视频教程

The above is the detailed content of The principles and implementation of common distributed locks in Redis (summary sharing). For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:jb51.net. If there is any infringement, please contact admin@php.cn delete