分布式或微服务架构中的分布式锁应用

1. 分布式锁特征

  在很多分布式或微服务架构产品应用中,有些场景需要加锁处理,要求分布式锁具备如下特性:

1、要求每个事物都有各自一把锁。

2、锁互斥,不管任何时候,只有一个客户端能持有同一个锁。

3、锁具有自动释放特征(超时后会自动释放),确保不会死锁,最终客户端一定会得到锁,就算一个持有锁的客户端宕掉。

4、锁的时效设置。避免单点故障造成死锁,影响其他客户端获取锁。但是也要保证一旦一个客户端持锁,在客户端可用时不会被其他客户端解锁。

5、加锁的事务或者操作尽量粒度小,减少其他客户端申请锁的等待时间,提高处理效率和并发性。

6、客户端在不再需要锁或者任务执行完成之后需要主动释放锁,这样其他客户端就不用等到超时时间再去获取这个锁。

7、当一个客户端尝试获取锁时,如果这个锁被其他客户端占用,则立即返回,不做任何业务处理,此目的在于确保同一时刻只有一个客户端在执行特定网元告警同步操作即可。

8、提供分布式锁的中间件,需要具有高可靠、容灾等特性,确保分布式锁稳定性。

2. 分布式锁选型

  分布式锁以往大部分的解决方案是基于数据库来实现的,这种方式业务实现比较复杂,比如需要开发人员自行实现锁超时释放机制,避免死锁问题。那么如何找到一款能够满足各种应用场景的分布式锁组件呢?

2.1 ZooKeeper分布式锁

  ZooKeeper是一个分布式应用程序协调服务,为分布式应用提供一致性服务的组件。ZooKeeper节点结构是一个和文件系统类似的小型的树状的目录结构,同时Zookeeper机制规定:同一个目录下只能有一个唯一的文件名。例如:在ZooKeeper的根目录下,由两个客户端同时创建一个名为/locks/ne_node,则只有一个客户端可以创建成功。因此,可以通过ZooKeeper节点为每个待告警同步的网元来创建一个锁,例如/locks/10.63.204.101就可以定义为一个锁。ZooKeeper分布式锁架构示意图如下:

blob.png 

  另外,ZooKeeper有一种临时类型的节点,临时节点由某个客户端创建,当客户端因为宕机,与ZooKeeper集群断开连接时,则该临时节点会被自动删除,从而避免了死锁问题。

客户端在获取到锁之后,开始执行互斥业务逻辑,执行完成后,显示删除临时节点,即可释放锁。
 

2.2 Redis分布式锁

  Redisson在基于NIO的Netty框架上,充分的利用了Redis键值数据库提供的一系列优势,在Java实用工具包中常用接口的基础上,为使用者提供了一系列具有分布式特性的常用工具类。Redisson提供了分布式锁特性,开发者可直接利用开发相关业务。

Redis分布式锁架构示意图如下:

blob.png

2.3 分布式锁比对

 

可重入锁

持锁断开连接后释放锁

锁持久化

优缺点

ZK

支持

支持,临时节点当连接中断会删除锁

支持

安全性较高,支持锁持久化存储,但效率稍低

Redis

支持

支持,过期时间

不支持

安全性较低,不支持锁持久化存储,但效率较高

3 分布式锁总结

  除了上面提到的ZooKeeper和Redis外,还有很多技术可以实现分布式锁。在思考是否采用分布式锁以及采用哪种实现方案的时候,还是要基于业务,技术方案一定是基于业务基础,服务于业务,并且衡量过投入产出比的。所以如果有成熟的解决方案,在业务可承受规模肯定是不要重复造轮子,当然还要经过严谨的选型和测试。开发者在实际开发中,可权衡利弊,选择一种最合适业务场景的分布式锁来实现相关业务。

原文地址:https://www.cnblogs.com/lixiaochun/p/8496351.html