分布式锁
分布式锁的实现简介
分布式CAP理论告诉我们需要做取舍:
任何一个分布式系统都无法同时满足一致性Consistency、可用性Availability和分区容错性PartitionTolerance三个方面,最多只能同时满足两项。
在互联网领域的绝大多数的场景中,都需要牺牲强一致性来换取系统的高可用性,系统往往只保证最终一致性。在很多场景中为了保证数据的最终一致性,需要很多的技术方案来支持,比如分布式事务、分布式锁等。
分布式锁一般有三种实现方式:
基于数据库
在数据库中创建一张表,表里包含方法名等字段,并且在方法名字段上面创建唯一索引,执行某个方法需要使用此方法名向表中插入数据,成功插入则获取锁,执行结束则删除对应的行数据释放锁
基于缓存数据库Redis
Redis性能好并且实现方便,但是单节点的分布式锁在故障迁移时产生安全问题,Redlock是Redis的作者Antirez提出的集群模式分布式锁,基于N个完全独立的Redis节点实现分布式锁的高可用
基于ZooKeeper
ZooKeeper是以Paxos算法为基础的分布式应用程序协调服务,为分布式应用提供一致性服务的开源组件
分布式锁需要具备的条件
分布式锁在应用于分布式系统环境相比单机锁更为复杂,本文讲述基于Redis的分布式锁实现,该锁需要具备一些特性:
互斥性
在任意时刻,只有一个客户端能持有锁其他尝试获取锁的客户端都将失败而返回或阻塞等待
健壮性
一个客户端持有锁的期间崩溃而没有主动释放锁,也需要保证后续其他客户端能够加锁成功,就像C++的智能指针来避免内存泄漏一样
唯一性
加锁和解锁必须是同一个客户端,客户端自己不能把别人加的锁给释放了,自己持有的锁也不能被其他客户端释放
高可用
不必依赖于全部Redis节点正常工作,只要大部分的Redis节点正常运行,客户端就可以进行加锁和解锁操作
基于单Redis节点的分布式锁
本文的重点是基于多Redis节点的Redlock算法,不过在展开这个算法之前,有必要提一下单Redis节点分布式锁原理以及演进,因为Redlock算法是基于此改进的。
最初分布式锁借助于setnx和expire命令,但是这两个命令不是原子操作,如果执行setnx之后获取锁但是此时客户端挂掉,这样无法执行expire设置过期时间就导致锁一直无法被释放,因此在2.8版本中Antirez为setnx增加了参数扩展,使得setnx和expire具备原子操作性。
在单Matster-Slave的Redis系统中,正常情况下Client向Master获取锁之后同步给Slave,如果Client获取锁成功之后Master节点挂掉,并且未将该锁同步到Slave,之后在Sentinel的帮助下Slave升级为Master但是并没有之前未同步的锁的信息,此时如果有新的Client要在新Master获取锁,那么将可能出现两个Client持有同一把锁的问题。
结束语:以上就是关于分布式锁的算法一般的实现方式的全部内容,更多内容请关注学步园。