Redis分布式锁
一、什么是分布式锁
分布式锁,即是在分布式项目中使用的锁,主要用来控制多个实例同时访问共享资源。当服务器抢占到锁时,即可对共享资源进行操作,未抢占到锁的服务器则直接返回失败或者阻塞轮询获取分布式锁。
分布式锁主要满足以下几个特点:
- 互斥性:在任何时刻,对于同一条数据,只有一台应用可以获取到分布式锁;
- 高性能和高可用性:加锁和释放锁的过程性能开销要尽可能的低,同时也要保证高可用,防止分布式锁意外失效(通过集群实现)。
- 独占性:加锁解锁必须由同一台服务器进行,锁的持有者才可以释放锁;
- 可重入性:持有锁的实例可以再次请求锁,防止锁在线程执行完临界区操作前释放
- 防止死锁:具有锁失效策略(比如持有锁的时间超过指定值时,则锁自动释放)
二、常见分布式锁实现
-
基于数据库实现
- 优势:实现简单
- 缺点:
- 不能定时释放锁,如果占有锁的应用挂掉了,其他应用就一直不能获取到锁
- 强依赖数据库,一旦数据库挂掉,则业务系统不可用
- 不可重入,同一个线程在没有释放锁之前无法再次获得该锁。因为数据中数据已经存在了。
- 实现方式:
- 建立一张lock表,表中根据共享资源设置一个唯一字段
- 当需要访问共享资源时,就向表中插入一条数据
- 插入成功则表示抢占到锁,执行完成后删除掉对应的数据以实现释放锁。
-
基于redis实现
- 优点:具有高性能、高可用,可解决失效死锁问题
- 缺点:单机redis不支持高可用,且可能存在两个实例同时占有锁的问题
-
基于zookeeper实现
- 优点:具备高可用、可重入、阻塞锁特性,可解决失效死锁问题。
- 缺点:因为需要频繁的创建和删除节点,性能上不如Redis方式。
- 实现方式:
- 创建一个目录mylock;
- 线程A想获取锁