Apache Flink在滴滴的应用与实践
扫描二维码
随时随地手机看文章
分享嘉宾:梁李印 滴滴出行 高级技术专家
出品平台:DataFunTalk
导读:Apache Flink 是一个分布式大数据处理引擎,可对有限数据流和无限数据流进行有状态计算。可部署在各种集群环境,对各种大小的数据规模进行快速计算。
滴滴基于 Apache Flink 做了大量的优化,也增加了更多的功能,比如扩展 DDL、内置消息格式解析、扩展 UDX 等,使得 Flink 能够在滴滴的业务场景中发挥更大的作用。本文中,滴滴出行实时计算负责人、高级技术专家梁李印分享了 Apache Flink 在滴滴的应用与实践。
主要内容包括:
-
服务化概述
-
StreamSQL 实践
-
平台化建设
-
挑战及规则
1. 滴滴大数据服务架构
滴滴基于开源的生态构建了比较完整的大数据体系,包括离线、实时系统,如 HBase 生态、数据检索 Elastic Search、消息队列 Kafka 等。在 Flink 基础上滴滴主要发展 StreamSQL,之后会有详细介绍。
2. 滴滴流计算发展历程
在2017年之前,滴滴流计算主要依靠业务方自建小集群的方式,技术选型也多种多样,包括 Storm、jstrom、Spark、Samza 等。2017年开始进行业务收敛,保留了8个 Spark Streaming 并构建了一个平台化、服务化的大集群,并且引入了 Flink。引入 Flink 的原因是部分业务对实时性要求较高,Spark Streaming 无法支持。2018年滴滴构建了基于 Flink SQL 的名为 StreamSQL 的 SQL 化服务,并且使用 Flink CEP 解决了一些网约车实时运营问题。2019年,滴滴完成了流计算引擎的统一,绝大部分任务以 Flink 为基础,通过 StreamSQL 开发流计算任务成为主流开发方式,达到了50%以上。
3. 滴滴流计算业务规模和场景
在业务规模方面,目前滴滴流计算服务业务线达到50多个,集群规模在千级别,流计算任务数达到3000+,每天处理的数据量达到万亿条。
在业务场景上,主要包括以下四类:
实时监控:实时监控包括交易指标监控、导航及 POI 准确率监控、业务健康度监控 ( 例如业务压测中的水位线、当前水位同水位线的实时差距监控 ) 和车辆网监控等。
实时同步:实时同步主要作用是把数据实时地从一个地方转移到另一个地方,数据包括业务日志、数据库日志、轨迹数据、埋点数据。轨迹数据放在 HBase。
实时特征:实时特征是比较关键的业务,它会影响派单,例如派单的导航和准确性。这些特征包括司机乘客特征、上下车特征、导航轨迹特征、工单特征。滴滴每天的客户量在百万级别,如果检测到高危,需要立刻触发报警和客服介入。
实时业务:实时业务会影响业务行为,包括司乘位置语义同步 ( 接单过程中司机可以实时知道乘客位置变化、乘客也可以知道司机位置变化 )、异常停留监测、高危行程监测、个性化发券、路线偏移监测等。
4. 滴滴流计算多集群体系
滴滴随着业务发展机房越来越多,为了更好地管理,对业务提供统一视图,滴滴在集群体系做了三方面的改进。
-
在 YARN 的基础上构建了路由层。路由层的职责是屏蔽多个物理集群,对业务方提供单一的逻辑集群。通过 YARN 上 queue 的划分来决定业务运行在机房的不同集群上。
-
在物理集群内部划分 label,通过 label 可以进行隔离,专门服务那些重要的不希望受到其他业务影响的业务。
-
同时定制了 YARN 调度器。由于实时和离线业务调度差异较大,所以两类业务调度完全分开。对于离线业务,希望尽可能把机器资源全部应用起来,吞吐越大越好。而实时业务对均衡性要求更高,所以将调度改为基于 CPU 调度,并且可以智能过滤繁忙节点 ( 如 CPU 使用较高的节点 ),也做了动态资源推荐,并将推荐值告知用户。
1. StreamSQL 的优势
StreamSQL 是在 Flink SQL 基础上做一些完善后形成的一个产品。使用 StreamSQL 具有多个优势:
-
描述性语言:业务方不需要关心底层实现,只需要将业务逻辑描述出来即可。
-
接口稳定:Flink 版本迭代过程中只要 SQL 语法不发生变化就非常稳定。
-
问题易排查:逻辑性较强,用户能看懂语法即可调查出错位置。
-
批流一体化:批处理主要是 HiveSQL 和 Spark SQL,如果 Flink 任务也使用 SQL 的话,批处理任务和流处理任务在语法等方面可以进行共享,最终实现一体化的效果。
-
入门门槛低:StreamSQL 的学习入门的门槛比较低,因此受到了广大开发者的欢迎。
2. StreamSQL 相对于 Flink SQL 的完善
完善 DDL:
包括上游的消息队列、下游的消息队列和各种存储如 Druid、HBase 都进行了打通,用户方只需要构建一个 source 就可以将上游或者下游描述出来。
内置消息格式解析:
用户消费数据后需要将数据进行提取,但数据格式往往非常复杂,如数据库日志 binlog,每个用户单独实现,难度较大。StreamSQL 将提取库名、表名、提取列等函数内置,用户只需创建 binlog 类型 source。并内置了去重能力。
对于 business log 业务日志 StreamSQL 内置了提取日志头,提取业务字段并组装成 Map 的功能。对于 json 数据,用户无需自定义 UDF,只需通过 jsonPath 指定所需字段。
扩展 UDX:
丰富内置 UDX,如对 JSON、MAP 进行了扩展,这些在滴滴业务使用场景中较多。支持自定义 UDX,用户自定义 UDF 并使用 jar 包即可。兼容 Hive UDX,例如用户原来是一个 Hive SQL 任务,则转换成实时任务不需要较多改动,有助于批流一体化。
Join 能力:
① 基于 TTL 的双流 join:
在滴滴的流计算业务中有的 join 操作数据对应的跨度比较长,例如顺风车业务发单到接单的时间跨度可能达到一个星期左右,如果这些数据的 join 基于内存操作并不可行,通常将 join 数据放在状态中,窗口通过 TTL 实现,过期自动清理。
② 维表 join 能力:
维表支持 HBase、KVStore、Mysql 等,同时支持 inner、left、right、full join 等多种方式。
1. StreamSQL IDE
滴滴对于 StreamSQL 构建了 StreamSQL IDE,除了基本的 StreamSQL editor 外,还主要包含多个其他功能:
-
SQL 模板:如果用户想要开发流式 SQL 时不需要从零开始,只需要选择一个 SQL 模板,并在这个模板之上进行修修改改即可达到期望的结果。
-
UDF 函数说明:StreamSQL IDE 还提供了 UDF 的库,相当于一个库如果不知道具有什么含义以及如何使用,用户只需要在 IDE 上搜索到这个库,就能够找到使用说明以及使用案例。
-
语法检测与智能提示:用户输入 DB 名字可以显示表名,对错误语法提示。
-
DEBUG:在线 DEBUG 能力,可以上传本地测试数据或者采样少量 Kafka 等 source 数据 debug,此功能对流计算任务非常重要。
-
版本管理:因为业务版本需要不断升级,而升级时也可能需要回退,因此 StreamSQL IDE 也提供了版本管理功能。
2. 任务管控
滴滴的所有流计算全部是通过 Web 化入口进行提交,提供了整个任务生命周期管理,包括任务提交、任务停止、任务升级和回滚。同时只需要在 web 化服务台进行参数修改即可实现对内置参数 ( 如 task manager memory 等 ) 进行调优。
3. 任务运维
任务运维主要分为四个方面:
日志检索:Flink UI 上查询日志体验非常糟糕,滴滴将 Flink 任务日志进行了采集,存储在 ES 中,通过 WEB 化的界面进行检索,方便调查。
指标监控:Flink 指标较多,通过 Flink UI 查看体验糟糕,因此滴滴构建了一个外部的报表平台,可以对指标进行监控。
报警:报警需要做一个平衡,如重启报警有多类如 ( 机器宕机报警、代码错误报警 ),通过设置一天内单个任务报警次数阈值进行平衡,同时也包括存活报警 ( 如 kill、start )、延迟报警、重启报警和 Checkpoint 频繁失败报警 ( 如 checkpoint 周期配置不合理 ) 等。
血缘追踪:实时计算任务链路较长,从采集到消息通道,流计算,再到下游的存储经常包括4-5个环节,如果无法实现追踪,容易产生灾难性的问题。例如发现某流式任务流量暴涨后,需要先查看其消费的 topic 是否增加,topic 上游采集是否增加,采集的数据库 DB 是否产生不恰当地批量操作或者某个业务在不断增加日志。这类问题需要从下游到上游、从上游到下游多方向的血缘追踪,方便调查原因。
4. Meta 化建设
对比批处理任务,流计算 Flink 任务需要先定义好 Source、Sink,需要先定义好 MetaStore,因此滴滴目前正在做实时 Meta,将实时数据如 Kafka 的数据流定义成实时表,存储在 MetaStore 中,用户在 IDE 中只需要写 DML ( 数据操纵语言 Data Manipulation Language ) 语句,系统在执行时自动填补 DDL ( 数据定义语言 Data Definition Language ) 语句,将完整的 StreamSQL 提交到 Flink 中去,该工作可以极大的降低 Flink 的使用门槛。
5. 批流一体化
虽然 Flink 具备批流一体化能力,但滴滴目前并没有完全批流一体化,希望先从产品层面实现批流一体化。通过 Meta 化建设,实现整个滴滴只有一个 MetaStore,无论是 Hive、Kafka topic、还是下游的 HBase、ES 都定义到 MetaStore 中,所有的计算引擎包括 Hive、Spark、Presto、Flink 都查询同一个 MetaStore,实现整个 SQL 开发完全一致的效果。根据 SQL 消费的 Source 是表还是流,来区分批处理任务和流处理任务,从产品层面上实现批流一体化效果。
1. 面临的挑战
大状态管理:
-
Flink 作为一个有状态的计算引擎,状态有时会非常大,在记录 checkpoint 过程中需要数据线对齐,磁盘 IO 变大,导致机器负载增大,checkpoint 效率的高低会影响服务稳定性。
-
目前 checkpoint 是一个黑盒,如何做状态诊断是一个挑战。
-
通过内置系统解决了上游不重复问题,但 Flink 本身问题没有解决,希望构建一个端到端的 Exactly Once。
业务高可用:
-
滴滴很多内部业务是通过 golang 或者 java 开发,迁移到 Flink 后,可以解决容错问题、拓展问题、算法模型问题等。在升级时业务不可停,需要实现透明升级。
-
快速诊断解决问题。
-
资源伸缩,如滴滴的早晚高峰时流量突增情况下如何保持系统稳定。
多语言:
-
虽然今天在滴滴大部分实时任务都是通过 SQL 来开发的,但是依旧不能100%覆盖全部的场景,有些场景下是需要写代码的。Flink 提供了 Java 和 Scala 这两种 API,但这对于业务人员而言依然是不够的,因为业务大部分是 Go 语言系或者 Python 语言系的,因此滴滴希望根据社区来提供多语言的开发 Flink 的能力,比如写 SQL,而 UDF 也可以通过多语言来开发。
2. 未来规划
-
提供高可用的流计算服务:使 Flink 具备支持完整线上业务能力的机制。
-
探索实时机器学习:借助 Flink 已经具备了10-15分钟的模型更新能力,接下来希望实现秒级别的模型更新。
-
实时数仓:目前的数仓系统大部分还是 T+1 级别,如何构建实时数仓,得到实时化报表,同时口径和离线保持一致,实现实时数据和离线数据互补。例如最长保存3个月的实时存储系统在3个月后将数据搬至离线仓库时,和离线产生数据保持一致,是一个较大的挑战和希望。
本次的分享就到这里,谢谢大家。
特别推荐一个分享架构+算法的优质内容,还没关注的小伙伴,可以长按关注一下:
长按订阅更多精彩▼
如有收获,点个在看,诚挚感谢
免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!