共计 10254 个字符,预计需要花费 26 分钟才能阅读完成。
摘要:本文整顿自 SelectDB 资深大数据研发专家王磊,在 FFA 2022 实时湖仓专场的分享。本篇内容次要分为四个局部:
- 实时数仓需要和挑战
- 基于 Apache Doris 和 Apache Flink 构建实时数仓
- 用户案例与最佳实际分享
- 新版本个性
点击查看直播回放和演讲 PPT
一、实时数仓需要和挑战
在数据流的角度上,剖析一下传统的数据架构。从图中能够看到,数据分为实时数据流和离线数据流。
在实时数据局部,通过 Binlog 的形式,将业务数据库中的数据变更,采集到实时数仓。同时,通过 Flume-Kafka-Sink 对进行实时采集。当数据源上不同起源的数据都采集到实时数仓后,便能够构建实时数仓。在实时数仓构建的外部,咱们依然会恪守数仓分层实践,将数据分为 ODS 层、DWD 层、DWS 层、ADS 层。
在离线数据流局部,通过 DataX 定时同步的形式,采集业务库 RDS 中的一些数据。当不同起源的数据,进入到离线数仓后,便能够在离线数仓外部,依赖 Spark SQL 或 Hive SQL,对数据进行定时解决。
而后,拆散出不同维度(ODS、DWD、ADS 等)的数据,并将这些数据存在一个存储介质上。咱们个别会存在 HDFS 或 S3 的对象存储上。通过这样的形式,咱们的离线数仓便构建起来了。与此同时,为了保障数据的一致性。咱们须要一个数据荡涤工作。应用离线数据对实时数据进行荡涤,保障数据最终的一致性。
如上图所示,咱们在技术架构的角度,对传统数据架构进行剖析。从图中能够看到,不同利用采取不同技术栈。比方在湖仓局部是 Hive、Iceberg、Hudi 等组件。在湖仓之上的 Ad-hoc,咱们抉择 Impala 或 Kudu。对于 OLAP 的高并发,咱们会应用 Druid 或 Kylin 组件。
除此之外,业务还有半结构化的需要。咱们会应用 ES 对日志进行检索和剖析;应用 HBase 构建高效的点查服务。在局部状况下,业务须要对外提供对立的数据服务。这时,局部业务会应用 Presto 或 Trino 的查问网关,对立对用户提供服务。
这个架构有什么问题呢?首先,架构组件多,保护简单。其次,它的计算、存储和研发老本都比拟高。次要因为咱们同时保护两套数据和两套计算,即实时数据流和实时计算工作。最初,咱们无奈保障实时流的数据和离线数据的一致性。此时,只能通过离线数据定时荡涤,保证数据的一致性。
基于以上痛点,一个“对立的实时”架构跃然纸上。“对立”是指数据结构的对立,咱们心愿半结构化和结构化数据可能对立存储在一起。同时也指的是在一个平台中能实现多种剖析和计算场合(实时查问,交互式剖析,批量解决等)“实时”指的是咱们心愿数据的接入和数据分析都能实时的进行。
二、基于 Apache Doris 和 Apache Flink 构建实时数仓
基于以上需要,如何通过 Apache Doris 和 Apache Flink 构建实时数仓?满足用户对实时利用和对立架构的需要。
首先,介绍一下什么是 Apache Doris?Apache Doris 是基于 MPP 架构的高性能的实时剖析型数据库。它以极速易用的特点被人们所熟知,Doris 只需亚秒就能实现海量数据(TB 级别或者百亿级别数据)的查问。不仅反对高并发(点查、ad-hoc)的查场景,也反对高吞吐量(ETL 工作)的查问场景。
因而,Apache Doris 能较好的满足高并发报表、即席查问、对立数仓服务、以及湖仓和联邦查问等性能。用户在此之上,能够构建用户行为剖析、AB 试验、日志检索剖析、用户画像剖析等利用。
从下图中咱们能够看到,数据源通过各种数据集成和加工后,通常会入库到实时数仓 Doris 之中。同时,局部数据会入到湖仓架构的 Hive 或 Iceberg 中。而后,基于 Doris 构建一个对立的数仓,对外提供服务。
接下来,看一下如何基于 Apache Doris 构建极速易用的实时数仓的架构?因为 Doris 既能够承载数据仓库的服务,也能够承载 OLAP 等多种利用场景。
因而,它的实时数仓架构变得非常简单。咱们只须要通过 Flink CDC 将 RDS 的数据,实时同步到 Doris。通过 routine load 将 Kafka 等音讯零碎中的数据,实时同步到 Doris。在 Doris 外部,基于 Doris 不同的表模型、Rollup、以及物化视图的能力,构建实时数仓。
Doris 的表模型分为明细模型、主键模型和统计模型。在 Doris 外部构建实时数仓时,ODS 层通常会应用明细模型构建。DWD 层通过 SQL 调度工作,对 ODS 数据抽取并获取。DWS 和 ADS 层则能够通过 Rollup 和物化视图的技术手段构建。
除此之外,Doris 还反对基于 Iceberg、Delta Lake 和 Hudi 的数据湖服务,提供一些联邦剖析和湖仓减速的能力。这样咱们便实现了基于 Doris 构建一个实时数仓。在实时数仓之上,咱们能够构建 BI 服务、Adhoc 查问、多维分析等利用。
架构明确之后,咱们看一下在实际过程中会有哪些挑战?首先,大家最关怀的问题就是数据的一致性保障。
数据一致性个别分为“最多一次”、“至多一次”和“准确一次”。
- 最多一次是指,发送方仅发送音讯,而不期待任何回复。在这种模型中,数据的生产和生产过程,都可能呈现数据失落。
- 至多一次是指,发送方一直重试,直到对方收到为止。在这个模型中,生产和生产过程都可能呈现数据反复。
- 准确一次可能保障音讯,只被严格发送一次,并且只被严格解决一次。这种数据模型,可能严格保证数据生产和生产过程中的精确一致性。Doris 基于两阶段提交,实现精确的数据一致性。
Flink CDC 通过 Flink Checkpoint 机制联合 Doris 两阶段提交,实现端到端的数据写入一致性。具体过程分为四步。
第一步,事务开启(Flink Job 启动和 Doris 事务开启):当 Flink 工作启动后,Doris 的 sink 会发动一个 precommit 申请,开启一个写入事务。
第二步,数据传输(Flink Job 的运行和数据的传输):在 Flink Job 运行过程中,Doris sink 会一直从上游算子获取数据,并通过 httpchunked 的形式,继续将数据传输到 Doris。
第三步,事务预提交:当 Flink 开始进行 Checkpoint 时,Flink 会发动一个 Checkpoint 申请。此时,Flink 的各个算子会进行 Barrier 对齐和快照保留。Doris Sink 会收回进行 Stream Load 写入的申请,并发动一个事务提交申请到 Doris。
此时,这批数据曾经齐全写入 Doris BE 中,BE 还没有进行数据公布。因而,写入 BE 的数据对用户来说是不可见的。
第四步,事务提交。当 Flink 的 Checkpoint 实现之后,它会告诉各个算子。此时,Doris 会发动一次事务提交到 Doris BE。BE 会对此次写入的数据,进行公布。最终实现数据流的写入。
综上所述,是 Flink CDC 联合 Doris 两阶段事务,实现数据一致性提交的过程。这里有一个问题是,当预提交胜利,但 Flink Checkpoint 失败时,该怎么办?这时 Doris 并没有收到事务最终的提交申请,Doris 外部会对写入数据进行回滚(rollback),从而保证数据最终的一致性。
上面来看一下数据增量和全量的同步。如何基于 Flink CDC 实现全量和增量的数据同步?
这个原理很简略,因为 Flink CDC 实现了基于 Snapshot 的全量数据同步,以及基于 BinLog 实时增量的数据同步。与此同时全量数据同步和增量数据同步能够主动切换。因而。在数据迁徙的过程中,用户只须要配置好同步的表即可。当 Flink 工作启动时,首先会进行历史表的数据同步。同步实现之后,它会主动切换成实时同步。
实现实时数据同步之后,用户又产生了 RDS Schema 的变更需要。因为随着业务的倒退,RDS 表构造会产生变更,用户心愿 Flink CDC 岂但可能将数据变动同步到 Doris,也心愿将 RDS 表构造的变更也同步到 Doris。这样的话,用户不必放心 RDS 的表构造和 Doris 表构造不统一的问题。
要满足这种 DDL 同步的需要,前提是 Doris 可能疾速反对这种 Schema 的变更。当很多 Schema Change 申请到来后 Doris 可能疾速解决。因为 Doris 解决 Schema Change 时,绝对比拟耗时,所以咱们引入了 Light Schema Change。
Light Schema Change 的实现原理非常简单,咱们只须要在加减列时,对 FE 中的元数据进行批改,将批改后的数据长久化。Schema Change 只须要更新 FE 中的元数据即可,因而 Schema Change 的效率就十分高。
与此同时,这个响应过程是同步的过程。因为 Light Schema Change 只批改了 FE 的元数据,并没有同步给 BE。因而,会产生 BE 和 FE Schema 不统一的问题。
为了解决这种问题,咱们对 BE 的写出流程进行了批改,具体蕴含三个方面。
- 数据写入:对于数据写入而言,FE 会将 Schema 长久化到元数据中。当 FE 发动导入工作时,会把最新的 Schema 一起发给 Doris BE,BE 会依据最新的 Schema 对数据进行写入,并与 RowSet 进行绑定。将该 Schema 长久化到 RowSet 的元数据中,实现了数据的各自解析。解决了写入过程中 Schema 不统一的问题。
- 数据读取:对于数据读取而言,FE 生成查问打算时,会把最新的 Schema 附在其中,并一起发送给 BE。BE 会拿到最新的 Schema,对数据进行读取,来解决读取过程中 Schema 产生不统一的问题。
- 数据 Compaction:对于数据的 Compaction 而言,当数据进行 Compaction 时,咱们选取须要进行 Compaction 的 RowSet 中最新的 Schema,作为之后 RowSet 对应的 Schema。以此解决不同 Schema 上,RowSet 的合并问题。
通过 Light Schema Change 优化之后,Doris Schema Change 的性能,从之前一个 Schema 变动 310 毫秒,升高到了 7 毫秒。整体性能有近百倍的晋升。彻底的解决了,海量数据的 Schema Change 变动难的问题。
有了 Light Schema Change 的保障,Flink CDC 可能同时反对 DML 和 DDL 的数据同步。那么在 Flink CDC 中,咱们是如何实现的呢?
- 首先,咱们要在 Flink CDC 的 MySQL Source 侧开启同步 MySQL DDL 的变更配置。而后,咱们须要在 Doris 侧辨认 DDL 的数据变更,并对其进行解析。
- 当 Doris Sink 发现 DDL 语句后,Doris Sink 会对这种表构造进行验证,验证表构造是否反对 Light Schema Change。当表构造验证通过后,Doris Sink 会发动 Schema Change 申请到 Doris,从而实现此次 Schema Change 的变动。
- 在具体应用过程中,Doris 如何开启 Light Schema Change 呢?咱们只须要在表里增加,”light_schema_change” = “true” 即可。当咱们解决了基于 Flink 和 Doris 数据同步过程中,源数据的一致性、全量数据和增量数据的同步、以及 DDL 数据的变更后,一个残缺的数据同步计划就实现了。
站在数据模型的角度,看一下如何基于 Flink 和 Doris,构建不同的数据模型。
第一种数据模型,也是最简略的数据模型。咱们将一个 RDS 的表,同步到一个 Doris 的表中。通过 MySQL-Source 加 Doris-Sink,实现表构造和数据的变更。
第二种数据模型,咱们能够将 MySQL 中两个表的数据同步到 Flink 后,在 Flink 外部进行多流 Join,实现数据打宽,生成一个大宽表数据,同步到 Doris 之上。
第三种数据模型,咱们能够对上游的 Kafka 数据进行荡涤,荡涤后通过 Doris-Sink 写入 Doris 表中。
第四种数据模型,咱们还能够将 MySQL 数据和 Kafka 数据,进行多流的 Join,而后写入 Doris。
第五种数据模型,咱们在 Doris 侧建一个基于 Unique Key 模型的宽表。而后,将上游 RDS 中的数据,依据 Key 应用 Doris 的多列更新模式,将多列数据分布写入到 Doris 的大宽表中。
例如,咱们首先将 MySQL 第一个表中的 status,同步到 Doris 中。其次,咱们将 MySQL 第二个表中的,amount 字段同步到 Doris 的同一个大宽表模型中。
除此之外,咱们还能够将多源的 RDS(MySQL、Oracle 等)数据同步到 Doris 后,在 Doris 外部应用宽表抽取的形式,构建一个大宽表。
对于大数据来说,高并发写入并不难,难点在于高并发更新。如何在上亿数据中疾速找到须要更新的数据,并对其进行更新?这始终是大数据畛域比拟难的问题。
为了解决这个问题,Doris 通过 MVCC 多版本并发机制来实现。特地是在 Unique Key 模型中,当咱们写入一个数据时,如果数据库中不存在数据,会写入一个版本。当咱们再次对该数据进行更新时,会再次写入一个版本。此时,数据变更在 Doris 以多个版本的模式存在。当用户在查问时,Doris 会将最新版本对应的数据返回给用户。并在 compaction 时,对历史变更的数据进行清理。这种设计解决了海量数据的更新问题。同时,Doris 反对 Merge On Read 和 Merge On Write 两种形式。
首先,讲一讲 Merge On Read,它的特点是写入速度十分快。无论是 insert 语句,还是 update 语句,对于 Doris 来说,都是以多版本的形式写入 Doris。因而,它的写入性能很高。其次,它的查问性能不是很高。因为在查问过程中,须要对 Key 进行聚合去重,而后再执行查问。因而,它的性能不是很高。
举例:
- 咱们在数据外面写入三条订单数据,数据是以 append 的模式写入 Doris 表中。
- 而后,咱们对订单 1 的 cost 进行更新,写入一个新的版本的数据。当咱们将订单 1 的 cost 批改为 30 时,数据通过 append 的模式,以新版本写入 Doris。
- 当咱们对订单 2 的数据进行删除时,依然通过 append 形式,将数据多版本的写入 Doris 并将__DORIS_DELETE_SIGN_字段变为 1,此时,示意这条数据被删除了。
当 Doris 读取数据时,发现最新版本的数据被标记删除,就会将该数据从查问后果中进行过滤。除此之外,Doris 还有一个__DORIS_SEQUENCE_COL__列,保障在高并发更新的状况下,更新数据的一致性和程序性。
上面看一下查问成果。当用户进行查问时,会进行两次聚合操作。第一次,应用多路归并排序,将反复的数据排列在一起,并应用高版本数据笼罩低版本数据的形式,对数据进行合并。
第二次,依照查问的聚合条件,对数据进行聚合。这样带来两个比较严重的查问性问题。第一,在多路归并的时候,它的代价较高,对 Key 进行比拟,十分耗费 CPU。第二,在数据读取的过程中,咱们无奈进行无效的数据裁剪,会引入大量的 IO 操作。
上面来看一下 Merge On Write 如何实现高并发写入以及查问的性能问题。Merge On Write 兼容查问性能和写入性能。
Merge On Write 在写入的过程中,引入了 Delete Bitmap 数据结构,Doris 应用 Delete Bitmap 标记 RowSet 中某一行是否被删除。这里应用了兼顾性能和存储空间的 Row Bitmap,将 Bitmap 中的 Mem Table 一起存储在 BE 中,每个 segment 会对应一个 Bitmap。
为了放弃 Unique Key 原有的语义,Delete Bitmap 也反对多版本。每次导入会产生该版本增量的 Bitmap。在查问时须要合并此前所有版本的 Delete Bitmap。
接下来,看一下基于 Delete Bitmap 的 Merge On Write 的写入流程。首先,DeltaWriter 会先将数据 flush 到磁盘。第二步,咱们会批量查看所有 Key。在点查过程中,会通过一个区间树,查找到对应的 RowSet。而后,在 RowSet 外部通过 BloomFilter 和 index 高效查问。当查问到 Key 对应的 RowSet 后,便会笼罩 RowSet Key 对应的 Bitmap。而后在 publish 阶段更新 Bitmap,从而保障批量点查 Key 和更新 Bitmap 期间不会有新的可见 RowSet,保障 Bitmap 在更新过程中数据的正确性。除此之外,如果某个 segment 没有被批改,则不会有对应版本的 Bitmap 记录。
上面看一下 Merge On Write 的查问流程。首先,当咱们查问某一版本数据时,Doris 会从 LRU Cache Delete Bitmap 中,查找该版本对应的缓存。如果缓存不存在,咱们再去 RowSet 中读取对应的 Bitmap。最初,咱们应用 Delete Bitmap,对 RowSet 中的数据进行过滤,将后果返回。
同时在这个阶段咱们还能够通过 Bloomfilter 和 Bitmap 的二级索引来进步查问的效率,查问过程中 Doris 会进行无效的谓词下推。因而,在 Merge On Write 中,大幅晋升了数据写入的查问的效率。
Doris 针对不同场景,提供了不同的数据模型,别离有明细数据模型、主键数据模型、聚合数据模型。其中,明细数据模型次要用来存储日志,数据来一条就存一条。主键数据模型指雷同的 Key 会进行笼罩,比方依据订单 ID,对订单状态进行更新。
在统计模型方面,咱们会将雷同 Key 的 Value 列进行统计合并计算。比拟典型的利用场景是报表统计和指标计算。比方依据门店 ID 和门店工夫,对销售额进行统计计算。
对于统计模型来说,数据会边入库边统计。对于用户查问来说,间接查问统计后的数据,让查问过程更高效。
物化视图的概念。物化视图指,依据预约义的 SQL 剖析语句执行预计算,并将计算结果物化,从而减速查问的一种伎俩。
对于 Doris 来说,物化视图次要用于聚合场景。除此之外,还能够用于聚合数据和明细数据的同时查问;以及匹配不同的前缀索引场景。
在物化视图应用方面,首先建设一个表,而后再建设一个物化视图。基于一张 Base 表,能够构建不同的物化视图基于不同的维度进行统计。当用户查问时,如果可能命中化识图,都会走物化视图;如果没有命中物化视图,会走 Base 表,从而实现高效查问。
对于数据更新来说,首先会更新 Base 表,而后更新物化视图。从而让 Doris 保障物化视图和 Base 表数据的齐全一致性。
接下来,看一下物化视图的智能路由抉择。Doris 通过物化视图减速查问,并且在查问过程中,主动进行路由抉择。在查问数据的过程中,如果数据在物化视图中存在,会间接走物化视图;如果在物化视图中不存在,才会走 Base 表。
与此同时,Doris 的智能存储和现代化计算能力,也能疾速实现数据查问。物化视图在智能路由的过程中,遵循最小匹配准则。只有查问的数据集比物化视图汇合小时,才可能走物化视图。
它的智能抉择过程包含最优抉择和查问改写两个局部。首先,咱们来看一下最优抉择。最优抉择包含两个局部,即过滤候选集和抉择最优。
在过滤候选集过程中,当一个 SQL 语句过去,通过 Where 条件进行判断。Where 条件里查问的是 advertiser=1。由此可见,物化视图和 Base 表都有这个字段,这时的候选集是物化视图和 Base 表。
咱们会判断 Group By 计算。Group By 字段是 advertiser 和 channel。这两个字段同时在物化视图和表中 Base。这时过滤的候选集依然是物化视图和 Base 表。接下来,咱们会过滤计算函数。比方在这里会执行 count(distinct user_id),而后对数据进行计算。因为 Count Distinct 的字段 user_id 在物化视图和 Base 表中都存在。因而过滤后果仍是物化视图加 Base 表。最初,进行最优抉择。通过一系列计算,咱们发现查问条件无论是 Where、Group By 还是 Agg function 关联的字段,在 Base 表和物化视图都存在。这时,咱们须要进行最优抉择。而后,Doris 通过计算发现 Base 表的数据远大于物化视图,即物化视图的数据更小。
由此可见,如果查问走物化视图,它的效率更高。最优的查问打算是物化视图。当咱们找到最优的查问打算,会进行子查问改写,将咱们的 Count Distinct 改写成 Bitmap。从而实现了物化视图的智能路由。实现智能路由之后,咱们会将 Doris 生成的查问 SQL 发送到 BE 进行分布式查问计算。
Doris 数据分为两级存储。第一个是分区,第二个是分桶。咱们能够依照天对数据在 Partition 级别进行分区。
接下来,咱们依照 set 级别进行分桶。将一个分区的数据,分到不同的桶里。当咱们在查问 set ID 时,就能够通过分区裁剪,疾速定位数据,实现高并发的查问。
除此之外,Doris 还有很多优化查问的伎俩。比方一些索引可能减速查问,前 36 位会走前缀索引。Zone Map 索引、Bloom Filter 索引都能能疾速实现数据的过滤计算。最初,Doris 外部在查问过程中,还做了各种各样的优化。
比方智能算子下推,抉择更适合的数据模型。与此同时,Doris 在 Join 方面也有很大的劣势,比方 Broadcast Join、Bucket Shuffle Join、Colocate、Shuffle Join,可能尽量减少 Join 过程中的数据 Shuffle。
三、用户案例与最佳实际分享
Doris 的利用场景次要利用在即时剖析 / 交互剖析、多维报表剖析,实时数仓、湖仓减速 & 联邦剖析的四大场景。在这四大场景上,咱们能够构建一些指标监控、高频发报表、自助 BI、行为剖析、AB Test 等各丰盛的数据利用。
这是一个典型的基于 Doris 构建实时数仓的案例。上层的数据源是 RDS 业务库,文件系统数据、埋点数据。当数据实时接入 Doris 后,它基于 Doris 构建了一个实时数仓。
在数据接入过程中通过 DataX 进行离线数据同步;通过 Flink CDC 进行实时数据同步。而后,在 Doris 外部构建不同的数据分层,比方 ODS 层、DWS 层、DWD 层的数据。最初,在下层构建不同的数据利用,比方自助报表、自助数据抽取、数据大屏。
除此之外,它联合了本人的利用平台,构建了数据开发与治理平台,实现了源数据管理、数据分析等操作。用户在应用 Doris 后,又带来什么益处呢?
首先,它的业务计算从之前的两小时,缩小到三分钟。全链路的更新报表从周级别,更新到十分钟级别。同时,Doris 基于高度兼容 MySQL,它的学习老本非常低。因而,报表签约工作是十分顺利的。
因为 Doris 的开发非常简单。开发周期从从周降落至天级。业务人员能疾速满足业务需要的变动。
某运营商的服务的架构是通过 Flink CDC 将 RDS 的数据同步到 Doris 中。而后,通过 routine load 将下层日志中的数据接入到 Kafka 之后,将 Kafka 数据同步到 Doris 之中。而后,在 Doris 外部构建实时数仓。在数据调度时,它通过开源 Doris,实现数据调度。应用 Prometheus+Grafana 进行数据监控。
它采纳 Flink+Doris 架构体系后,带来的益处是组件缩小,解决了多架构下的数据的冗余存储,服务器资源节俭了 30%,数据存储磁盘占用节俭了 60%,经营老本大幅升高。该案例每天在用户的业务场景上,反对数万次的用户的在线查问和剖析。
如上图所示,之前的架构是 Hadoop 数仓架构。因而它的组件比拟丰盛,有 RDS、HBase、Hive。除此之外,还有 Kafka 等技术栈。由此可见,它的技术栈非常复杂。
在应用 Doris 之后,它将 RDS 里的数据通过 Flink CDC,实时同步到 Doris 里,服务器资源老本失去了很大的升高。同时,也将数据的查问工夫从 Spark 的 2~5 小时,缩短到十分钟,查问效率也大大晋升。
在数据的同步过程中,它应用了 Flink CDC+MySQL,全量加增量的数据同步形式。与此同时,它还利用 Doris 的 Light Schema Change 个性,实时同步 Binlog 里的 DDL 表构造变更到 Doris,实现数据接入数仓零开发成本。
四、新版本个性
1.2 版本第一个新个性是减少了 Multi Catalog,用户能够无缝对接多种数据源。Doris 会主动进行 Schema 同步,它的性能是 Trino 的三倍。
除此之外,咱们在主键模型可实时更新,实时更新场景下查问性能 10 倍以上晋升。Light Schema Change 能将 DDL 数据更新,并将数据表构造的变更,拉近毫秒级别。在表面上,咱们开始反对 JDBC 表面,以及 Array 类型数据类型,New Decimal 等各种状况。
重点介绍一下,之前咱们反对 native UDF,大家的应用老本较高。当初,咱们会反对 Java UDF,用户能够疾速写一个 Java 类,就能够实现 Java UDF 的应用。
新版本相比在 1.1 之前的版本,有 3~5 倍的性能晋升。同时,咱们的性能也当先某业界标杆竞品两倍以上。上图是咱们在 SSB-FLAT 的性能测试后果。
点击查看直播回放和演讲 PPT
更多内容
流动举荐
阿里云基于 Apache Flink 构建的企业级产品 - 实时计算 Flink 版现开启流动:
99 元试用 实时计算 Flink 版(包年包月、10CU)即有机会取得 Flink 独家定制卫衣;另包 3 个月及以上还有 85 折优惠!
理解流动详情:https://www.aliyun.com/product/bigdata/sc