Curator在大数据集群可靠性中的应用以及改进

来源:互联网 发布:淘宝销售工资一般多少 编辑:程序博客网 时间:2024/06/07 19:20

Curator在大数据集群可靠性中的应用以及改进

Curator简介

大家都知道,ZooKeeper是当前大数据领域内常用的分布式协调组件。几乎在所有的大数据、分布式处理组件中都能见到它的应用。但由于ZooKeeper提供的原始API并不是很易用,在其基础上封装一些高级应用(服务发现、分布式锁、Master选举等)需要处理到很多细节,是一件很复杂的事情。

Curator在此场景下应运而生,由Netflix贡献到Apache社区,至今已经成了各大厂商使用ZooKeeper服务的标配第三方库。它提供了Framework模块对ZooKeeper客户端进行了高级封装,并且对外包装了连接状态的处理以及重试逻辑,另外提供了Recipes模块封装一些针对ZooKeeper应用场景开发出来的高级特性(Elections、Locks、Barriers、Counters等等)。这次我们要介绍的就是Recipes模块中的leader(Elections)子特性。

LeaderLatch与Master选举

LeaderLatch是Curator中Elections特性中的主要接口,它封装了一个CuratorFramework和一个用于选举的ZooKeeper ZNode路径。用于在多个实例中随机选取一个作为Master实例,其他作为Standby实例备用;当Master实例发生故障或者退服后,再选举其中一个Standby实例升主,继续对外提供不间断的服务。

LeaderLatch是怎么参与Maser选举的呢?流程是这样的:在启动时,在指定的latch path(由用户指定)下建立一个前缀为latch-的ZNode,Create Mode选定为EPHEMERAL_SEQUENTIAL,EPHEMERAL指创建的节点为临时节点,在session关闭后会被服务端删除,SEQUENTIAL意味着在同一个path下创建的节点是递增有序的。ZNode建立完毕后,会调用一个回调函数,在这个回调函数里处理Master竞选的逻辑。

其实竞选逻辑也很简单,每个实例都会在指定的latch path下创建一个latch-前缀的ZNode,而在服务端这些请求是被顺序处理的,且每个ZNode后缀是递增有序的。那么实例创建ZNode完成后,只需要将latch path下的所有ZNode取到,做一个排序,若本实例创建的ZNode在有序序列的第一个,则为leader;否则为standby实例,继续监控排在本实例ZNode之前的实例节点(此处很妙,监控前一个ZNode而不是leader ZNode,是为了防止羊群效应)。当监控的节点被删除时,重新触发竞选过程。

表示成图如下:

这里写图片描述

LeaderLatch对ZooKeeper connection的敏感度及优化

以上说的是正常情况下的选举逻辑,实际上LeaderLatch除了处理服务端ZNode节点的变化外,还要处理与ZooKeeper集群的连接状态。当连接状态发生变化时,LeaderLatch的竞选逻辑也要做相应的改变。

我们先从LeaderLatch的组成部分开始:

这里写图片描述

LeaderLatch中有一个listener,会在启动的时候加入到ConnStateManager的listner列表中,而CuratorFramework处理每次事件时,都会检查Event的状态,将ZooKeeper的状态转换为Curator内部状态码后,交由ConnStateManager处理,而ConnStateManager处理的最关键步骤就是作为总线将这些状态传递注册的listener。ZooKeeper连接状态到Curator内部状态码的对应关系如下:

KeeperException.Code Event.KeeperState conn state AUTHFAILED AuthFailed / NOAUTH AuthFailed / CONNECTIONLOSS Disconnected SUSPENDED OPERATIONTIMEOUT Disconnected SUSPENDED SESSIONEXPIRED Expired LOST OK SyncConnected RECONNECTED SESSIONMOVED SyncConnected RECONNECTED / ConnectedReadOnly READ_ONLY

而LeaderLatch中注册的listener是处理conn state的,处理的流程图如下:

这里写图片描述

可以看到,出现LOST或者SUSPENDED时,LeaderLatch都做降备处理,而对应的ZooKeeper状态确实Disconnected,这是一种很常见的状态。当ZooKeeper客户端和服务端暂时断开连接时,ZooKeeper客户端收到的状态就是Disconnected。

这样就意味着在网络情况较差,或者ZooKeeper集群中的实例发生故障时,一定会导致LeaderLatch降备行为的发生。我们知道在大规模集群下,网络情况偶尔闪断、集群节点下电、进程故障等情况发生的概率还是很大的。决不能容忍这些情况下LeaderLatch降备从而导致服务的主备切换,增加服务的不可用时间。

针对这种情况,我们做了如下优化:

这里写图片描述

即在发生SUSPENDED事件后,会在降备之前等待一个connection timeout的时间,如果在此时间内ZooKeeper客户端尝试重连集群成功,则忽略这次断连时间。否则按照之前的处理逻辑,降备处理。

通过增加这一个缓冲区域,我们有效的降低了LeaderLatch(以及依赖其提供HA的上层服务)的可用性,大大减少了服务发生主备切换的频率,效果提升明显。

声明:本文为原创,版权归本人所有,禁止用于任何商业目的,转载请注明出处:http://blog.csdn.net/asongoficeandfire/article/details/70667203

如果你觉得我文章写的不错,可以扫描支付宝二维码打赏我:)

img

0 0