使用ZooKeeper进行不频繁操作的有效排他锁

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用ZooKeeper进行不频繁操作的有效排他锁相关的知识,希望对你有一定的参考价值。

我将微服务部署在具有两个主要数据源的多台服务器上:

  1. 事件以高音量(100-1000事件/秒)持续(24/7/365)接收到

  2. 每天一次的操作,可能需要一点时间才能完成

我想以独占模式运行此每天一次的处理:暂停事件处理,运行每天一次的任务,然后恢复事件处理。我已经有办法正确地开始每天一次的操作,但是我仍然必须在1和2之间实施锁定以确保排他性。

我发现的大多数ZooKeeper配方都需要对每个已处理事件进行写操作,例如InterProcessReadWriteLock时读取锁定获取,InterProcessReadWriteLock时计数器增加。由于每天很少出现这种情况,因此每个事件的开销似乎很浪费。

是否存在针对此类用例进行了优化的ZooKeeper / Curator收据?

我考虑过要遵循,但我不确定100%是否是正确的方法(以及如何实施下面的第2点):

  1. 每天运行一次时,在ZooKeeper中创建新的DistributedAtomicLong路径
  2. 等待所有机上活动结束
  3. [处理事件之前,请检查是否存在DistributedAtomicLong。如果在那里,请停止处理,直到删除/exclusive路径
  4. 每天结束时删除/exclusive路径
答案
每个事件处理器必须:

通过/exclusive获得

    read锁。
  • 使用/exclusive监视“信号”节点并侦听此节点上的更改。当该节点存在时,表示它是每日处理时间。如果不存在,则可以进行事件处理。
  • [当NodeCache显示已创建信号节点时,事件处理器必须释放其锁,并等待信号节点被删除(再次通过监听NodeCache进行。)
  • [当NodeCache显示信号节点已被删除时,事件处理器再次获取读锁并继续处理事件。
  • 一旦设置好,所有的ZooKeeper活动都将运行。
  • 当每天一次的操作准备运行时:

    它创建信号节点(作为临时节点)

    • 在与事件处理器用于其读取锁的路径相同的路径上获取
    • write锁
    • 进行定期处理
    • 释放写锁
    • 删除信号节点
  • 但是,有一个很大的警告,这就是JVM暂停可能发生的情况。对于重要的边缘情况,也请阅读此InterProcessReadWriteLock
  • 以上是关于使用ZooKeeper进行不频繁操作的有效排他锁的主要内容,如果未能解决你的问题,请参考以下文章

    zookeeper常见的操作命令

    JUC之ReadWriteLockReentrantReadWriteLock读写锁

    sql server 锁

    如何在springcloud分布式系统中实现分布式锁?

    利用springcloud+Redis在分布式系统中实现分布式锁

    MySQL中的共享锁与排他锁