基于ZooKeeper的分布式锁

基于配置中心的分布式锁

这里以ZooKeeper为例,ZooKeeper基于树形数据存储结构实现分布式锁,来解决多个进程同时访问同一临界资源时,数据的一致性问题。ZooKeeper的树形数据存储结构主要由4种节点构成:

  • 持久节点。这是默认的节点类型,一直存在于ZooKeeper中。
  • 持久顺序节点。也就是说,在创建节点时,ZooKeeper根据节点创建的时间顺序对节点 进行编号。
  • 临时节点。与持久节点不同,当客户端与ZooKeeper断开连接后,该进程创建的临时节 点就会被删除。
  • 临时顺序节点,就是按时间顺序编号的临时节点。

根据它们的特征,ZooKeeper基于临时顺序节点实现了分布锁。还是以电商售卖吹风机的场景为例。假设用户A、B、C同时在1111日的零点整提交 了购买吹风机的请求,ZooKeeper会采用如下方法来实现分布式锁:

  • 在与该方法对应的持久节点shared_lock的目录下,为每个进程创建一个临时顺序节 点。如下图所示,吹风机就是一个拥有shared_lock的目录,当有人买吹风机时,会为 他创建一个临时顺序节点。
  • 每个进程获取shared_lock目录下的所有临时节点列表,注册子节点变更的Watcher,并监听节点。
  • 每个节点确定自己的编号是否是shared_lock下所有子节点中最小的,若最小,则获得 锁。例如,用户A的订单最先到服务器,因此创建了编号为1的临时顺序节点LockNode1。该节点的编号是持久节点目录下最小的,因此获取到分布式锁,可以访 问临界资源,从而可以购买吹风机。
  • 若本进程对应的临时节点编号不是最小的,则分为两种情况:a.本进程为读请求,如果比自己序号小的节点中有写请求,则等待; b.本进程为写请求,如果比自己序号小的节点中有读请求,则等待。

例如,用户B也想要买吹风机,但在他之前,用户C想看看吹风机的库存量。因此,用户B只能等用户A买完吹风机、用户C查询完库存量后,才能购买吹风机。