现在很多码农都有接触到redis和ZK,那么Redis和ZK实现分布式锁的区别有哪些呢?
由于本地锁的作用范围只限于当前应用的线程。高并发场景下,集群中某个应用的本地锁并不会对其它应用的资源访问产生互斥,就会产生数据不一致的问题,所以分布锁就派上了用场。
setnx争抢key的锁,如果已有key存在,则不作操作,过段时间继续重试,保证只有一个客户端能持有锁。获取锁对应的value值,检查是否与requestId相等,如果相等则删除锁。使用lua脚本实现原子操作,保证线程安全。
redis版分布式锁很好,用起来很方便,实现也不难而且还有现成的,可惜主从不是强一致在redis集群的场景下会有问题,zk解决了这个问题不过说实话用得很少
zk那个模式完美诠释了分布式锁的几个抽象出来的步骤:
1. 向一个公共组件互斥地申请一个标志,拿到了认为取到锁(redis setnx);
2. 维持心跳(redis setex+持续expire),心跳断了自动释放;
3. 业务逻辑执行完毕释放该标志;
NPC问题感觉太深入了,真要纠结到这个地步,可能应该看一下是不是要换个思路,绕开使用分布式锁。
ZK具有较好的稳定性,响应时间抖动很小,没有出现异常。但是随着并发量和业务数量的提升其响应时间和qps会明显下降。
Redis 实现的分布式锁基本原理是利用 Redis 本身提供的 SETNX 命令,而 ZooKeeper 的分布式锁是基于 ZooKeeper 独特的节点监听机制实现的。