天天看点

性能、稳定性、反压、Exactly Once,Jstorm开源最佳实践全解析发展历史使用场景架构JStorm增强JStorm Future

在2017年在线技术峰会——阿里开源项目最佳实践上,来自阿里巴巴中间件的技术专家卫乐分享了jstorm开源最佳实践。他主要介绍了jstorm的架构,从性能、稳定性、监控系统、大规模部署、反压、灰度发布&热升级、exactly-once、新的窗口机制等方面详细扥想了jstorm做的优化。以下内容根据直播视频整理而成。

<b></b>

性能、稳定性、反压、Exactly Once,Jstorm开源最佳实践全解析发展历史使用场景架构JStorm增强JStorm Future

jstorm从2013年开始开发,历经了25个版本。从2014年“双十一”开始,做了管控平台,包括调度、用户自定义日志等特征。2015年的“双十一”,对调度进行了优化,并且增加了反压功能,重新设计了topology master。2016年,除了性能优化之外,还提供了exactly once,包括把社区的sliding window和shade dependency等特性都移植到jstorm,此外还提供了很多新的feature,如重构的窗口机制,灰度发布等。

jstorm在阿里集团、蚂蚁、优酷、土豆、高德都使用非常广泛。有三种部署方式:standalone、jstorm-on-yarn、jstorm-on-docker(主推,可以一键部署,扩容缩容方便)。

jstorm已经不是简单的实时计算了,其应用在很多场景:

反欺诈:nut/velocity;

审计:阿里妈妈广告/p4p,amg;

数据统计分析:eagleeye,ae,bi;

监控:tlog(阿里内部监控),rds-monitor(sql监控),oceanbase-monitor(sql监控), cainiao radar, yunosmonitor;

数据同步:rds-log-sync, unify-log;

实时推荐:alipay 1315, alipay hyperloop, tpp;

应用调度:ae邮件实时分析,网销宝。

性能、稳定性、反压、Exactly Once,Jstorm开源最佳实践全解析发展历史使用场景架构JStorm增强JStorm Future

jstorm的整体架构如上图所示。最下方是部署模式,jstorm core是jstorm计算框架本身,其上是raw storm api(此接口相对底层)、exactly once、extension api。其上是集团内部广泛使用的plugin,sql engine上是应用。最右边是管控平台koala。

性能、稳定性、反压、Exactly Once,Jstorm开源最佳实践全解析发展历史使用场景架构JStorm增强JStorm Future

上图是去年jstorm 2.2.0和storm 1.0.2的性能对比图。硬件是32cpu core/128g物理机,每个worker是6g内存。从图中可以看到在不同的worker已经不同的并发下,jstorm至少是storm两倍以上的性能。那么,如何进行的性能优化?

性能、稳定性、反压、Exactly Once,Jstorm开源最佳实践全解析发展历史使用场景架构JStorm增强JStorm Future

性能优化在现代的流处理领域广泛认可的一种方式是做batch,batch对性能优化的影响是非常大的。batch是将消息打包,从上游接收一些消息,处理完后进行batch再往下发,能够节省很多资源,提高性能。在此基础上进行了路径优化,即对jstorm做了jvm层面的profile,检测框架的hot function部分(调用比较多的部分),进行针对性优化。虽然对jstorm进行了重构metrics体系,但是底层的metrics core库并没有优化,所以对meter,histogram等进行了优化。此外,在序列化方面,对常用的序列化都进行了调优。

性能、稳定性、反压、Exactly Once,Jstorm开源最佳实践全解析发展历史使用场景架构JStorm增强JStorm Future

在稳定性方面,做了以下优化:

多集群部署方面,由于涉及到异地多机房、同城多机房等问题,所以同城方面使用了zk做多机房的容灾,jstorm自动把这些作业调到别的机房,只要保证别的机房的worker量可以支撑作业量就不会出现问题。跨城情况相对复杂,成本也比较高,在阿里使用多链路来解决,即在多城市部署一模一样的集群消费同一份数据,在输出上做一些灾备,输出到不同的异构数据输出中,这样任意一条链路挂掉就能实时切换。

隔离方面,standalone提供了天然的隔离性,因为docker本身用cgroup做资源隔离,所以jstorm-on-docker的隔离也相对简单。jstorm-on-yarn是在yarn上的container中开启cgroup来做隔离。

ha方面,jstorm的ha是很早的特性,非常稳定。节点自检是checkhealth,用于检查supervsior。脚本会在supervsior压力过大或者内存快满的情况下自动调整可用worker数(降低)。

监控方面,jstorm的自定义metrics重新实现,管控平台koala集成了监控报警。tuple life style能够根据节点间花费的时间得知拓扑结构中比较慢的环节。

升级/降级方面,降级即jstorm的反压,升级即热部署和灰度发布。

性能、稳定性、反压、Exactly Once,Jstorm开源最佳实践全解析发展历史使用场景架构JStorm增强JStorm Future

jstorm的监控系统如上图所示,重新设计的监控系统的优点在于自动聚合的功能。从下往上,一个task有多个stream,task往上是component,再往上是topology,再往上是cluster。重新设计后的优点在于可以统计所有级别的metrics,展现完整的历史曲线,而不是单点的数据。

性能、稳定性、反压、Exactly Once,Jstorm开源最佳实践全解析发展历史使用场景架构JStorm增强JStorm Future

上图是metrics整个分级汇总的实现。具体可见github源码中最新的metrics设计文档。

性能、稳定性、反压、Exactly Once,Jstorm开源最佳实践全解析发展历史使用场景架构JStorm增强JStorm Future

在没有topology master的情况下,所有的task汇报心跳、发送metrics的时候都需要写zk,并且storm是把metrics直接zk里面,这样zk的压力更大。有了topology master之后,topology master是task的总节点,task汇报心跳的时候只需要向task汇报心跳,topology master汇总后再发送给nimbus或者zk,这样会使zk的压力缩到拓扑的量级。

storm的反压,比如bolt处理消息来不及的情况下会向zk写一个节点进行反压,监听bolt上游的节点停止发送数据直到下游的bolt能够正常处理。这样的问题是数据可能出现骤降的过程,并且反压结束数据流下来之后容易导致新一次的反压,从而导致tps会一直抖动。

性能、稳定性、反压、Exactly Once,Jstorm开源最佳实践全解析发展历史使用场景架构JStorm增强JStorm Future

jstorm做了两级的反压,第一级和jstorm类似,通过执行队列来监测,但是不会通过zk来协调,而是通过topology master来协调。在队列中会标记high water mark和low water mark,当执行队列超过high water mark时,就认为bolt来不及处理,则向tm发一条控制消息,上游开始减慢发送速率,直到下游低于low water mark时解除反压。此外,在netty层也做了一级反压,由于每个worker task都有自己的发送和接收的缓冲区,可以对缓冲区设定限额、控制大小,如果spout数据量特别大,缓冲区填满会导致下游bolt的接收缓冲区填满,造成了反压。

性能、稳定性、反压、Exactly Once,Jstorm开源最佳实践全解析发展历史使用场景架构JStorm增强JStorm Future

一个规模很大的拓扑,以前的升级需要先把拓扑kill掉,修改代码、重新打包、重新提交,导致应用会有短暂的时间不能使用。此外,有时候只想升级部分的worker,不想重启整个拓扑。灰度发布和热升级是做worker内部的重启,但是不会kil拓扑。

性能、稳定性、反压、Exactly Once,Jstorm开源最佳实践全解析发展历史使用场景架构JStorm增强JStorm Future

在jstorm中,exactly-once是通过topology master来做协调的。jstorm中的exactly-once并不像以前那样每发一条消息一次。spout发一个batch,会有一个batch id,并且立马发一个checkpoint barrier(控制消息),tm会得知发了一条新的batch,tm会把offset记录下来。bolt分为两种,一种是stateless bolt,一种是stateful bolt。stateless bolt比较简单,就是正常处理,继续往下游bolt发。stateful bolt则需要把状态存起来,把checkpoint发送给topology master,直到ending bolt向tm发送checkpoint barrier。当所有的ending bolt都做完checkpoint后,就会将状态存在hdfs/hbase中,再通知spout发送下一个batch。

性能、稳定性、反压、Exactly Once,Jstorm开源最佳实践全解析发展历史使用场景架构JStorm增强JStorm Future

实际上,每一个batch的处理和发送是可以并行的,只是tm本身的checkpoint是串行的,这样就可以很好的提高性能。比如中间有一个batch处理失败了,tm会得知,此时就会做rollback,向spout发送rollback barrier,从hdfs/hbase中找出最近完成的checkpoint,删除历史无用的checkpoint,spout会从状态中重新恢复offset,stateless bolt会继续处理,stateful bolt会把checkpoint所对应的状态从hdfs/hbase中拉出来恢复,再根据数据计算。

其他的特性包括自定义调度、动态调整日志级别、自定义日志(外部应用可以很方便做日志采集、基于日志的监控报警)、用户自定义metrics(根据业务日志做监控报警)、优雅shutdown(把所有的消息处理完之后再shutdown)、动态扩容、更新配置。

storm的window有很多问题,所有的数据需要统一处理,在工业级的产品中不可行。重构的窗口机制不会在内存憋每个窗口的数据,只需要存每个窗口的处理结果。重构的窗口机制,支持processing time、ingestion time、event time、watermark (late element)、window early fire。

apache beam提供了一次编写、多个不同引擎到处运行的特性。jstorm也会适配beam,做apache beam jstorm runner。jstorm sql需要进行重构和优化。将来计划在jstorm上封装一些算子、整合框架,使其易于开发、调试,性能更加优化。

继续阅读