【Zookeeper】分布式锁
一、概述
- 分布式锁解决方案(目的:为了保证在分布式领域中共享数据安全问题)
- 数据库实现分布式锁(不推荐、效率特别低)
- 基于Redis实现分布式锁setNx (非常麻烦考虑死锁、释放问题) 、redission分布式锁
- 基于Zookeeper实现分布式锁(强烈推荐)
SpringCloud内置实现全局锁(冷门)实现起来非常简单,使用临时节点释放锁(效率最高)、失效时间容易控制
- 分布式锁(产生的原因:因为服务器产生集群)
- 在单台服务器上如何生成订号( 保证唯一) UUId、时间戳、(大公司)redis
- 为什么要用redis去生成订单号 提前生成好150万订单号,存放在redis中,当客户端下单的之后,直接取redis获取对应的订单号即可,因为redis本身是单线程,如果redis还只剩下50万个订单号的时候,有继续在生成100万个订单号。
- 如果在集群的环境下使用UUId、时间戳能够保证订单号唯一性问题?不能
实现原理
- 多个jvm同时在zookeeper上创建同一个相同的节点(/lock) ,因为zookeeper节点是唯一的,如果是唯一的话,那么同时如果有多个客户端创建相同的节点/lock的话,最终只有看谁能够快速的抢资源,谁就能创建/lock节点,这个时候节点类型应该使用临时类型。
- 如果jvm1已经创建节点成功,那么这个时候jvm2、jvm3创建的节点时候,会报该/lock节点已经存在。这个时候jvm2和jvm3进行等待。如果jvm1现在已经程序已经执行完毕的话,
- Zookeepre如何实现释放锁?如果jvm1现在已经程序已经执行完毕的话,当前jvm1的ZK已经关闭当前Session会话。
- Zookeepre如何获取锁?看谁请求创建节点快,谁就可以拿到锁。
- 这时候jvm2和jvm3使用Watcher (事件通知)获取/lock已经被删除,这时候重新进入到获取请求。
- 如果程序一直不处理完,可能导致死锁,可以设置有效期,看业务情况,60秒,zk连接不要强制关闭,百分百延迟,直接调用close,产生延迟的概率非常小。
实现代码
************ **供自己学习查阅使用(我只想静静的写篇博客,自我总结下[手动狗头]) by Pavel** *********