Beam - Execution Engine
Pipeline
读取输入数据到 PCollection
对读进来的 PCollection 进行 Transform,得到另一个 PCollection
输出结果 PCollection
1234567891011121314// Start by defining the options for the pipeline.PipelineOptions options = PipelineOptionsFactory.create();// Then create the pipeline.Pipeline pipeline = Pipeline.create(options);PCollection<String> lines = pipeline.apply( "ReadLines", TextIO.read().from("gs://some/inputData.txt"));PCollection<String> filteredLines = lines.apply(new FilterLines());filteredLi ...
Beam - Pipeline Test
Context
设计好的 Pipeline 通常需要放在分布式环境下执行,具体每一步的 Transform 都会被分配到任意机器上执行
如果 Pipeline 运行出错,则需要定位到具体机器,再到上面去做调试是不现实的
另一种办法,读取一些样本数据集,再运行整个 Pipeline 去验证哪一步逻辑出错 - 费时费力
正式将 Pipeline 放在分布式环境上运行之前,需要先完整地测试整个 Pipeline 逻辑
Solution
Beam 提供了一套完整的测试 SDK
可以在开发 Pipeline 的同时,能够实现对一个 Transform 逻辑的单元测试
也可以对整个 Pipeline 的 End-to-End 测试
在 Beam 所支持的各种 Runners 中,有一个 DirectRunner
DirectRunner 即本地机器,整个 Pipeline 会放在本地机器上运行
DoFnTester - 让用户传入一个自定义函数来进行测试 - UDF - User Defined Function
DoFnTester 接收的对象是用户继承实现的 DoFn
不应该将 DoFn 当成一个单 ...
Beam - Pattern
Copier Pattern
每个数据处理模块的输入都是相同的,并且每个数据处理模块都可以单独并且同步地运行处理
1234567891011121314151617181920212223242526272829303132333435363738394041PCollection<Video> videoDataCollection = ...;// 生成高画质视频PCollection<Video> highResolutionVideoCollection = videoDataCollection.apply("highResolutionTransform", ParDo.of(new DoFn<Video, Video>(){ @ProcessElement public void processElement(ProcessContext c) { c.output(generateHighResolution(c.element())); }}));// 生成低画质视频PCo ...
Beam - Pipeline IO
读取数据集
一个输入数据集的读取通常是通过 Read Transform 来完成
Read Transform 从外部源读取数据 - 本地文件、数据库、OSS、MQ
Read Transform 返回一个 PCollection,该 PCollection 可以作为一个输入数据集,应用在各种 Transform 上
Pipeline 没有限制调用 Read Transform 的时机
可以在 Pipeline 最开始的时候调用
也可以在经过 N 个步骤的 Transforms 后再调用它来读取另外的数据集
本地文件
1PCollection<String> inputs = p.apply(TextIO.read().from(filepath));
Beam 支持从多个文件路径中读取数据集,文件名匹配规则与 Linux glob 一样
glob 操作符的匹配规则最终要和所使用的底层文件系统挂钩
从不同的外部源读取同一类型的数据来统一作为输入数据集 - 利用 flatten 操作将数据集合并
12345PCollection<String> input1 = p ...
Beam - Pipeline
创建
在 Beam 中,所有的数据处理逻辑都会被抽象成 Pipeline 来运行
Pipeline 是对数据处理逻辑的一个封装
包括一整套流程 - 读取数据集、将数据集转换成想要的结果、输出结果数据集
创建 Pipeline
12PipelineOptions options = PipelineOptionsFactory.create();Pipeline p = Pipeline.create(options);
应用
PCollection 具有不可变性
一个 PCollection 一旦生成,就不能在增加或者删除里面的元素了
在 Beam 中,每次 PCollection 经过一个 Transform 之后,Pipeline 都会创建一个新的 PCollection
新创建的 PCollection 又成为下一个 Transform 的输入
原先的 PCollection 不会有任何改变
对同一个 PCollection 可以应用多种不同的 Transform
处理模型
Pipeline 的底层思想依然是 MapReduce
在分布式环境下,整个 Pipeline 会启 ...
Beam - Transform
DAG
Transform 是 Beam 中数据处理的最基本单元
Beam 把数据转换抽象成有向图
反直觉 - PCollection 是有向图中的边,而 Transform 是有向图中的节点
区分节点和边的关键是看一个 Transform 是不是有一个多余的输入和输出
每个 Transform 都可能有大于一个的输入 PCollection,也可能输出大于一个的输出 PCollection
Apply
Beam 中的 PCollection 有一个抽象的成员函数 Apply,使用任何一个 Transform 时,都需要调用 Apply
123final_collection = input_collection.apply(Transform1).apply(Transform2).apply(Transform3)
Transform概述
ParDo - Parallel Do - 表达的是很通用的并行处理数据操作
GroupByKey - 把一个 Key/Value 的数据集按照 Key 归并
可以用 ParDo 实现 GroupByKey
简单实现 - 放一个全 ...
Beam - PCollection
数据抽象
Spark RDD
不同的技术系统有不同的数据结构, 如在 C++ 中有 vector、unordered_map
几乎所有的 Beam 数据都能表达为 PCollection
PCollection - Parallel Collection - 可并行计算的数据集,与 Spark RDD 非常类似
在一个分布式计算系统中,需要为用户隐藏实现细节,包括数据是怎样表达和存储的
数据可能来自于内存的数据,也可能来自于外部文件,或者来自于 MySQL 数据库
如果没有一个统一的数据抽象的话,开发者需要不停地修改代码,无法专注于业务逻辑
Coder
将数据类型进行序列化和反序列化,便于在网络上传输
需要为 PCollection 的元素编写 Coder
Coder 的作用与 Beam 的本质紧密相关
计算流程最终会运行在一个分布式系统
所有的数据都可能在网络上的计算机之间相互传递
Coder 就是告诉 Beam 如何将数据类型进行序列化和反序列化,以便于在网络上传输
Coder 需要注册进全局的 CoderRegistry
为自定义的数据类型建立与 Coder 的对应关系,无需每次 ...
Beam - Paradigm
Why
Apache Beam 本身并不是一个数据处理平台,本身也无法对数据进行处理
Apache Beam 所提供的是一个统一的编程模型思想
通过 Apache Beam 统一的 API 来编写处理逻辑,该处理逻辑会被转化为底层运行引擎相应的 API 去运行
SDK 会变,但背后的设计原理却不会改变
生态
Layer
Desc
Runner
现有的各种大数据处理平台,如 Apache Spark、Apache Flink
可移植的统一模型层
各个 Runner 将会依据中间抽象出来的模型思想Runner 将提供一套符合该模型的 APIs 出来,以供上层转换
SDK
提供不同语言版本的 API 来编写数据处理逻辑这些数据处理逻辑会被转换成 Runner 中相应的 API 来运行
基本概念
数据可以分成有界数据和无界数据
其中有界数据是无界数据的特例,可以将所有的数据抽象看作无界数据
每个数据都有两个时域,即事件时间和处理时间
处理无界数据时,数据会有延迟、丢失的情况
因此,无法保证是否接收完了所有发生在某一时刻之前的数据 - 事件时间
流处理必须在数据的完整性和数据处理的 ...
Beam - Context
MapReduce架构思想
提供一套简洁的 API 来表达工程师数据处理的逻辑
在这套 API 底层嵌套一套扩展性很强的容错系统
计算模型
Map
计算模型从输入源中读取数据集合
这些数据经过用户所写的逻辑后生成一个临时的键值对数据集
MapReduce 计算模型会将拥有相同键的数据集集中起来发送到下一阶段,即 Shuffle 阶段
Reduce
接收从 Shuffle 阶段发送过来的数据集
在经过用户所写的逻辑后生成零个或多个结果
划时代意义
Map 和 Reduce 这两种抽象,其实可以适用于非常多的应用场景
MapReduce 的容错系统,可以让数据处理逻辑在分布式环境下有很好的扩展性(Scalability)
不足
使用 MapReduce 来解决一个工程问题,往往会涉及非常多的步骤
每次使用 MapReduce 时,都需要在分布式环境中启动机器来完成 Map 和 Reduce 步骤
并且需要启动 Master 机器来协调两个步骤的中间结果,存在不少的硬件资源开销
FlumeJava
将所有的数据都抽象成名为 PCollection 的数据结构
无论是从内存中读取的数据,还是在 ...
Big Data - Spark + Flink
Spark 实时性
无论是 Spark Streaming 还是 Structured Streaming,Spark 流处理的实时性还不够
无法应对实时性要求很高的流处理场景
Spark 的流处理是基于微批处理的思想
把流处理看做批处理的一种特殊形式,没接收到一个时间间隔的数据才会去处理
虽然在 Spark 2.3 中提出连续处理模型,但只支持有限的功能,并不能在大项目中使用
要在流处理的实时性提升,就不能继续用微批处理的模式,而是有数据数据就立即处理,不做等待
Apache Flink 采用了基于操作符(Operator)的连续流模型,可以做到微秒级别的延迟
Flink模型
Flink 中最核心的数据结构是 Stream,代表一个运行在多个分区上的并行流
在 Stream 上可以进行各种转换(Transformation)操作
与 Spark RDD 不同的是,Stream 代表一个数据流而不是静态数据的集合
Stream 所包含的数据随着时间增长而变化的
而且 Stream 上的转换操作都是逐条进行的 - 每当有新数据进入,整个流程都会被执行并更新结果
Flink 比 Spark St ...