Storm的自适应动态流控制算法

  • 前言

业务的日志ETL拉取框架一直存在很多问题,每次出现故障就导致手忙大乱,因此这次决心要对其进行大改造。这个ETL系统是基于Storm实现的,主要是依靠Spout拉取原始日志,Bolt进行处理再入库,为了提高吞吐量,采用了12个Bolt进行并行处理。旧算法由于没有使用Storm的ack特性,而且还是根据发送Tuple的hash值发送到对应的Bolt中,完全没有考虑好负载均衡问题,在崩溃重启后也需要重新处理当天日志,可用性极低。

  • 新的想法

为了能够达到bolt的负载平衡,想到了采用动态平衡的算法去适应,另外也需要提供一个可靠的checkpoint机制,能够使崩溃重启后从当前时间点继续处理。

这个动态平衡的算法,可以参考TCP的流控制算法。TCP是可靠报文传输协议,具有可靠性,高效性,能够避免网络拥堵等特点。这里列出几个主要的TCP流控制算法的特点:

  1. TCP把多个发送信息的字节组合成一个数据报,提高发送效率
  2. TCP采用超时重发机制,并且按照超时时间按照优先级进行排列发送。
  3. 接收端收到数据报后发送ack到对应的发送端,这里是cumulative ack算法,也就是如果依次接收到数据报2,3,则发送两个ack,ack的是数据报1。
  4. 发送端有发送窗口,接收端也有接收窗口的概念,发送窗口表示发送端可以发送的数据报数量,接收窗口可以理解为接收端的接收数据报的缓存队列,一般情况下两个窗口大小相同。
  5. 接收端可以根据自己的处理速度发送接收窗口的大小给发送端,发送端根据需要调整发送窗口大小,避免发送速度超过处理速度。
  6. 除了5中根据发送端反馈的窗口大小外,发送端也会根据网络拥堵情况,动态调整发送窗口大小。(TCP Congestion Handling and Congestion Avoidance Algorithms)

当然TCP远远不止以上6点的特点,这里只列出部分的对于新算法有参考性的特点。具体可以参考这里以及IETF的标准规范rfc2001

  • 具体算法

由于ETL系统是依赖Storm进行开发,因此有一定的限制。不过可以根据Storm的特性类比TCP算法。Spout,也就是发送端,每个发送单元被称为Tuple,可以类比为TCP的数据报。Bolt接收端收到Tuple后,根据需要ack或者fail掉这个tuple,然后Spout会重发fail的tuple,同样地,Storm内部会探测到超时没响应的Tuple,然后发送fail到Spout。

虽然Storm拥有这些发送特性,但Storm除了ack和fail以外,没办法发送更多的反馈信息到Spout处,特别是Bolt的接收窗口大小(也就是缓存队列剩下的容量),这样Spout就没法根据Bolt进行发送窗口调整。另外Bolt每次也只能够ack或者fail对应的Tuple,不能使用cumulative ack算法。另外Spout和Bolt的关系,目前是一对多,也就是一个发送端发送到多个接收端进行并行处理,因此负载平衡显得尤为重要。

对于这个新算法,希望达到的目标是高吞吐量,高可用性以及简单性。高吞吐量是指多个Bolt的并发处理量,为了提高吞吐量,关键是实现动态的负载平衡。对于每个Bolt,发送窗口越大并不一定是越好,因为即使发送过去,Bolt也未必能够马上处理,相反,应该是把更多的Tuple发送到处理更快的Bolt上去,因此最恰当的做法是根据Bolt的处理速度,也就是ack的往返时间来衡量发送窗口大小。对于高可用性,要达到joiner崩溃后,重新启动后能够崩溃前的处理点重新处理,这就需要一种类似checkpoint的机制。要达到这个要求,并且保证简单性,可以通过保存已经ack的rt值。但由于Bolt只能够做到ack或者fail接收到的tuple,因此必须在Spout端统计采用累计的算法统计rt值,也就是如果ack了1,3,4的Tuple,只能记录第1个tuple的rt值,如果再收到ack
2的tuple,才记录第4个Tuple的rt值。简单性是为了避免算法和实际业务的代码的耦合,可以采用类似消费——生产者模式。

在rfc2001规范中,指出的TCP的拥塞处理和避免算法采用的是一种启发式的动态流控制算法。由于网络拥堵没办法可以使用数字精确测定,但可以简单地根据接收端的ack情况和丢包情况进行判断拥堵情况,然后线性或者指数式增加/减小发送窗口大小,从而避免增加网络拥堵压力。基于此算法,结合joiner的目标,可以延伸出一种类似的自适应动态流控制算法:

  • Spout把多条数据库记录组合成一个Tuple进行发送,这样可以减轻ack/fail时的压力,提高发送效率
  • Spout针对不同的Bolt拥有不同的发送窗口,每个发送窗口都会根据情况动态地增加或减小,并且都会记录Tuple的发送时间
  • Spout收到Bolt的ack时,根据之前记录的发送时间计算处理时间值,如果处于正常范围,则为NORMAL状态,线性增加发送窗口大小,如果超出阈值,则转为SLOW状态,线性减小发送窗口大小,另外Spout通过累积的ack计算出需要记录的tuple的rt值。
  • 当Spout收到fail,也就是Storm判断Tuple处理时间超时(目前不允许Bolt主动发送fail),则转为BUSY状态,马上减小1个发送窗口大小,并把Tuple重新放回发送缓冲区,等待发送到下一个Bolt,减轻当前BUSY的Bolt的压力。

这个新算法相比较TCP的拥堵控制算法,减小了一些特性,如Slow Start、Fast Retransmit等,有些是由于没有必要(Slow Start是避免一开始就遇到拥堵,但Bolt的初始化状态肯定为空闲),有些则是为了适用多个接收端的情况,(和Fast Retransmit相比较起来,发送给下一个空闲的Bolt更有优势),另外,新算法没有了ssthresh,慢开始阈值,用以区分指数增加发送窗口和线性增加发送窗口的阈值,因为指数增加发送窗口的时候很容易造成SLOW状态,另外盲目地增加发送窗口大小也并不能提高吞吐量,因此只选择线性增加。还有的就是Bolt并没有强调Tuple的处理顺序性,也就是只要收到ack,对应的Tuple就从发送窗口移出,就可以发送一个新的Tuple,这和TCP的发送窗口的必须等待处理完毕才能右移有区别。

  • 实现

整个实现的类图如下:

FlowProducer是由业务实现的流生产者,主要是实现数据流的生成,FlowControlSpout实现了Storm的Spout的逻辑,需要将Storm的发送Tuple和Ack/Fail Tuple的消息传递给AdapativeFlowConsumer,另外还充当缓冲队列,主要缓冲FlowProducer一次产生的数据流等待AdapativeFlowConsumer消费。AdapativeFlowConsumer是实现了自适应动态流控制算法的消费者,每个AdapativeFlowConsumer对应一个Bolt,自身维护了对应的发送窗口大小,以及重发等机制。FlowControlBolt实现了Storm的Bolt的逻辑,主要负责对处理过的Tuple进行ack(目前不支持处理失败发送Fail)。

  • 总结

新算法对比旧算法来看,有了更高的吞吐量以及可用性。具体的日志处理量都得到了提升。

尽管如此,实际上新算法还有一定的提升地步,就是更精确的负载平衡控制。目前在发送Tuple的时候,新算法是按照round robin算法逐个请求AdapativeFlowConsumer发送Tuple的,但事实上,应该计算出最空闲的Bolt,按照优先级进行发送,这就需要一个衡量空闲度的方法,但设计算法的时候考虑到流的生成是不间断的,而且这个衡量空闲度的算法暂时没想到简单的,因此就暂时不考虑。或许将来有需要的时候可以添加。

时间: 2024-10-04 15:46:42

Storm的自适应动态流控制算法的相关文章

基于自适应蚁群算法的无人飞行器航迹规划

为求解无人飞行器航迹规划问题,提出自适应蚁群算法,区别于标准蚁群算法的全部搜索模式,该算法采用局部搜索模式.首先根据起始节点与目标节点的相对位置 关系选择相应的搜索模式,然后计算各个待选节点的转移概率,最后按照轮盘赌规则选择下一个节点.仿真结果表明,自适应蚁群算法具有搜寻节点数少.速度快等 优点,在降低了航迹代价的同时,减小了计算时间.此外,自适应蚁群算法可以避免奇异航迹段的出现,从而保证所获的航迹实际可飞,表明所提算法整体性能明显 较标准蚁群算法优异. 此资料( 基于自适应蚁群算法的无人飞行器

ROS(14)----局部避障的动态窗口算法(DWA)

Dynamic Window Approach(DWA)是重要的局部轨迹规划算法,ROS中使用了DWA算法获得了很好的局部路径规划的效果.这里收集了些很不错的资料. 参考资料: [1]. 机器人局部避障的动态窗口法(dynamic window approach)(*****) [2]. Autonomous Robot Navigation [3]. Circular Motion in 2D for graphics and robotics [4]. A Tutorial and Elem

html div自适应动态上下左右居中

html 的body里只放一个div,其他的内容放在这个div里,设置div的样式如下:                   div {                             position:absolute;                             background:#404040;                             width:500px;                             height:400px;    

回声消除中的自适应算法发展历程

传统的IIR和FIR滤波器在处理输入信号的过程中滤波器的参数固定,当环境发生变化时,滤波器无法实现原先设定的目标.自适应滤波器能够根据自身的状态和环境变化调整滤波器的权重. 自适应滤波器理论 $x(n)$是输入信号,$y(n)$是输出信号,$d(n)$是期望信号或参考信号,$e(n)=d(n)-y(n)$为误差信号.根据自适应算法和误差信号$e(n)$调整滤波器系数. 自适应滤波器类型.可以分为两大类:非线性自适应滤波器.线性自适应滤波器.非线性自适应滤波器包括基于神经网络的自适应滤波器及Vol

基于请求的分布式互斥算法

一个悲剧的文章,研究的东西确实比较老,但是因为这些研究,让我对分布式的底层的关系有了更加清晰的认识,也算是不枉此功. 下面贴出来核心的部分. 引言 分布式系统中的一组进程可能会同时访问一个资源或者同时执行一个给定的函数,我们称这些资源或者函数为临界区(Critical Section),若不加控制的话,会造成资源或者环境的不一致的现象.保证任何给定时刻只允许一个进程或者给定的进程去执行临界区的算法称为互斥算法.互斥也可以称为并发控制. 这个问题最早由Dijkstra[1]在1965年提出.互斥可

【转】 运动目标检测跟踪主流算法

不全,需要慢慢补充 一.运动目标检测 (一)背景差 1.帧差 2.GMM 等 背景减算法可以对背景的光照变化.噪声干扰以及周期性运动等进行建模,在各种不同情况下它都可以准确地检测出运动目标.因此对于固定摄像头的情形,目前大多数的跟踪算法中都采用背景减算法来进行目标检测.背景减算法的局限性在于它需要一个静态的固定摄像头. (二)运动场 光流法 光流估计的方法都是基于以下假设:图像灰度分布的变化完全是目标或者场景的运动引起的,也就是说,目标与场景的灰度不随时间变化.这使得光流方法抗噪声能力较差,其应

【红外DDE算法】聊聊红外图像增强算法的历史进程(第一回)

宽动态红外图像增强算法综述回顾过去带你回顾宽动态红外图像增强算法的历史进程,历来学者的一步步革命(新的算法框架提出),一步步改革(改进优化),从简单粗暴到细致全面.正所谓是:改革没有完成时,只有进行时.没有完美的算法,也没有最好的算法,只有更好更优秀的算法.展望未来以现在看90年代的算法,那时候的算法是有点粗糙,但是正是在这一点点的积累上,才有了现在较之优秀完美的算法.正所谓是:站在巨人的肩膀,我们看得更远,不积跬步无以至千里. 目录 为什么需要该算法?摘要主要的三类算法思路大致介绍第一类:基于

SSL/TLS算法流程解析

SSL/TLS 早已不是陌生的词汇,然而其原理及细则却不是太容易记住.本文将试图通过一些简单图示呈现其流程原理,希望读者有所收获. 一.相关版本 Version Source Description   Browser Support SSL v2.0 Vendor Standard (from Netscape Corp.) [SSL2] First SSL protocol for which implementations exist - NS Navigator 1.x/2.x - MS

storm教程

二.安装部署 ? 一.storm伪分布式安装 (一)环境准备1.OS:debian 72.JDK 7.0 (二)安装zookeeper1.下载zookeeper并解压?wget http://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.4.6/zookeeper-3.4.6.tar.gz?tar -zxvf zookeeper-3.4.6.tar.gz2.准备配置文件cd confcp zoo_sample.cfg zoo.cfg?3.启动zoo