【技术猩球】​七牛云内部平台架构 QStreaming——轻量级大数据ETL的开发框架

QStreaming 背景

首先在进入主题之前我们先来回顾下经典的大数据 ETL 架构有哪些?

1. Lambda 架构

2. Kappa 架构

3. 混合架构

它们之间的区别如下:

七牛的大数据平台在搭建过程中也经历了上面几个架构的变迁,也就是从最早的 Lambda 架构,到尝试使用 Kappa 架构,再到后面的新型混合 ETL 架构,为了满足业务需求,开发人员在这几个架构中进行折中选择,但是我们发现上面几个架构对于大数据的开发人员要求较高,主要体现在下面几个方面:

  1. 涉及到众多的框架,如流处理框架就有早期的 Apache Storm,到后面的 Apache Spark Streaming,再到 Apache Flink,学习门槛较高。

  2. 不同计算框架对数据源的定义不统一,造成输入输出较难管理。

  3. 数据开发人员新开发一个业务指标,不同开发人员写出的代码风格不统一,开发效率低,很难进行工程化,后期维护也必将困难。

为了解决上面的几个问题,团队选择基于 Apache Spark 开发了 QStreaming ( https://github.com/qiniu/QStreaming )这套简单轻量级 ETL 开发框架。

QStreaming 特性

数据源支持

  1. Apache Kafka
  2. Apache Hbase
  3. Hadoop HDFS/S3
    4 .OSS对象存储
  4. Jdbc
  5. MongoDB
  6. Apache Hudi

1. DDL 定义输入源

这里面“stream”关键字代表定义了一个流表,并且是连接到 Kafka 消息中间件。

2. 流处理 Watermark 的 DSL 支持

在 DSL 中添加 Watermark,主要有 2 种方式:

  1. 在 DDL 中指定
  1. 在 create view 语句中指定
  1. 动态 UDF
    比如下面这个转换一个日期字符串为时间戳格式。

  1. 流处理的多输出

这个特性主要是通过 Spark Structed Streaming 的 foreachBatch 实现的。

  1. 变量渲染

变量渲染经常在一些定时调度批处理中非常有用,如下根据小时读取一个 HDFS 上的parquet 文件。

  1. 监控,如 kafka lag 监控

由于 Apache spark 消费 Kafka 是使用的低阶 API,默认我们没有办法知道消费的 topic有没有延迟,我们通过指定 group-id 属性,模拟 Kafka consumer 的 subscribe 模式,这样就和普通的 Kafka consumer 高级 API 一样了。

  1. 数据质量

这个特性主要是用来对数据做单元测试的,比如校验我们 ETL 结果表的准确性。

8.流读批写

这个特性是用来在集成一些第三方 spark connector 的时候,发现某些 connector 没有对流的写入支持得很好,只能在批处理场景中使用,那么这个时候就可以用上这个特性。

比如下面这条语句:

create stream output table behavior_cnt_per_hour using jdbc(url=,
user=,password=,dbTable=)
TBLPROPERTIES(batchWrite=true)

本身 jdbc format 没有对流进行支持,但是我们加上了 TBLPROPERTIES(batchWrite=true),这样就能够在流计算中往数据库写入数据。

9.其他

支持对 view 或者 table 的 repartition 及 coalesce 操作,这个和 spark 本身对 dataset 进行 repartition 及 coalesce 时一样支持的。

比如下面这条 create view 语句加入了coalesce, 代表对结果进行了 coalesce 操作,并且设置重分区为 1 个分区:

create view v_request_log with(coalesce=1) as
select
request_time,
domain,
server_ip,
ip_ver,
scheme,
status_code,
hitmiss,
bytes_sent,
response_time
from request_log;

10.语法

QStreaming 完整的语法特性参考:

(https://github.com/qiniu/QStreaming/blob/master/stream-core/src/main/antlr4/com/qiniu/stream/core/parser/Sql.g4)

QStreaming 架构

架构图

核心组件

从上面的架构图中可以看出 QStreaming 主要有以下几个组件组成:

  1. Pipeline DSL

Pipeline DSL 是一个定义时的 Job 任务描述文件,类似于 SQL 语法,对 Spark SQL 完全兼容,比如下面这个:

  1. Pipeline DSL Parser

Pipeline DSL Parser 组件负责解析 Pipeline DSL 并且转换 ANTLR AST 为 Pipeline Domain Models。

Pipeline Domain Models

  1. Pipleine Translator

Pipeline Translator 进一步将 Pipeline domain model 转换为 Spark transformations and actions。

  1. Data Quality Checker

Data Quality Check 负责解析单元测试语句,使用 Amazon Deequ 库并且翻译为 Deequ 的 Verification Suite。

  1. Pipeline Runner

这个组件负责构建 Pipeline 启动上下文,协同 Pipeline Parser 和 Pipeline Translator一起工作,根据配置启动流或者批处理 Application。

QStreaming 使用场景

场景一

在这一个场景中,QStreaming 主要通过消费 Kafka,然后进行预聚合,预聚合可以进行开窗口计算,比如 1 分钟的窗口,然后再把窗口聚合的结果写入下游数据存储中,这里面很重要的一个特性就是数据订正功能,所以可以选择的 ETL 架构如下:

Lambda架构

Kappa架构

混合架构

场景二

在这个场景中,QStreaming 扮演了一层很薄的角色,比如对数据进行加工,但是不对数据进行聚合,保留了明细,预聚合的功能交给了下游支持 OLAP 引擎,比如支持 RollUp 功能的 Apache Druid,Apache Doris,Clickhouse 等,另外 Apache Doris 还可以保留明细功能。

场景三

在这个场景中,QStreaming 主要是通过 Apache Airflow 进行调度的,ODS 对接 Apache Hive 数据仓库,然后可以做 DWS 或者是 DWD 操作,再把结果写入 Hive 数据仓库中,提供离线即席查询,或者是聚合的结果写入 RDS,NOSQL 等数据库,上层对其结果封装为 API,供用户使用。

场景四

这个场景主要是消息驱动的,通过上游业务方发送消息到消息中间件,然后消费消息驱动 QStreaming ETL 任务。

QStreaming 总结

整体上 QStreaming 可以从 三点简单概况:

1.架构层面: 可用于 Lambda架构,Kappa架构,混合架构三种架构中,并且灵活切换。
2.开发层面: 只需要掌握 SQL 即可。
3.运维层面: 能够实现统一部署和管理。

QStreaming RoadMap

QStreaming 还非常年轻,后期还会有进一步的规划,规划的特性包括 完善数据源支持(如 Delta Lake,Apache Hudi 等), 添加数据血缘功能 和 机器学习 Pipeline。
欢迎大家持续关注我们的项目和「技术猩球」栏目,共同交流技术,畅谈未来。