请求|阿里面试官:分布式锁到底用Redis好?还是Zookeeper好?( 三 )


在ZooKeeper所有的节点,也就是文件夹称作 Znode,而且这个Znode节点是可以存储数据的。
我们可以通过“ create /zkjjj nice” 来创建一个节点,这个命令就表示,在跟目录下创建一个zkjjj的节点,值是nice。同样这里的值,和我在前面说的redis中的一样,没什么意义,你随便给。
另外ZooKeeper可以创建4种类型的节点,分别是:
1,持久性节点
2,持久性顺序节点
3,临时性节点
4,临时性顺序节点
首先说下持久性节点和临时性节点的区别,持久性节点表示只要你创建了这个节点,那不管你ZooKeeper的客户端是否断开连接,ZooKeeper的服务端都会记录这个节点。
临时性节点刚好相反,一旦你ZooKeeper客户端断开了连接,那ZooKeeper服务端就不再保存这个节点。
再说下顺序性节点,顺序性节点是指,在创建节点的时候,ZooKeeper会自动给节点编号比如0000001 ,0000002 这种的。
最后说下,zookeeper有一个监听机制,客户端注册监听它关心的目录节点,当目录节点发生变化(数据改变、被删除、子目录节点增加删除)等,zookeeper会通知客户端。
下面我们继续结合我们上面的分红包场景,描述下在zookeeper中如何加锁。
假设服务器1,创建了一个节点 /zkjjj ,成功了,那服务器1就获取了锁,服务器2再去创建相同的锁,那么他就会失败,这个时候他就就只能监听这个节点的变化。
等到服务器1,处理完业务,删除了节点后,他就会得到通知,然后去创建同样的节点,获取锁处理业务,再删除节点,后续的100台服务器与之类似
注意这里的100台服务器并不是挨个去执行上面的创建节点的操作,而是并发的,当服务器1创建成功,那么剩下的99个就都会注册监听这个节点,等通知,以此类推。
但是大家有没有注意到,这里还是有问题的,还是会有死锁的情况存在,对不对?
当服务器1创建了节点后挂了,没能删除,那其他99台服务器就会一直等通知,那就完蛋了。。。
这个时候呢,就需要用到临时性节点了,我们前面说过了,临时性节点的特点是客户端一旦断开,就会丢失,也就是当服务器1创建了节点后,如果挂了。
那这个节点会自动被删除,这样后续的其他服务器,就可以继续去创建节点,获取锁了。
但是我们可能还需要注意到一点,就是惊群效应:举一个很简单的例子,当你往一群鸽子中间扔一块食物,虽然最终只有一个鸽子抢到食物,但所有鸽子都会被惊动来争夺,没有抢到..
就是当服务器1节点有变化,会通知其余的99个服务器,但是最终只有1个服务器会创建成功,这样98还是需要等待监听,那么为了处理这种情况,就需要用到临时顺序性节点
大致意思就是,之前是所有99个服务器都监听一个节点,现在就是每一个服务器监听自己前面的一个节点。
假设100个服务器同时发来请求,这个时候会在 /zkjjj 节点下创建 100 个临时顺序性节点 /zkjjj/000000001,/zkjjj/000000002,一直到/zkjjj/000000100,这个编号就等于是已经给他们设置了获取锁的先后顺序了。
当001节点处理完毕,删除节点后,002收到通知,去获取锁,开始执行,执行完毕,删除节点,通知003~以此类推。
热门推荐:
微信昵称新玩法,速来~
我写了一个“打飞机”的小游戏(附源码),网友直呼:屌爆了~
马保国一年能挣多少钱?
不开心就点点在看
开心也要点点在看