深度好文|实时数仓不用愁,StarRocks+Flink 来解忧!

本文发表于: &{ new Date(1641916800000).toLocaleDateString() }

2022年1月9日, StarRocks 亮相 Flink Forward Asia 2021 大会开源解决方案专场, StarRocks 解决方案架构师谢寅做了题为【双剑合璧:Flink + StarRocks 构建实时数仓解决方案】的主题演讲。本文以主讲嘉宾从技术方案的角度,为社区的小伙伴带来最全、最详细的文字版回顾。

本文从以下5个方面介绍:

  • 第一部分,实时数仓技术的发展趋势和技术挑战,以及为什么 Flink+StarRocks 能够提供端到端的极速实时数仓体验。
  • 第二部分,介绍什么是 StarRocks,它有哪些技术特点,擅长的场景是什么,以及为什么作为 OLAP 层的极速分析引擎,它能够很好与 Flink 技术进行整合。
  • 第三部分,重点介绍联合 Flink 和 StarRocks 两大技术栈构建实时数仓的方法论。
  • 第四部分,介绍一些利用 Flink 和 StarRocks 构建实时数仓的最佳实践案例。
  • 第五部分,展望了 StarRocks 在实时数仓方向以及 Flink 社区贡献等方面的后续规划。

 

1.实时数仓概述

随着各行各业对数据越来越重视,实时计算技术也在不断的演进。从时效性上来讲,对于小时级或者分钟级的计算已经不能满足客户业务的需要,需求逐渐从时窗驱动,升级到事件驱动,甚至每产生一条数据,都想尽快看到数据。ETL 过程也从离线或者微批的 ETL,变为 Flink 擅长的实时流式处理。

数据源上,早先只能支持单一的数据源,整体的数据表现力较差。而当下,人们不仅希望能对单一数据流进行分析计算,还希望能联合多个数据源进行多流计算,为此不惜想尽一切办法,来让数据的表现力更加丰富。

从工程效率的角度上看,技术团队也逐渐意识到,工程代码开发的成本高企不下,更希望能构建自己的平台化 IDE 工具,让业务人员能基于其上直接进行 FlinkSQL 的开发。在这些演进的过程也逐渐浮现出一些技术难点亟待解决,比如:

  • 乱序数据怎么更好的处理?
  • 通过Watermark之类的手段,是让过去的数据随即失效,还是希望所有的明细数据都能入库?
  • 多流Join到底应该怎么做合适?
  • 维表是一次性加载进来,还是放到外存储做热查询,除此之外还有没有其他的技术选择?
  • 数据处理作业一旦重启,怎么保证在恢复之后还能做到不丢不重的续接消费?
  • 怎么才能提高整体的业务开发效率,保证业务上线时没有业务中断,更优雅快捷的进行业务逻辑迭代?

在此之外,还有一件事也是业务人员或平台架构师最关注的,那就是通过 Flink 这么强大的实时计算引擎,费劲千辛万苦好不容易把计算层效率从小时级或者分钟级的延迟提升到了秒级,结果现有的 OLAP 产品拖了后腿,查询耗费了好几分钟,辜负了计算团队的大量心血。

以上种种,充分证明了极速 OLAP+实时计算的重要性,以此我们就可以打造一套端到端的极速实时数仓解决方案,即所谓“双剑合璧”!

谈到数仓,目前业界落地较多的还是 Lambda 架构,也就是离线数仓和实时数仓分开构建。逻辑分层的形式,也基本形成了业界的共识。业务数据有的是 RDBMS 采集上来的,有的是日志采集上来的,有的是批量抽取上来的,有的是 CDC 或者流式写上来的。原始操作层(ODS)基本都是保持数据原貌,然后经过维度扩展、清洗过滤、转换,构建成明细层(DWD)。再往上层走,数据开始做轻度聚合,并有原子指标出现。最后按照主题或者应用的需要产出 ADS 层里的派生指标或者衍生指标。

企业构建实时数仓,为了让整体的逻辑清晰,通常情况下也会沿用这种分层模式,只不过受限于实时数据到达的先后情况以及业务需要,可能会有些层次的裁剪,不像离线数仓里那么丰富。中间的一些维度信息,可能会同时被离线数仓和实时数仓共享使用。最后将数据送入 OLAP 产品,供报表系统、接口或者Adhoc查询所调用。

基于前面对数仓典型逻辑分层的探讨,问题也随之而来:

是否有一款 OLAP 产品能够很好的和Flink结合,满足持续的秒级的数据摄入和极速分析查询能力?

答案是一定的,StarRocks 的定位正是要提供极速分析查询能力,来适应各种各样的 OLAP 场景。

 

2.StarRocks 是什么

这是 StarRocks 的宏观架构图。

从左边我们可以看到常见的 Kafka、分布式文件系统、传统关系型数据库,都可以作为 StarRocks 的数据源。

StarRocks 提供了4种模型:

  • 如果业务场景只涉及数据的持续 Append,可以选择 Duplicate 明细模型,在其上可以实时构建物化视图加速 DWS 层查询;
  • 如果业务场景不关注明细的下钻,StarRocks 还有 Aggregate 聚合模型表,相当于数据直接秒级打入DWS 层,满足高并发的聚合指标查询;
  • 对于 ODS 层做业务库数据还原时,若涉及到数据更新的场合,可以采用 Unique 模型,利用 Flink 的Append 流 Sink 数据进来,完成 ODS 数据去重和更新;
  • 另外,StarRocks 最新2.0版本提供的 PrimaryKey 主键模型,比 Unique 模型查询性能快3倍以上,内置了 OP 字段来标记 Upsert/Delete 操作,并且能够很好的吻合 Flink 的 Retract 回撤流语义,聚合计算不必非要开窗转为 Append 流来 Sink,进一步增强了 FlinkSQL 的表现力。

StarRocks 还提供了逻辑 View 和物化视图,提供了更丰富的建模能力。

  • 在上图的右侧是 StarRocks 的物理架构,整体还是非常简洁的,主要就是两种角色:FE 前端节点和 BE 后端节点。
  • FE 负责查询规划、元数据管理、集群高可用,并包含 CBO 优化器,为分布式多表关联和复杂 Adhoc 查询提供最优的执行规划。
  • BE 节点承载了列式存储引擎和 全面向量化的执行引擎,保障在 OLAP 分析场景中提供极速查询体验。
  • 对上层应用提供 MySQL 连接协议,可以用 MySQL 客户端轻松连入进行开发和查询,和主流 BI 工具有很好的兼容性,也可以服务于 OLAP 报表和 API 封装。

3.StarRocks 擅长哪些场景

基于 StarRocks 的4种模型,可以提供明细查询和聚合查询,能够应对 OLAP 报表的上卷和下钻,比如在广告主报表场景应对高并发点查询。

StarRocks 基于 Roaring Bitmap 提供了 Bitmap 数据结构,并配套有集合计算函数,可以用于精确去重计算和用户画像的客群圈选业务。在实时方面,StarRocks可以用于支撑实时大屏看板、实时数仓,秒级延迟的呈现业务原貌和数仓指标。

最后,基于 CBO 优化器,StarRorcks 在 OLAP 场景下有很好的多表关联、子查询嵌套等复杂查询的性能,可以用于自助BI平台、自助指标平台和即席数据探查等自助分析场景。

StarRocks 能够用于构建实时数仓,得益于他的三种实时数据摄入能力:

  • 可以直接消费 Kafka 的消息。
  • 可以借助 Flink-connecor 实现 Exactly-once 语义的流式数据摄入。
  • 另外,结合 Flink-CDC 和 PrimaryKey 模型,可以实现从 TP 库 Binlog 实时同步 Upsert 和 Delete 等操作,更好的服务于 ODS 层业务库还原。

利用 Flink-Connector-StarRocks 插件,可以实现从 TP 库  Binlog 实时同步 Upsert 和 Delete 等操作,更好的服务于 ODS 层业务库还原。配套的 SMT(StarRocks Migration Tool)工具,可以自动映射 Flink 中的 TP库 Source 和 StarRocks 库的 Sink 建表语句,使得基于 FlinkSQL 的开发工作变得简单便捷。

另外,Flink-Connector 更重要的功能是提供了通用 Sink 能力,开发者把依赖加入后,无论是工程编码还是 FlinkSQL 都可以轻松 Add Sink,保障数据秒级导入时效性。

结合 Flink 的 Checkpoint 机制和 StarRocks 的导入事务标签,还可以保障不丢不重的精准一次导入。

StarRocks 的实时物化视图构建能力,结合 Flink-Connector 的持续增量数据导入,可以在流量类指标计算的建模中,实现 DWD 明细数据导入完成的同时,DWS 聚合指标也同步增量构建完成,极大提升聚合指标产出效率,缩短分层 ETL 的旅程。

StarRocks 提供的 Replace_if_not_null 能力比较有意思,正如语义所述,只要插入的数据不是 null,那么就可以去替换数据。

如图所示,右侧是个建表示例,里面维度列为日期和 Uid,其余3列中 SRC 表示数据源,另外带了 v1,v2两个 Metric;

通过2个 Insert 语句我们可以看到,来自2个 Kafka 主题的数据源的数据,轻松的实现了同时写入一张表的不同列。因此,这个功能提供了两种实时数仓能力:

1) Join on Load,也就是在导入的过程中,基于 StarRocks 来实现流式 Join。

2) 部分列更新能力。

StarRocks 为了支持更好的 Upsert/Delete,提供了 PrimaryKey 表模型。

如上图所示,最左侧是经典的 LSM 模型,也就是 Merge-on-Read 的形式。这种模型写入时不用去判断既有键位,对写友好,但读取时需要 Merge 合并,所以对读取数据不友好。

而最右侧是 Copy-on-Write 的模型,典型的产品就是 DeltaLake。这种模型和 LSM 正好相反,有比较好的读效率,但是对于写入不是很友好。

比较平衡读取和写入的,就是上图中间的两种 Record 级别冲突检查的模型,Kudu 的 Write Delta和StarRocks 的 Delete+Insert 模型。

由于维护了内存表,PrimaryKey 模型更适合冷热特征明显的场合,对热数据频繁的更新和删除更友好;

另外非常适合 PrimaryKey 较少的表(如用户画像的宽表),虽然列很多,但是主键其实只有 UUID 这种字段。

StarRocks 早期的 Unique 模型就是采用了最左边的 LSM 模型,因此查询效率较差,并且对于 Delete 不友好,结合 Flink 开发应用时,只能使用 Append 流进行 Sink。

StarRocks 2.0 版本中新增加的 PrimaryKey 模型,提供了软删除字段,通过在内存中维护最新数据,使得查询时避免了 Merge 的过程,从而极大提升了查询性能,并且既可以使用 Append 流也可以使用 Retract 流进行 Sink,丰富了与 Flink 结合时的应用场景。

 

4.构建实时数仓的具体方法

众所周知,在按照逻辑分层自下而上的构建实时数仓时,多流 Join 是有一定的技术门槛的。传统的实时计算引擎如  Storm、Spark Streaming 在这方面做的都不是很好。而Flink其实提供了很多通用的解决方法,如:

  • 基于 MapStat 做状态计算,或者 BroadcastStat 将维度缓存广播出去;
  • 用 Flink 关联外部热存储,如 HBase/Redis 等;
  • 一些相对稳定、更新频率低的维度数据或者码表数据,可以利用 RichFlatMapFunc 的Open方法,在启动时就全部加装到内存里;

不限于以上这些,其实 Flink 已经在维度扩展上,给了开发者很多可以落地的选择。然而有了 StarRocks,我们会有更多的想象空间。

比如利用前面介绍的 Replace_if_not_null 的能力,开发者可以实现多个数据源稀疏写入宽表的不同列,来实现 Join-on-Load 的效果。

另外 StarRocks 强悍的 CBO 优化器在多表关联查询能力方面也表现优异,如果数据量不大或者在查询并发不高的场景,甚至可以把 Join 的逻辑下推到 OLAP 层来做,这样可以释放掉 Flink 上的一些构建负荷,让 Flink 专注于清洗和稳定的数据导入,而多表关联和复杂查询等业务逻辑在 StarRocks 上进行。

不仅如此,还可以结合 Join-on-Load 和 Join on StarRocks 的两种形式,也就是稀疏写入有限张表,通过表之间做 Colocation join 策略,保证有限的表之间数据分布一致,做 Join 的时候没有节点间 Shuffle,在上层构建逻辑 View 面向查询。

 

双剑方案1. 微批调度

Flink 清洗导入 Kafka 的日志或者用 Flink-CDC-StarRocks 读取 MySQL Binlog 导入 StarRocks,ETL 过程中埋入批次处理时间,采用外围调度系统,基于批次处理时间筛选数据,做分钟级微批调度,向上构建逻辑分层。

这种方案的主要特点是:StarRocks 作为 ETL 的 Source 和 Sink,计算逻辑在 StarRocks 侧,适用于分钟级延迟,数据体量不大的场景。

 

双剑方案2. Flink 增量构建

实时消息流通过 Kafka 接⼊,采用 Flink 进⾏流式 ETL、多流 Join、增量聚合等,在内存中完成分层构建,然后将相应的数据,层对层的通过 Flink-connector 写出到 StarRocks 对应表内。各层按需面向下游提供 OLAP 查询能力。

该方案的主要特点是:计算逻辑在Flink侧,适用于需要前导做较重ETL的场景,StarRocks 不参与 ETL,只承载 OLAP 查询,应对较高 QPS 查询负荷。

 

双剑方案3. StarRocksView视图

Flink 清洗导入 Kafka 的日志或者用 Flink-CDC-StarRocks 工具读取 MySQL Binlog 导入 StarRocks;根据需要选用明细、聚合、更新、主键各种模型,只物理落地 ODS 和 DIM层,向上采用 View 视图;利用StarRocks 向量化极速查询和 CBO 优化器满足多表关联、嵌套子查询等复杂 SQL,查询时现场计算指标结果,保证指标上卷和下钻高度同源一致。

该方案主要特点是:计算逻辑在 StarRocks 侧(现场查询),适用于业务库高频数据更新的场景,实体数据只在 ODS 或 DWD 存储 (未来 StarRocks 提供多表 Materialized Views,将会进一步提升查询性能)。

 

5.最佳实践案例

前面我们介绍了一些联合 Flink 和 StarRocks 构建实时数仓的几种方法论,下面我们来看4个实际的客户案例。

汽车之家目前在智能推荐的效果分析、物料点击、曝光、计算点击率、流量宽表等场景,对实时分析的需求日益强烈。经过多轮的探索,最终选定 StarRocks 作为实时 OLAP 分析引擎,实现了对数据的秒级实时分析。

在数据处理流程上,SQLServer、MySQL、TiDB 等数据源,通过 CDC 打入多个 Topic主题,用 FlinkSQL 进行 ETL 清洗和聚合计算,然后通过 Flink-Connector 导入 StarRocks。早期选择的 Unique 表模型,由于业务有很多 Delete 操作,而 Merge-on-Read 的模型对Delete 支持不好,如果只做Update 而不做 Delete,会造成结果数据比业务库多的问题。

最新的 PrimaryKey 模型支持了OP 字段(更新/删除操作),改为 PrimaryKey 模型后,数据结果与上游业务完全一致。

上图右侧是在硬件配置 6x 48c 256G、数据量 3500W+、有持续写入情况下,22 个 SQL 用例的测试情况,查询性能也比 Unique 模型有大幅提升。

在合理的选型和建模之后,汽车之家在实时平台 IDE上也做了很多工作,开发运维人员可以在页面里进行 DDL 建表,FlinkSQL 开发,作业的起停、上线管理等工作。结合 Flink-Connecotor,可以直接通过FlinkSQL 将加工后的数据导入 StarRocks,完成端到端的实时平台集成。

另外,利用 StarRocks 提供的 200 多个监控 Metric,汽车之家用 Prometheus 和 Grafana 等组件做了充分的可视化监控,即时查看集群的统计指标,把握集群的健康状态。

第2个案例,顺丰科技的运单分析场景实践。在2021年双11大促活动中,运单分析场景应对了15w TPS 消息体量的实时数据导入和更新。整体的处理流程如图所示,多个业务系统中的数据源打到几个 Source Kafka,用 Flink 来对数据进行加工、字段补充、重新组织,然后整理后的数据打到若干个 Sink Kafka 主题,最后利用前面介绍的 Join-on-Load 的形式,将多个数据源的数据,稀疏的写入宽表的不同列,以此来实现宽表拼齐的过程。

在具体使用上,顺丰科技将运单的数据根据更新的频度,划分为了2张宽表,按照相同的数据分布做成 Colocation 组,保证 Join 的时候没有额外的节点 Shuffle。一张表涉及的更新较少,命名为公表。另一张表涉及的更新较多,命名为私表。

每个子表都利用了 Replace_if_not_null 的部分列更新的能力,合理的设计了维度和聚合指标,并引入了 Bloom Filter 索引加速筛选的效率,用日期做范围分区,用订单号做数据分布,配置了动态分区,自动淘汰冷数据。对外通过逻辑 View 的形式关联成一张宽表,底层是以现场 Join 的形式,整体面向业务提供查询服务。

第3个案例是来自多点 DMALL 的实时数仓实践。实时更新场景主要对实时监控经营的各项指标进行分析,如当前时间段内的 GMV 、下单数量、妥投数量、指标达成、对比、环比等指标分析,为客户的经营决策提供更具时效性的参考依据。

早期,针对数据为实时(秒级)更新的场景,主要使用 Impala on Kudu 引擎,采用 Lambda 架构,基于相同的主键,将流式的预计算的结果数据、批计算的结果数据,基于相同的主键进行 Merge。

这个 Case 早期的架构如左图所示,ODS、DWD、DWS等分层在Kafka里承载,ADS层 在 Kudu/MySQL里,维表放在 HBase 里,采用 Flink 查询外表热存储的形式实现维度数据和事实消息的关联。如右图所示,经过梳理和改造,顺丰科技将 DWD 到 DWS 的聚合处理从 Flink 下沉到 OLAP 层,用 StarRocks 替换了Kudu,简化了预聚合链路,提升了开发效率。

第4个案例是来自一个某车联网企业的 Fusion 数仓建设。随着新能源汽车的普及,车联网 IOT 数据的实时接入分析的需求也越来越多。

业务逻辑如左图所示,传感器上报的仪表、空调、发动机、整车控制器、电池电压、电池温度等1000+传感器 Metric 要通过 Flink 做实时 ETL 清洗,同时要完成功能主题实时分拣、数据质量实时报告,最终满足于时序数据综合分析和可视化展示。技术上,大量采用 Flink.Jar 的工程代码开发,对于某些码值还涉及到 Flink 多流 Join 及状态计算。流量类的主题,采用 StarRocks 的增量聚合模型出聚合指标。也利用 FlinkSQL 对于运营分析类业务进行了实时数仓构建,将 ADS 层结果导入 StarRocks 供统一接口查询。

整体上也是按照 Lambda 模型设计的,FLink 清洗整合后的合规数据,会通过落盘程序沉降到 HDFS,用于持久存储、离线数仓进行跑批及更复杂的模型训练,最终 Hive 的结果数据也会送到 StarRocks 供接口查询使用。

数据逻辑设计如右图所示,上面为离线数仓,下面为实时数仓逻辑分层。

可以看到实时清洗后的 DWD 层数据会成为离线数仓的 ODS 层,而离线数仓构建好的一些相对固定的维表数据,也会用于实时数仓的流式维度扩展。实时数仓的逻辑分层相较于离线数仓更为简约,DWD明细层会存在于独立的 Kafka 或者在 Flink 内存中,DWS 层在 FlinkSQL 聚合完成后就直接下沉到 StarRocks了。

这里其实是进行了两次聚合,在 Flink 里进行了秒级的聚合,而 StarRocks 里的时间信息相关的维度列是到分钟或者15分钟的,利用 StarRocks 的聚合模型,将 Flink 汇聚的5-10s的聚合结果,再次汇聚到分钟级键位。这样设计有两个好处,第一,能够减少 LSM 模型的 Version版本,提升查询性能;第二,抽稀到分钟级后,更便于可视化展示,降低了前端取数的压力。

 

6.实时即未来, StarRocks 后续规划

关于 PrimaryKey 模型,后续版本即将支持部分列更新,进一步丰富 TP 业务库还原的能力;并在 PrimaryKey 模型上支持 Bloom Filter、Bitmap 等索引能力,进一步提升数据查询性能。

资源隔离方面,后续 StarRocks 会发布自适应内存、CPU 分配能力,客户不再需要手动调整配置参数;未来也会支持多租户资源隔离的 Feature。

对于 Apache Flink 项目的贡献方面,当前 Flink-Connector-StarRocks 还只具备 Sink 能力,后续会在Source 方面提供支撑,届时用户可以通过 Flink 分布式读取 StarRocks 数据,用 FlinkSQL 做跑批任务。

另外,在 CDC 适配上,后续也会提供 Oracle/PostgreSQL 等更丰富的 TP 库的 DDL 自动映射能力,适应更多 CDC 应用。

在云原生时代,StarRocks 已经开始了积极探索和实践,很快就会提供存储计算分离、异地容灾等能力,为客户提供弹性、可靠的 OLAP 层查询分析体验。


 

以上就是本次分享的全部内容。实时即未来,欢迎大家一起加入到 Apache Flink 和 StarRocks 社区建设,共同探索出更多实时数仓的最佳实践。