代码之家  ›  专栏  ›  技术社区  ›  Karol Dowbecki

配有ZooKeeper的高效专属锁,可用于不频繁的操作

  •  0
  • Karol Dowbecki  · 技术社区  · 6 年前

    我在多台服务器上部署了一个微服务,它有两个主要的数据源:

    1. 以高容量(100-1000个事件/秒)持续接收事件(365年7月24日)

    2. 每天一次的手术,可能需要一段时间才能完成

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

    我发现的大多数ZooKeeper菜谱都需要对每个处理过的事件进行写入操作,例如使用 InterProcessReadWriteLock 或者用 DistributedAtomicLong .由于每天一次的运营很少发生,因此每次的开销似乎是浪费。

    是否有动物园管理员/策展人收据针对这种用例进行了优化?

    我考虑过以下方法,但我不确定这是否是正确的方法(以及如何实现下面的第2点):

    1. 当每天一次的操作开始时,创建新的 /exclusive 动物园管理员之路
    2. 等待所有飞行事件完成
    3. 在处理事件之前,请检查 /独家的 存在。如果有,停止处理,直到 /独家的 路径被删除
    4. 每天一次结束后,移除 /独家的 路径
    0 回复  |  直到 6 年前
        1
  •  1
  •   Randgalt    6 年前

    这个呢?

    每个事件处理器必须:

    • 获得 阅读 锁孔 InterProcessReadWriteLock .
    • 使用 NodeCache 观察“信号”节点并监听该节点上的更改。当节点存在时,这意味着它是每天的处理时间。当它不存在时,事件处理可以继续。
    • 当NodeCache显示信号节点已创建时,事件处理器必须释放其锁并等待信号节点被删除(再次通过使用NodeCache监听)。
    • 当NodeCache显示信号节点已被删除时,事件处理器将再次获取读取锁并继续处理事件。

    一旦设置好了,就不会有任何额外的ZooKeeper活动了。

    当每天一次的操作准备好运行时:

    • 它创建信号节点(作为临时节点)
    • 获得 与事件处理器用于读取锁的路径相同
    • 它的周期性处理
    • 释放写锁
    • 删除信号节点

    然而,这有一个巨大的警告,这就是JVM暂停可能发生的情况。请同时阅读这篇文章 Tech Note 对于重要的边缘情况。