1分布式锁介绍 · SpringCloud微服务实战 · 看云
导航
1. 为什么用分布式锁
在单机应用中,如果有多个线程,它们不需要访问共享资源、也不需要线程间的协调,因此都没事,一旦需要访问共享资源,程序中就要借助比如synchronized、线程安全的对象提供的机制来进行处理
在分布式系统中,当多台机器需要访问同一个共享资源的时候,也会遇到同样的问题,这时候就需要一个分布式锁,实际上单体应用面临的问题在分布式系统中也会遇到。
2. 分布式锁特点
- 互斥性:和我们本地锁一样互斥性是最基本,但是分布式锁需要保证在不同节点的不同线程的互斥
- 可重入性:同一个节点上的同一个线程如果获取了锁之后那么也可以再次获取这个锁
- 锁超时:和本地锁一样支持锁超时,防止死锁
- 高效,高可用:加锁和解锁需要高效,同时也需要保证高可用防止分布式锁失效,可以增加降级
- 支持阻塞和非阻塞:和ReentrantLock一样支持lock和trylock以及tryLock(long timeOut)
- 支持公平锁和非公平锁(可选):公平锁的意思是按照请求加锁的顺序获得锁,非公平锁就相反是无序的。这个一般来说实现的比较少
3. 分布式锁的实现方式
用锁的过程一般包括三部分:分布式定义锁、获取锁、释放锁。目前实现分布式锁的一般借助数据库、Redis和Zookeeper。
4. Redis和Zookeeper的分布式锁对比
| 对比 | Redis | Zookeeper |
|---|---|---|
| 失效时间问题 | 可指定超时时间 | 客户端session断开即失效 |
| 阻塞问题 | 可通过循环解决 | Zookeeper可以实现阻塞的锁 |
| 锁重入问题 | 把当前主机信息和线程信息保存起来 | 把当前客户端的主机信息和线程信息直接写入到节点中 |
| 单点问题 | 集群部署,可以避免单点问题 | ZK是集群部署的,只要集群中有半数以上的机器存活 |
| 存在问题 | 如何设置的失效时间太短,方法没等执行完,锁就自动释放了,那么就会产生并发问题 | ZooKeeper中创建和删除节点只能通过Leader服务器来执行,然后将数据同不到所有的Follower机器上 |
| 性能 | 较高 | 一般 |