赞
踩
举一个很简单的例子,当你往一群鸽子中间扔一块食物,虽然最终只有一个鸽子抢到食物,但所有鸽子都会被惊动来争夺,没有抢到食物的鸽子只好等待下一块食物到来。这样,每扔一块食物,都会惊动所有的鸽子,即为惊群。对于操作系统来说,多个进程/线程在等待同一资源是,也会产生类似的效果,其结果就是每当资源可用,所有的进程/线程都来竞争资源。
ZooKeeper 的节点通常可以作为分布式锁来使用。比如可以多个服务对同时竞争申请一个节点 “/zk/lock”,创建成功的服务获取到这个锁,其他没创建成功的监听这个锁,等到这个锁释放后再重新申请该锁。这样就实现了简单的分布式锁。
但同时在大量锁的情况下会有**“惊群”**的问题。“惊群”就是在一个节点删除的时候,大量对这个节点的删除动作有订阅Watcher的线程会进行回调,这对Zk集群是十分不利的。所以需要避免这种现象的发生。
为了解决“惊群“问题,我们需要放弃订阅一个节点的策略,那么怎么做呢?
Watcher
是一次性操作,这意味着它只触发一个通知。要继续接收通知,客户必须在收到每个事件通知后重新注册一个监视。
脑裂 (split-brain),就是“大脑分裂”,也就是本来一个“大脑”被拆分了两个或多个“大脑”。这种现象经常出现于集群情况。
对于一个集群,想要提高这个集群的可用性,通常会采用多机房部署,比如现在有一个由6台 zkServer 所组成的一个集群,部署在了两个机房。正常情况下,此集群只会有一个 Leader。那么如果机房之间的网络断了之后,两个机房内的 zkServer 还是可以相互通信的,如果不考虑过半机制,那么就会出现每个机房内部都将选出一个 Leader,如下图所示:
Zookeeper 选举时,必须接收到超过一半节点选择同样的节点,超过一半节点意味着不能等于一半节点。这里的原因用上面的问题可以很好的解释:
假设允许等于一半节点,那么假设两个机房都是三台服务器,中间两个机房的网络连接断了,那么两个机房内部选举,都会选出分别的Leader,即出现了脑裂现象。
但是如果只允许大于一半节点,不允许等于,那么上面的情况,两边机房都不会选出新的 Leader。如果两个机房分别是3台,2台节点,那么机房一所有节点的投票最终会相同,投票数量为3,大于总服务器的一半,所以新的Leader节点只可能出现在机房一中。
怎么避免脑裂?实际上 Zookeeper 集群中是不会出现脑裂问题的,而不会出现的原因就跟过半机制有关。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。