分布式系列基于zookeeper解决分布式锁问题与缓存技术实现分布式锁
Posted 程序猿小秘圈
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分布式系列基于zookeeper解决分布式锁问题与缓存技术实现分布式锁相关的知识,希望对你有一定的参考价值。
简化生活的主张,某种程度上看似不近人情,其实真正践行后所得到的轻松快乐,无以言表,最重要的,还会省钱,我们人活一生,是为了体验生命,而不是为了拥有物品。
基于zookeeper解决分布式锁问题
基于问题三中分析图中加入zookeeper,谁先得到zookeeper 锁,谁先更新redis cluster ,同时缓存数据加入当时的时间(版本控制、比较),没有得到锁的等待。
zookeeper分布式锁的解决逻辑思路
变更缓存重建或者空缓存请求重建,更新redis之前,先获取对应商品id的分布式锁
拿到分布式锁后,做时间版本比较,如果自己的版本新于redis中的版本,那么就更新,否则就不更新
如果拿不到分布式锁,那么就等待,不断轮询等待,直到自己获取到分布式的锁。
基于缓存实现分布式锁
相比较于基于数据库实现分布式锁的方案来说,基于缓存来实现在性能方面会表现的更好一点。而且很多缓存是可以集群部署的,可以解决单点问题。
目前有很多成熟的缓存产品,包括Redis,memcached以及我们公司内部的Tair。
这里以Tair为例来分析下使用缓存实现分布式锁的方案。关于Redis和memcached在网络上有很多相关的文章,并且也有一些成熟的框架及算法可以直接使用。
基于Tair的实现分布式锁其实和Redis类似,其中主要的实现方式是使用TairManager.put方法来实现。
以上实现方式同样存在几个问题:
1、这把锁没有失效时间,一旦解锁操作失败,就会导致锁记录一直在tair中,其他线程无法再获得到锁。
2、这把锁只能是非阻塞的,无论成功还是失败都直接返回。
3、这把锁是非重入的,一个线程获得锁之后,在释放锁之前,无法再次获得该锁,因为使用到的key在tair中已经存在。无法再执行put操作。
当然,同样有方式可以解决。
没有失效时间?tair的put方法支持传入失效时间,到达时间之后数据会自动删除。
非阻塞?while重复执行。
非可重入?在一个线程获取到锁之后,把当前主机信息和线程信息保存起来,下次再获取之前先检查自己是不是当前锁的拥有者。
但是,失效时间我设置多长时间为好?如何设置的失效时间太短,方法没等执行完,锁就自动释放了,那么就会产生并发问题。如果设置的时间太长,其他获取锁的线程就可能要平白的多等一段时间。这个问题使用数据库实现分布式锁同样存在。
以上是关于分布式系列基于zookeeper解决分布式锁问题与缓存技术实现分布式锁的主要内容,如果未能解决你的问题,请参考以下文章