hi, I have forgotten how long I haven't blogged, and now I'm officially back! What I want to share today is the principle and implementation of distributed locks; in the process of system software development, we often have such a scenario: we have many tasks that need to be processed at the same time, and these tasks need to be accessed during the execution process. Modify a public resource; if each thread can modify the resource at will, the final result of our public resource may be inconsistent with what we expect (for example: deduction of inventory); at this time, we need the same time, only There is a thread to access and modify public resources; to achieve this function, we need to use locks; JDK's JUC provides many related implementations, such as: synchronized, ReenreantLock, etc.; however, when the program is deployed to multiple servers at the same time, we Distributed locks are required. For the implementation of distributed locks, the following schemes are commonly used:
- 1. The database implements distributed locks: the principle is simple, the performance is poor
- 2. Distributed lock implemented by redis: the best performance
- 3. Distributed locks implemented by zookeeper: Distributed locks: the best reliability
1. Based on database table method 1: By creating a separate database table biz_lock
CREATE TABLE `biz_lock` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`biz_name` varchar(64) NOT NULL DEFAULT '' COMMENT '锁定的业务/资源',
`remarks` varchar(1024) NOT NULL DEFAULT '备注信息',
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '保存数据时间,自动生成',
PRIMARY KEY (`id`),
UNIQUE KEY `uidx_biz_name` (`biz_name`) USING BTREE
)
ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='锁定中的业务/资源';
How to use : When we want to lock a method or resource, we add a record to the table, and delete this record when we want to release the lock.
(1).获取锁
insert into biz_lock(biz_name,remarks) values ('resort_room_stock_operate','酒店房间库存操作')
(2).释放锁
delete from methodLock where biz_name ='biz_name'
Method 2: Do optimistic locking based on database tables
常用的方法是为数据增加一个版本标识,每次修改记录的时候需要比对版本号是否一致;
(1).查询商品记录下本次操作前的version
select (id,status,version) from t_goods_info where id=#{id}
(2).根据商品信息生成订单
(3).修改商品status为2
update t_goods_info
set status=2,version=version+1
where id=#{id} and version=#{version};
Method 3: Database pessimistic lock Before each operation, go to the database to obtain the lock, and then perform the operation to complete the submission
select * from t_goods_info where id = #{id} for update
2. Distributed locks implemented by redis (there are about three ways)
(1).jredis implements it by itself
a.【setnx】+命令实现分布式锁(set if not exist)
b.lua脚本实现redis分布式锁
(2).Redisson implementation
RedissonLock、RedissonRedLock
Three, zookeeper
(1)、使用zookeeper API根据节点监听和临时有序节点功能实现
(2)、Apache Curator