关于flink:进击的-Flink网易云音乐实时数仓建设实践

1次阅读

共计 5741 个字符,预计需要花费 15 分钟才能阅读完成。

如何基于 Flink 的新 API 降级实时数仓架构?

背景介绍

网易云音乐从 2018 年开始搭建实时计算平台,到目前为止曾经倒退至如下规模:

  1. 机器数量:130+
  2. 单 Kafka 峰值 QPS:400W+
  3. 在线运行工作数:500+
  4. 开发者:160+
  5. 业务笼罩:在线业务反对,实时报表统计,实时特色解决,实时索引反对
  6. 2020 年 Q1 工作数增长 100%,处于高速倒退中

这是网易云音乐实时数仓 18 年的版本,基于 Flink 1.7 版本开发,过后 Flink SQL 的整体架构也还不是很欠缺。咱们应用了 Antlr(通用的编程语言解析器,它只需编写名为 G4 的语法文件,即可主动生成解析的代码,并且以对立的格局输入,解决起来非常简单。因为 G4 文件是通过开发者自行定制的,因而由 Antlr 生成的代码也更加简洁和个性化)自定义了一些 DDL 欠缺了维表 Join 的语法。通过 Antlr 实现语法树的解析当前,再通过 CodeGen(依据接口文档生成代码)技术去将整个 SQL 代码生成一个 Jar 包,而后部署到 Flink 集群下来。

此时还没有对立的元数据管理系统。在 JAR 包工作的开发上, 咱们也没有任何框架的束缚,平台也很难晓得 JAR 的工作上下游以及相干业务的重要性和优先级。这套架构咱们跑了将近一年的工夫,随着工作越来越多,咱们发现了以下几个问题:

反复的数据了解

因为没有进行对立的元数据管理,每个工作的代码外面都须要事后定义 DDL 语句,而后再进行 Select 等业务逻辑的开发;音讯的元数据不能复用,每个开发都须要进行反复的数据了解,须要理解数据从哪里来、数据如何解析、数据的业务含意是什么;整个过程须要多方沟通,整体还存在了解谬误的危险;也不足对立的管理系统去查找本人想要的数据。

和官网版本越走越远

因为晚期版本很多 SQL 的语法都是咱们本人自定义的,随着 Flink 自身版本的欠缺,语法和官网版本差异越来越大,功能完善性上也慢慢跟不上官网的版本,易用性天然也越来越差。如果你自身就是一名熟知 Flink SQL 的开发人员,可能还须要重新学习咱们平台本人的语法,整体不是很对立,有些问题也很难在互联网上找到相干的材料,只能靠运维来解决。

工作运维问题

SQL 工作没有对立的元数据管理、上下游的数据源没有对立的注销、JAR 包工作没有对立的框架束缚、平台方很难跟踪整个平台数据流的走向,咱们不晓得平台上运行的几百个工作别离是干什么的,哪些工作读了哪个数据源?输入了什么数据源?工作的品种是什么?是线上的,测试的,重要的还是不重要的。没有这些数据的撑持,导致整个运维工作十分局限。

网易云音乐的业务倒退十分快,数据量越来越大,线上库和一些其它的库变更非常频繁,相干的实时工作也要跟着业务架构的调整,变更相干数据源的地址。此时咱们就须要晓得哪些工作用到了相干的数据源,如果平台没有能力很快筛选出相干工作,整个流程解决起来就非常繁冗了。

首先,须要分割平台所有的开发者确认是否有相干工作的数据源,整个流程十分浪费时间,而且还有可能产生疏漏;其次,假如呈现平台流量激增,做运维工作时,如果咱们不晓得工作在干什么,天然也不能晓得的工作的重要性,不晓得哪些工作能够限流,哪些工作能够做暂时性的进行,哪些工作要重点保障。

实时数仓建设

带着这些问题,咱们开始进行新版本的构建工作。

  • 在 Flink 1.9 版本当前,Flink 有了重大变动,重构了 Catalog 的 API,这和之前咱们做的离线方向的工作有肯定的符合。在离线的生态上,网易云音乐有着一套十分残缺的服务体系,买通元数据中心和 Spark SQL,能够通过 Spark SQL 连贯元数据中心的元数据,进行异构数据源的联邦查问以及数据传输工作;
  • 同样基于 Flink 1.10,咱们利用新的 Catalog 的 API 实现了一个元数据中心的 Catalog。将元数据中心作为 Flink SQL 的底层元数据组件,实现了 Kafka 到元数据中心任一数据源的实时的数据传输,以及 Redis、HBase、Kudu 等数据源的维表 JOIN 的实现;
  • 除了纯 SQL 的开发方式外,咱们还提供了一套 SDK,让用户能够通过 SQL 加代码混合应用的形式来实现本人的业务逻辑,晋升整个 Flink API 的易用性,大大降低用户的开发门槛,晋升了平台对工作的管控能力;
  • 有了对立的元数据的治理以及 SDK 的开发方式,血统收集也变得瓜熟蒂落,有了上下游数据的走向信息,平台也很容易通过数据源的业务属性来判断工作的重要性。

元数据中心

不晓得大家有没有用过 Apache Atlas、Netflix 的 Metacat 等工具,网易云音乐的元数据中心顾名思义就是一个元数据管理的程序,用于治理网易云音乐所有数据源的元数据。你有可能在理论的开发中用到 Oracle、Kudu、Hive 等工具,也有可能是自研的分布式数据库。如果没有对立的元数据管理,咱们很难晓得咱们有哪些数据,数据是如何流转的,也很难疾速找到本人想要的数据。

将它们对立治理的益处是,能够通过元数据中心疾速找到本人想要的数据,理解数据表的连贯信息、schema 信息,字段的业务含意,以及所有表的数据起源和走向。

咱们的元数据中心零碎有以下几个特点:

  1. 扩展性强: 元数据中心零碎实践上是能够治理所有的数据存储中间件的,每个存储中间件都能够通过插件的形式热部署扩大下来,目前咱们曾经反对了云音乐外部简直所有的存储中间件;
  2. 下推查问: 对于本身有元数据系统的存储中间件,如刚刚提到的 Oracle、Kudu、Hive 等,咱们采纳的是下推查问的形式,间接去查问它们的元数据的数据库,获取到相应的元数据信息,这样就不会存在元数据不统一的问题;
  3. Nest 元数据注销: 对于像 Kafka、RocketMQ 这种本身并不存在元数据体系的,元数据中心外部有一个内嵌的元数据模块 Nest,Nest 参考了 Hive 元数据的实现,用户能够手动注销相干数据的 Schema 信息;
  4. 对立的类型零碎: 为了更好的治理不同类型的的数据源,不便内部查问引擎对接,元数据中心有一套欠缺的类型零碎,用户在实现不同数据源的插件时须要实现本身类型体系到元数据类型的映射关系;
  5. 元数据检索: 咱们会定期用全量数和增量的形式将元数据同步到 ES 当中,不便用户疾速查找本人想要的数据;
  6. 欠缺的血统性能: 只有将工作的上下游依照指定的格局上报到元数据中心,就能够通过它提供的血统接口去拿到整个数据流的血统链路。

建设流程

须要进行的工作包含:

  1. 应用元数据中心的 API 实现 Flink Catalog API。
  2. 元数据中心到 Flink 零碎的数据类型转换,因为元数据中有一套对立的类型零碎,只须要解决 Flink 的类型零碎到元数据类型零碎的映射即可,不须要关怀具体数据源的类型的转换。
  3. 数据源属性和表属性的转换,Flink 中表的属性决定了它的源头、序列化形式等,然而元数据中心也有本人的一套属性,所以须要手动转换一些属性信息,次要是一些属性 key 的对齐问题。
  4. 血统解析上报。
  5. 序列化格局欠缺。
  6. Table Connector 的欠缺,欠缺罕用的存储中间件的 Table Connector,如 Kudu、网易外部的  DDB 以及云音乐自研的 Nydus 等。
  7. 提供 SDK 的开发方式:SDK 开发相似于 Spark SQL 的开发方式,通过 SQL 读取数据,做一些简略的逻辑解决,而后转换成 DataStream,利用底层 API 实现一些简单的数据转换逻辑,最初再通过 SQL 的形式 sink 进来。简略来说就是,SQL 加代码混编的形式,晋升开发效率,让开发专一于业务逻辑实现,同时保障血统的完整性和便利性,且充分利用了元数据。

实现以上工作后,整体根本就能实现咱们的预期。在一个 Flink 工作的开发中,波及的数据源次要有三类:

  • 流式数据:来自 Kafka 或者 Nydus,能够作为源端和指标端;
  • 维表 JOIN 数据:来自 HBase、Redis、JDBC 等,这个取决于咱们本人实现了哪些;
  • 落地数据源:个别为 MySQL、HBase、Kudu、JDBC 等,在流解决模式下通常作为指标端。

对于流式数据,咱们应用元数据中心自带的元数据系统 Nest 注销治理(参考右上角的图);对于维表以及落地数据源等,能够间接通过元数据中心获取库表 Schema 信息,无需额定的 Schema 注销,只须要一次性注销下数据源连贯信息即可(参考右下角的图)。整体对应咱们零碎中数仓模块的元数据管理、数据源注销两个页面。

实现注销工作当前,咱们能够通过 catalog.[table] 等形式拜访任一元数据中心中注销的表,进行 SQL 开发工作。其中 Catalog 是在数据源注销时注销的名字;db 和 table 是相应数据源本身的 DB 和 Table,如果是 MySQL 就是 MySQL 本身元数据中的 DB 和 Table。

最终成果能够参考左下角读取实时表数据写入 Kudu 的的例子,其中红框局部是一个 Kudu 数据表,在应用前只须要注销相干连贯信息即可,无需登记表信息,平台会从元数据中心获取。

ABTest 我的项目实际

我的项目阐明

ABTest 是目前各大互联网公司用来评估前端改变或模型上线成果的一种无效伎俩,它次要波及了两类数据:第一个是用户分流数据,一个 AB 试验中用户会被分成很多组;而后就是相干指标统计数据,咱们通过统计不同分组的用户在相应场景下指标的好坏,来判断相干策略的好坏。这两类数据被分为两张表:

  • 用户分流表:dt 示意工夫,os 示意操作系统。ab_id 是某个 ABTest 的 id 号,group_id 就是分组 id,group_type 分为两种,对照组指的是 ABTest 外面的基准,而实验组即是这次 ABTest 须要去评估的这批数据。userId 就是用户 id 了。
  • 指标统计表:依据 dt、os 等不同维度来统计每个用户的无效播放,曝光,点击率等指标,metric、metric_ext 组合成一个具体含意。

在晚期版本中,咱们应用 Spark 依照小时粒度实现从 ODS 到 DWD 层数据荡涤工作,生成用户分流表和指标统计表。而后再应用 Spark 关联这两张表的数据将后果写入到 Kudu 当中,再应用 Impala 零碎对接,供用户进行查问。

这套计划的最大的问题是提早太高,往往须要提早一到两个小时,有些甚至到第二天能力看到后果。对于提早归档的数据也不能及时对后果进行修改。

这个计划对咱们的业务方比方算法来说,上线一个模型须要等到两个小时甚至第二天能力看到线上的成果,试错老本太高,所以起初应用新版的实时仓开发了一套实时版本。

如上图所示,是咱们实时版本 ABTest 的数据走向,咱们整体采纳了 Lambda 架构:

  • 第一步: 应用 Flink 订阅 ODS 原始的数据日志,解决成 DWD 层的数据分流表和指标统计表,同时也将实时的 DWD 层数据同步到雷同构造的 Hive 表当中。DWD 层解决的目标是将业务数据荡涤解决成业务能看懂的数据,没有聚合操作,实现比较简单。然而流数据归档到 Hive 的过程中须要留神小文件问题,文件落地的频率越高,提早越低,同时落地的小文件也会越多,所以须要在技术和需要上衡量这个问题。同时在下方,咱们也会有一条离线的数据流来解决同样的过程,这个离线不是必须的,如果业务方对数据的准确性要求十分高,咱们须要用离线解决做一次修改,解决数据反复问题。这一步还波及到一个埋点的简单问题,如果一个指标的埋点非常复杂,比方须要依赖工夫程序门路的归因,而且自身客户端日志的提早水平也十分不牢靠的话,离线的修复策略就更加有必要了。
  • 第二步:DWS 层解决,读取第一步生成的 DWD 的流表数据应用 Flink 依照天和小时的维度做全局聚合,这一步利用了 Flink 状态计算的特点将两头后果保护在 RocksDB 的状态当中。而后应用 RetractionSink 将后果数据一直写入到 Kudu,生成一个一直修改的 DWS 层聚合数据。同样咱们也会应用 Spark 做一套同样逻辑的计算历史数据来做数据的修改。

  • 这个步骤波及到几个问题:
  1. Flink 大状态的运维和性能问题:为了解决了这个问题,咱们应用 SSD 的机器专门用来运行这种大状态的工作,保障 RocksDB 状态的吞吐性能;
  2. Kudu 的 Update 性能问题:这里做了一些 minibatch 的的优化升高 Kudu 写入的压力;
  3. Lambda 架构的运维老本:实时离线两套代码运维老本比拟高。
  • 第三步: 后果数据对接
  • 对于实时的后果数据咱们应用 Impala 间接关联用户分流表和指标数据表,实时计算出后果反馈给用户;
  • 对于 T+1 的历史数据,因为数据曾经落地,并且不会再变了,所以为了升高 Impala 的压力,咱们应用 Spark 将后果提前计算好存在 Kudu 的后果表中,而后应用 Impala 间接查问出计算好的后果数据。

批流一体

后面介绍的 ABTest 实时化整个实现过程就是一套残缺的批流一体 Lambda 架构的实现。ODS 和 DWD 层既能够订阅拜访,也能够批量读取。DWD 层落地在反对更新操作的 Kudu 当中,和下层 OLAP 引擎对接,为用户提供实时的后果。目前实现上还有一些有余,然而将来批流一体的致力方向应该能看得比较清楚了。

咱们认为批流一体次要分以下三个方面:

■ 1. 后果的批流一体

应用数据的人不须要关怀数据是批处理还是流解决,在提交查问的那一刻,拿到的后果就应该是截止到目前这一刻最新的统计后果,对于最上层用户来说没有批和流的概念。

■ 2. 存储的批流一体

下面的 ABTest 例子中咱们曾经看到 DWD、DWS 层数据的存储上还有很多有余,业界也有一些相应解决方案期待去尝试,咱们心愿的批流一体存储须要以下几个个性:

  1. 同时提供增量订阅读取以及批量读取的能力,如 Apache Pulsar,咱们能够批量读取它外面的归档数据,也能够通过 Flink 订阅它的流式数据,解决 DWD 层两套存储的问题。
  2. 高性能的实时 / 批量 append 和 update 能力,读写互不影响,提供相似于 MVCC 的机制,相似于 Kudu 这种,然而性能须要更加强悍来解决 DWS 层存储的问题。
  3. 和 OLAP 引擎的对接能力,比方 Impala、Presto 等,并且如果想要晋升查问效率可能还要思考到列式存储,具备较强的 scan 或者 filter 能力,来满足下层用户对业务后果数据查问效率的诉求。

■ 3. 计算引擎的批流一体

做到一套代码解决批流对立场景,升高开发运维老本,这个也是 Flink 正在致力的方向,将来咱们也会在下面做一些尝试。

正文完
 0