发布时间:2022-08-19 14:12
在分布式系统中,分布式锁用来解决分布式系统中多线程、多进程在不同机器上共享资源访问的问题。本文简要介绍分布式锁的四种实现机制,包括数据库、Redis缓存、Zookeeper和Etcd,以加深了解。
在单体应用中,通过锁机制实现多线程对共享资源的访问的,在分布式系统中,由于多线程、多进程是分布在不同的机器上,单机部署的并发锁控制机制已经不能满足分布式要求。分布式锁就是解决分布式系统中共享资源访问的问题,与单体应用不同的是,资源控制的最小粒度也从线程升级到了进程。
为了满足分布式系统中资源的并发访问控制,分布式锁在设计上应满足以下原则:
常见的分布式锁实现方法有几种:基于数据库通过唯一索引实现、基于缓存Redis实现、基于一致性算法Zookeeper或Etcd实现
下面将分别介绍以上几种实现方法。
基于数据库实现分布式锁的原理是使用表的唯一索引:在数据库中创建一个表,表中包含方法名等字段,并在方法名字段上创建唯一索引,想要执行某个方法,就是要这个方法名向表中插入数据,成功插入则获取锁,执行完成后删除对应的行数据释放锁。
CREATE TABLE `distributed_lock` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`unique_method` varchar(255) NOT NULL COMMENT '锁定的方法名',
`holder_id` varchar(255) NOT NULL COMMENT '锁持有者id',
`create_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `unique_method_index` (`unique_method`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
其中id字段为自增id,unique_method字段就是防重的唯一方法名,也就是加锁的对象。在表中创建了唯一索引,保证unique_method的唯一性。
1)加锁即插入一条记录
insert into distributed_lock(unique_method, holder_id) values (‘unique_method’, ‘holder_id’);
如果当前sql执行成功代表加锁成功,如果抛出唯一索引异常(DuplicatedKeyException)则代表加锁失败,当前锁已经被其他竞争者获取。
2)解锁很简单,直接删除此条记录即可
delete from methodLock where unique_method=‘unique_method’ and holder_id=‘holder_id’;
3)数据库实现简单,操作简单,用操作数据库的方式即可实现锁,但是存在以下问题: