【IT168 专稿】本文根据罗江宇老师在2018年5月12日【第九届中国数据库技术大会】现场演讲内容整理而成。
讲师简介:
罗江宇,滴滴出行资深研发工程师。浙江大学硕士,曾就职新浪微博,2016年加入滴滴出行,目前从事Flink业务支持,集群稳定性保障和研发工作。
摘要:
为了应对滴滴数据量爆炸性增长和对实时计算低延迟的高要求,滴滴引入Flink 实时计算框架,目前Flink Streaming已在滴滴的实时监控,实时BI,实时CEP ,和在线业务等领域有了广泛的应用。本次演讲主要介绍Flink Streaming在滴滴大规模生产的应用场景,以及分享生产中遇到的问题以及解决方法,从中获取的经验。
分享大纲:
1、Flink Streaming平台化
2、Flink Streaming在滴滴的实践
3、Flink Streaming展望与规划
正文:
1、Flink Streaming平台化
首先,我介绍一下滴滴引入Flink Streaming的背景,主要分为三部分:一是滴滴存在丰富的数据及应用场景,比如乘客、司机、交易以及轨迹数据等,在用户下单过程中也会产生很多日志数据;二是业务实时性要求越来越高;三是公司很多Storm或JStorm小集群需要及时升级整合。由于Flink Streaming原生兼容Storm和JStorm,因此转向Flink Streaming的成本相对来说比较低。
作为滴滴大数据架构部,我们改造的主要目的,一是希望降低使用Flink Streaming服务的门槛,二是整合公司内的小集群,降低运维成本,提升机器利用率;三是提升服务的稳定性与问题定位的效率。
上图为滴滴实时计算平台整体架构,底层存储使用HDFS、ES以及Druid,再上一层是Yarn调度层,再向上是目前滴滴正在使用的计算引擎——Flink Streaming和Spark Straeming, 最上层主要包括应用管控、WeblDE,SQL(建设中)以及诊断系统。
在Yarn计算资源管理部分,我们主要分为两大类,一类是稳定性要求较高的业务独占机器(基于Label机制);二是普通业务混布机器(基于CGroup机制)。如上图下方所示,Label一般基于业务,每个业务分成一个Label,稳定性要求较高的业务使用队列绑定Label,普通业务基本就是No-Label, 运行在混布环境。
为了支持平台化Flink Streaming改造,我们做得第一件事是支持HDFS应用资源,主要因为flink提交应用不支持HDFS;二是限制JobManager至多运行一个应用;三是基于应用DAG情况进行计算资源申请;四是支持计算资源的动态缩扩。下面重点介绍下基于计算资源的动态缩扩。
上图是计算资源扩容示例图,比如我现在需要进行应用升级,原来的50个并行度变为100个并行度,我并不是先把申请的50个资源全部回收,再重新申请100个,而是直接在50个的基础上追加。首先由应用管控部分提交应用到JobManager,JobManager计算应用所需资源后进行缩扩check,如果需要扩容,JobManager会先向Yarn RM申请,Yarn RM再向Hadoop Yarn申请扩容资源。会新增相应的TaskManager,这个过程还会涉及到调整networkbuffer。
缩容示意图如上所示,同样是由应用管控提交应用,计算所需资源之后进行缩扩check,JobManager主动check进行realease一些TM。在缩扩容的过程中,最重要的两件事情就是计算所需资源和保持该资源。
接下来讲讲Flink流式任务开发与管控,Flink流式任务开发主要有三种方式,一是通过Web IDE,二是通过Streaming SOL(建设中),三是线下开发。流式任务管控就是管控web化,不需要客户机,并且简化提交应用的参数配置。
流式任务开发及管控整体流程如上所示,Web IDE、SQL以及线下开发接入应用管控平台,整体再接入诊断系统,诊断系统主要用于分析调优。
上述为Web IDE界面,我们会在Web IDE上提供一些基本模板,可以多位用户协同开发。在Web管控提交页面,我们会列出集群、所属项目、公共用户、任务名称、任务类别、主程序等信息,用户基本不需要配置太多信息。
Flink流式任务诊断体系如下图所示,主要分为两部分:Flink日志和流式指标。
日志部分实时接入ES,我们可以通过Kibana和ES SQL查询。由于ES层的数据只能保留有限的时间,如果用户需要保持较长时间的数据进行分析,我们会考虑将日志接入HDFS,然后通过Hive和UI查看。流式指标直接接入Druid,然后通过监控大盘查看流量和延迟,以及其他指标。
2、Flink Streaming在滴滴的实践
Flink Streaming在滴滴的主要应用场景有四个:实时ETL、实时报表、实时监控和实时业务。接下来,我先分享一下实时网关日志监控,一是主要支持select、groupby、filter和一定时间范围内的window计算规则;二是支持计算规则的动态更新;三是基本覆盖整个公司的网关日志;四是数据量高峰期可达到每秒300万以上;五是通过网关日志监控提升线上业务排查问题效率。
以上是实时网关日志监控整体图,日志Agent采集数据到Kafka,Flink Streaming会定时从计算规则元数据管理中心拉取元数据,Metric上报可进行自监控,最终结果输入ES,业务方通过查询ES进行DashBoard展示和告警; Flink Streaming计算应用的metric 上报到监控平台,提供对监控计算应用的监控。
以上是实时网关日志监控规则,基本涵盖groupby、select等指标。在这个过程中,我们遇到的问题大概可分为以下五类:一是数据量暴涨,计算资源不够,这种情况常见于节假日前夕,提供兜底的方案是基于计算规则的降级方案。
二是机房网络可能存在故障,在我们实际生产中有两个机房,为了防止因机房故障导致服务不可用,我们做了异地多活。
三是聚合结果明显不正确,造成这种现象的原因可能是数据跨度较大,延迟数据较多,进而造成数据聚合结果不正确,我们的解决方案是构建延迟数据监控。
四是其他异常处理,主要包括Checkpoint异常和Kafka 异常,针对监控对时间延迟要求高,对延迟一定时间的数据没有意义的情况,对checkpoint异常的处理策略进行优化和监控;而Kafka 的异常,主要发生在kafka的发送的时候,由于kafka集群升级或者网络抖动,导致kafka 发送失败的情况,针对kafka 发送失败的情况,提供合理的retries 和在最大retries 失败后的skip策略。
在实时规则引擎部分,其支持DSL和CEP代码规则,支持CEP规则动态更新,目前已上线的应用场景是实时运营,实时发放券和实时风控,并且由原来天级别的处理时间提升为实时处理。
实时规则引擎整体架构如上图所示,从MQ和Kafka接入数据清洗,我们做了CEP规则元数据管理中心,提供动态CEP算子,通过Groovy方式解析规则并生成NFA,然后进行数据处理,这匹配过程中可能需要依赖外部特征数据查询,最后匹配结果输出到Kafka,下游根据发送到Kafka的匹配结果进行进一步处理。
实时规则描述部分从上至下依次为规则、序列算子、condition描述和输出算子。在序列算子层加入了wait和abortwith算子,condition描述就是代码级别,此处主要是SQL。假如,beginwith是yes,followba是yes,wait是yes,abortwith是no,则最后输出算子。
实时规则引擎遇到的问题主要有以下四类:
1. pattern无法动态加载,每次更新需要重启应用。解决方案是采用groovy动态语言,改造cep operator动态加载update NFA生效。
2. sharedBuffer的性能问题,每次元素到来会需要将之前匹配到的中间元素都rocksdb中获取出来导致性能很差,基于社区的优化patch,在中间加了一些缓存优化很好的满足了业务需求。
3. cep的原本实现条件表达复杂,需要写很多内部类利用aviator的表达式解析引擎,和json表达很好的简化了数据匹配条件的描述。
4. cep本身无法表达notFollowedBy结尾类型的条件,而业务中确有很多类似的需求,通过开发类似wait语义的算子将满足了类似 begin().notFollowedBy().wait()这种业务需求的表达 。
3、Flink Streaming展望与规划
根据滴滴的应用情况,我们总共提出了五点规划:一是完善动态CEP,接下来会将考虑动态CEP与风控相结合,提升风控的实时性;二是构建Streaming SQL平台,进一步降低使用门槛与开发成本;三是支持Flink Streaming任务平滑升级,主要满足稳定性要求极高的应用的升级;四是支持流与维表Join和双流Join(不借助外部存储) ;五是拓宽Flink Streaming应用场景,未来可能会考虑向机器学习和IOT等方向拓展。