为什么Zookeeper天生就是一副分布式锁的胚子?
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end"; Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId)); if (result.equals(1L)) { return true; } return false; } Zookeeper 的漫衍式锁 Zookeeper 漫衍式锁实现道理 领略了锁的道理后,就会发明,Zookeeper 生成就是一副漫衍式锁的胚子。 起首,Zookeeper 的每一个节点,都是一个自然的次序发号器。 在每一个节点下面建设子节点时,只要选择的建设范例是有序(EPHEMERAL_SEQUENTIAL 姑且有序可能 PERSISTENT_SEQUENTIAL 永世有序)范例,那么,新的子节点后头,会加上一个序次编号。 这个序次编号,是上一个天生的序次编号加 1,好比,建设一个用于发号的节点“/test/lock”,然后以他为父亲节点,在这个父节点下面建设沟通前缀的子节点。 假定沟通的前缀为“/test/lock/seq-”,在建设子节点时,同时指明是有序范例。 假如是第一个建设的子节点,那么天生的子节点为 /test/lock/seq-0000000000,下一个节点则为 /test/lock/seq-0000000001,依次类推,等等。 其次,Zookeeper 节点的递增性,可以划定节点编号最小的谁人得到锁。 一个 Zookeeper 漫衍式锁,起首必要建设一个父节点,只管是耐久节点(PERSISTENT 范例),然后每个要得到锁的线程城市在这个节点下建设个姑且次序节点,因为序号的递增性,可以划定排号最小的谁人得到锁。 以是,每个线程在实行占用锁之前,起首判定本身是排号是不是当前最小,假如是,则获取锁。 第三,Zookeeper 的节点监听机制,可以保障占据锁的方法有序并且高效。 每个线程抢占锁之前,先抢号建设本身的 ZNode。同样,开释锁的时辰,就必要删除抢号的 Znode。 抢号乐成后,假如不是排号最小的节点,就处于守候关照的状态。等谁的关照呢?不必要其他人,只必要等前一个 Znode 的关照就可以了。 当前一个 Znode 删除的时辰,就是轮到了本身占据锁的时辰。第一个关照第二个、第二个关照第三个,伐鼓传花似的依次向后。 Zookeeper 的节点监听机制,可以说可以或许很是美满的,实现这种伐鼓传花似的信息转达。 详细的要领是,每一个等关照的 Znode 节点,只必要监听 linsten 可能 watch 监督排号在本身前面谁人,并且紧挨在本身前面的谁人节点。 只要上一个节点被删除了,就举办再一次判定,看看本身是不是序号最小的谁人节点,假如是,则得到锁。 为什么说 Zookeeper 的节点监听机制,可以说长短常美满呢? 一条龙式的首尾相接,后头监督前面,就不怕中间截断吗?好比,在漫衍式情形下,因为收集的缘故起因,可能处事器挂了可能其他的缘故起因,假如前面的谁人节点没能被措施删除乐成,后头的节点不就永久守候么? 着实,Zookeeper 的内部机制,能担保后头的节点可以或许正常的监听到删除和得到锁。 在建设取号节点的时辰,只管建设姑且 Znode 节点而不是永世 Znode 节点。 一旦这个 Znode 的客户端与 Zookeeper 集群处事器失去接洽,这个姑且 Znode 也将自动删除。排在它后头的谁人节点,也能收到删除变乱,从而得到锁。 说 Zookeeper 的节点监听机制,长短常美满的。尚有一个缘故起因。Zookeeper 这种首尾相接,后头监听前面的方法,可以停止羊群效应。 所谓羊群效应就是每个节点挂掉,全部节点都去监听,然后做出反应,这样会给处事器带来庞大压力,以是有了姑且次序节点,当一个节点挂掉,只有它后头的那一个节点才做出反应。 Zookeeper 漫衍式锁实现示例 Zookeeper 是通过姑且节点来实现漫衍式锁: terruptedException e) { e.printStackTrace(); } System.out.println("*********营业要领竣事************n");
}
// 这里行使@Test会报错 public static void main(String[] args) { // 界说重试的侧计策 1000 守候的时刻(毫秒) 10 重试的次数 RetryPolicy policy = new ExponentialBackoffRetry(1000, 10);
// 界说zookeeper的客户端 CuratorFramework client = CuratorFrameworkFactory.builder() (编辑:湖南网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |