导读:Apache Flink 是一个分布式大数据处理引擎,可对有限数据流和无限数据流进行有状态计算。可部署在各种集群环境,对各种大小的数据规模进行快速计算。
滴滴基于 Apache Flink 做了大量的优化,也增加了更多的功能,比如扩展 DDL、内置消息格式解析、扩展 UDX 等,使得 Flink 能够在滴滴的业务场景中发挥更大的作用。本文中,滴滴出行实时计算负责人、高级技术专家梁李印分享了 Apache Flink 在滴滴的应用与实践。
主要内容包括:
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. 滴滴流计算多集群体系
滴滴随着业务发展机房越来越多,为了更好地管理,对业务提供统一视图,滴滴在集群体系做了三方面的改进。
1. StreamSQL 的优势
StreamSQL 是在 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 外,还主要包含多个其他功能:
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. 面临的挑战
大状态管理:
业务高可用:
多语言:
2. 未来规划