美文网首页Java学习笔记开发技巧Java 杂谈
不要老盯着redis分布式锁,这绝对不是一个简单的方案

不要老盯着redis分布式锁,这绝对不是一个简单的方案

作者: 腾讯码农之家 | 来源:发表于2020-12-19 16:37 被阅读0次

    分布式锁相比较多线程锁,更加高级一些。它的作用范围,也由单机转换为分布式,是常用的资源协调手段。常用的有redis分布式做和zk分布式锁。但它们有什么区别呢?我们在平常使用中,又该如何选择。

    1. 解析

    这个问题对要求较高,它不仅要了解实现方法,还要对原理有所掌握。所以问题回答起来,分为很多层次。

    众所周知,Redis标榜的是轻量级,直观上分布式锁是比较好实现的,比如使用setnx,但一旦加入高可用这个属性,Redis锁的实现难度就会爆炸式上升。

    再加上锁的其他几个属性:乐观悲观、读写锁等,事情会更加的复杂。

    如果你全都知晓,聊一天都聊不完。

    2. 尝试分析以下

    先来一个,比较浅显、入门的分析:

    redis的分布式锁,可以基于setnx指令实现(但其实更建议使用带nx参数的set指令)

    zk的分布式锁,是基于临时节点的有序性和节点的监听机制完成的

    这种回答方式,直接把自己给绕进去了,因为这涉及到非常多的细节。别人只是问区别,为什么把自己往源码级别绕呢?

    建议这样分析:

    Redis,使用redisson封装的RedLock

    Zk,使用curator封装的InterProcessMutex

    对比:

    实现难度上:Zookeeper >= redis

    服务端性能:redis > Zookeeper

    客户端性能:Zookeeper > redis

    可靠性:Zookeeper > redis

    细聊:

    2.1 实现难度

    对于直接操纵底层API来说,实现难度都是差不多的,都需要考虑很多边界场景。但由于Zk的ZNode天然具有锁的属性,所以直接上手撸的话,很简单。

    Redis需要考虑太多异常场景,比如锁超时、锁的高可用等,实现难度较大。

    2.2 服务端性能

    Zk基于Zab协议,需要一半的节点ACK,才算写入成功,吞吐量较低。如果频繁加锁、释放锁,服务端集群压力会很大。

    Redis基于内存,只写Master就算成功,吞吐量高,Redis服务器压力小。

    2.3 客户端性能

    Zk由于有通知机制,获取锁的过程,添加一个监听器就可以了。避免了轮询,性能消耗较小。

    Redis并没有通知机制,它只能使用类似CAS的轮询方式去争抢锁,较多空转,会对客户端造成压力。

    2.4 可靠性

    这个就很明显了。Zookeeper就是为协调而生的,有严格的Zab协议控制数据的一致性,锁模型健壮。

    Redis追求吞吐,可靠性上稍逊一筹。即使使用了Redlock,也无法保证100%的健壮性,但一般的应用不会遇到极端场景,所以也被常用。

    3. 扩展

    Zk的分布式锁样代码样例:

    RedLock的分布式锁使用样例:

    再附一段RedLock的内部lock和unlock的代码实现,以便对你对其复杂度有一定的了解。

    所以,建议使用已经封装好的组件。如果你非要使用setnx或者set指令去做这些事,xjjdog只能说是想被虐。基本原理我们可以做到了解,这些细节,不下点功夫是理不清的。

    说了这半天,我们选型的时候,该如何做呢?这要看你的基础设施。如果你的应用用到了zk,而且集群性能很强劲,优选zk。如果你只有redis,不想为了个分布式锁,引入臃肿的zk,那就用redis。

    相关文章

      网友评论

        本文标题:不要老盯着redis分布式锁,这绝对不是一个简单的方案

        本文链接:https://www.haomeiwen.com/subject/wmdcnktx.html