网易云音乐基于 Flink + Kafka 的实时数仓建设实践

简介: 本文由 网易云音乐实时计算平台研发工程师岳猛 分享,主要从如下四个部分 将为你们介绍 Flink + Kaf ka 在网易云音乐的应用实战

  1. 背景web

  2. Flink + Kafka 平台化设计微信

  3. Kafka 在实时数仓中的应用架构

  4. 问题 & 改进并发


直播回放:https://developer.aliyun.com/live/2894


1、背景介绍app


(一)流平台通用框架

目前流平台通用的架构通常来讲包括消息队列、计算引擎和存储三部分,通用架构以下图所示。客户端或者 web 的 log 日志会被采集到消息队列;计算引擎实时计算消息队列的数据;实时计算结果以 Append 或者 Update 的形式存放到实时存储系统中去。

目前,咱们经常使用的消息队列是 Kafka,计算引擎一开始咱们采用的是 Spark Streaming,随着 Flink 在流计算引擎的优点愈来愈明显,咱们最终肯定了 Flink 做为咱们统一的实时计算引擎。


(二)为何选 Kafka?

Kafka 是一个比较早的消息队列,可是它是一个很是稳定的消息队列,有着众多的用户群体,网易也是其中之一。咱们考虑 Kafka 做为咱们消息中间件的主要缘由以下:

  • 高吞吐,低延迟:每秒几十万 QPS 且毫秒级延迟;框架

  • 高并发:支持数千客户端同时读写;运维

  • 容错性,可高性:支持数据备份,容许节点丢失;高并发

  • 可扩展性:支持热扩展,不会影响当前线上业务。oop


(三)为何选择 Flink?

Apache Flink 是近年来愈来愈流行的一款开源大数据流式计算引擎,它同时支持了批处理和流处理,考虑 Flink 做为咱们流式计算引擎的主要因素是:

  • 高吞吐,低延迟,高性能;性能

  • 高度灵活的流式窗口;

  • 状态计算的 Exactly-once 语义;

  • 轻量级的容错机制;

  • 支持 EventTime 及乱序事件;

  • 流批统一引擎。


(四)Kafka + Flink 流计算体系

基于 Kafka 和 Flink 的在消息中间件以及流式计算方面的耀眼表现,因而产生了围绕 Kafka 及 Flink 为基础的流计算平台体系,以下图所示:基于 APP、web 等方式将实时产生的日志采集到 Kafka,而后交由 Flink 来进行常见的 ETL,全局聚合以及Window 聚合等实时计算。


(五)网易云音乐使用 Kafka 的现状

目前咱们有 10+个 Kafka 集群,各个集群的主要任务不一样,有些做为业务集群,有些做为镜像集群,有些做为计算集群等。当前 Kafka 集群的总节点数达到 200+,单 Kafka 峰值 QPS 400W+。目前,网易云音乐基于 Kafka+Flink 的实时任务达到了 500+。

2、Flink+Kafka 平台化设计


基于以上状况,咱们想要对 Kafka+Flink 作一个平台化的开发,减小用户的开发成本和运维成本。实际上在 2018 年的时候咱们就开始基于 Flink 作一个实时计算平台,Kafka 在其中发挥着重要做用,今年,为了让用户更加方便、更加容易的去使用 Flink 和 Kafka,咱们进行了重构。

基于 Flink 1.0 版本咱们作了一个 Magina 版本的重构,在 API 层次咱们提供了 Magina SQL 和 Magina SDK 贯穿 DataStream 和 SQL 操做;而后经过自定义 Magina SQL Parser 会把这些 SQL 转换成 Logical Plan,在将 LogicalPlan 转化为物理执行代码,在这过程当中会去经过 catalog 链接元数据管理中心去获取一些元数据的信息。咱们在 Kafka 的使用过程当中,会将 Kafka 元数据信息登记到元数据中心,对实时数据的访问都是以流表的形式。在 Magina 中咱们对 Kafka 的使用主要作了三部分的工做:

  • 集群 catalog 化;

  • Topic 流表化;

  • Message Schema 化。



用户能够在元数据管理中心登记不一样的表信息或者 catalog 信息等,也能够在 DB 中建立和维护 Kafka 的表,用户在使用的过程只须要根据我的需求使用相应的表便可。下图是对 Kafka 流表的主要引用逻辑。


3、Kafka 在实时数仓中的应用


(一)在解决问题中发展

Kafka 在实时数仓使用的过程当中,咱们遇到了不一样的问题,中间也尝试了不一样的解决办法。

在平台初期, 最开始用于实时计算的只有两个集群,且有一个采集集群,单 Topic 数据量很是大;不一样的实时任务都会消费同一个大数据量的 Topic,Kafka 集群 IO 压力异常大;

所以,在使用的过程发现 Kafka 的压力异常大,常常出现延迟、I/O 飙升。

咱们想到把大的 Topic 进行实时分发来解决上面的问题,基于 Flink 1.5 设计了以下图所示的数据分发的程序,也就是实时数仓的雏形。基于这种将大的 Topic 分发成小的 Topic 的方法,大大减轻了集群的压力,提高了性能,另外,最初使用的是静态的分发规则,后期须要添加规则的时候要进行任务的重启,对业务影响比较大,以后咱们考虑了使用动态规则来完成数据分发的任务。


解决了平台初期遇到的问题以后,在平台进阶过程当中 Kafka 又面临新的问题:

  • 虽然进行了集群的扩展,可是任务量也在增长,Kafka 集群压力仍然不断上升;

  • 集群压力上升有时候出现 I/O 相关问题,消费任务之间容易相互影响;

  • 用户消费不一样的 Topic 过程没有中间数据的落地,容易形成重复消费;

  • 任务迁移 Kafka 困难。


针对以上问题,咱们进行了以下图所示的 Kafka 集群隔离和数据分层处理。其过程简单来讲,将集群分红 DS 集群、日志采集集群、分发集群,数据经过分发服务分发到 Flink 进行处理,而后经过数据清洗进入到 DW 集群,同时在 DW 写的过程当中会同步到镜像集群,在这个过程当中也会利用 Flink 进行实时计算的统计和拼接,并将生成的 ADS 数据写入在线 ADS 集群和统计 ADS 集群。经过上面的过程,确保了对实时计算要求比较高的任务不会受到统计报表的影响。


经过上面的过程,确保了对实时计算要求比较高的任务不会受到统计报表的影响。可是咱们分发了不一样的集群之后就不可避免的面临新的问题:

  • 如何感知 Kafka 集群状态?

  • 如何快速分析 Job 消费异常?


针对上面两个问题,咱们作了一个 Kafka 监控系统,其监控分为以下两个维度,这样在出现异常的时候就能够进行具体判断出现问题的详细状况:

  • 集群概况的监控:能够看到不一样集群对应的 Topic 数量以及运行任务数量,以及每一个 Topic 消费任务数据量、数据流入量、流入总量和平均每条数据大小;

  • 指标监控:能够看到 Flink 任务以及对应的 Topic、GroupID、所属集群、启动时间、输入带宽、InTPS、OutTPS、消费延迟以及 Lag 状况。


(二)Flink + Kafk a 在 Lambda 架构下的运用

流批统一是目前很是火的概念,不少公司也在考虑这方面的应用,目前经常使用的架构要么是 Lambda 架构,要么是 Kappa 架构。对于流批统一来说须要考虑的包括存储统一和计算引擎统一,因为咱们当前基建没有统一的存储,那么咱们只能选择了 Lamda 架构。

下图是基于 Flink 和 Kafka 的 Lambda 架构在云音乐的具体实践,上层是实时计算,下层是离线计算,横向是按计算引擎来分,纵向是按实时数仓来区分。


4、问题&改进


在具体的应用过程当中,咱们也遇到了不少问题,最主要的两个问题是:

  • 多 Sink 下 Kafka Source 重复消费问题;

  • 同交换机流量激增消费计算延迟问题。


(一)多 Sink 下 Kafka Source 重复消费问题

Magina 平台上支持多 Sink,也就是说在操做的过程当中能够将中间的任意结果插入到不一样的存储中。这个过程当中就会出现一个问题,好比同一个中间结果,咱们把不一样的部分插入到不一样的存储中,那么就会有多条 DAG,虽然都是临时结果,可是也会形成 Kafka Source 的重复消费,对性能和资源形成极大的浪费。

因而咱们想,是否能够避免临时中间结果的屡次消费。在 1.9 版本以前,咱们进行了 StreamGraph 的重建,将三个 DataSource 的 DAG 进行了合并;在 1.9 版本,Magina 本身也提供了一个查询和 Source 合并的优化;可是咱们发现若是是在同一个 data update 中有对同一个表的多个 Source 的引用,它本身会合并,可是若是不是在同一个 data update 中,是不会当即合并的,因而在 1.9 版本以后中咱们对 modifyOperations 作了一个 buffer 来解决这个问题。


(二)同交换机流量激增消费计算延迟问题

这个问题是最近才出现的问题,也可能不只仅是同交换机,同机房的状况也可能。在同一个交换机下咱们部署了不少机器,一部分机器部署了 Kafka 集群,还有一部分部署了 Hadoop 集群。在 Hadoop 上面咱们可能会进行 Spark、Hive 的离线计算以及 Flink 的实时计算,Flink 也会消费 Kafka 进行实时计算。在运行的过程当中咱们发现某一个任务会出现总体延迟的状况,排查事后没有发现其余的异常,除了交换机在某一个时间点的浏览激增,进一步排查发现是离线计算的浏览激增,又由于同一个交换机的带宽限制,影响到了 Flink 的实时计算。


为解决这个问题,咱们就考虑要避免离线集群和实时集群的相互影响,去作交换机部署或者机器部署的优化,好比离线集群单独使用一个交换机,Kafka 和 Flink 集群也单独使用一个交换机,从硬件层面保证二者之间不会相互影响。

5、Q & A


Q1:Kafka 在实时数仓中的数据可靠吗?

A1:这个问题的答案更多取决于对数据准确性的定义,不一样的标准可能获得不一样的答案。本身首先要定义好数据在什么状况下是可靠的,另外要在处理过程当中有一个很好的容错机制。

Q2:咱们在学习的时候如何去学习这些企业中遇到的问题?如何去积累这些问题?

A2:我的认为学习的过程是问题推进,遇到了问题去思考解决它,在解决的过程当中去积累经验和本身的不足之处。

Q3:大家在处理 Kafka 的过程当中,异常的数据怎么处理,有检测机制吗?

A3:在运行的过程当中咱们有一个分发的服务,在分发的过程当中咱们会根据必定的规则来检测哪些数据是异常的,哪些是正常的,而后将异常的数据单独分发到一个异常的 Topic 中去作查询等,后期用户在使用的过程当中能够根据相关指标和关键词到异常的 Topic 中去查看这些数据。



  Flink Forward Asia 2020  
官网上线啦

洞察先机,智见将来,  Flink Forward Asia 2020 盛大开启!诚邀开源社区的各方力量与咱们一块儿,探讨新型数字化技术下的将来趋势,共同打造 2020 年大数据领域的这场顶级盛会! 大会官网已上线,点击「 阅读原文 」便可预定峰会报名~

(点击可了解更多议题投递详情)

戳我报名!

本文分享自微信公众号 - Flink 中文社区(gh_5efd76d10a8d)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。