Beam - Pipeline IO
读取数据集
- 一个输入数据集的读取通常是通过 Read Transform 来完成
- Read Transform 从外部源读取数据 - 本地文件、数据库、OSS、MQ
- Read Transform 返回一个 PCollection,该 PCollection 可以作为一个输入数据集,应用在各种 Transform 上
- Pipeline 没有限制调用 Read Transform 的时机
- 可以在 Pipeline 最开始的时候调用
- 也可以在经过 N 个步骤的 Transforms 后再调用它来读取另外的数据集
本地文件
1 | PCollection<String> inputs = p.apply(TextIO.read().from(filepath)); |
- Beam 支持从多个文件路径中读取数据集,文件名匹配规则与 Linux glob 一样
- glob 操作符的匹配规则最终要和所使用的底层文件系统挂钩
从不同的外部源读取同一类型的数据来统一作为输入数据集 - 利用 flatten 操作将数据集合并
1 | PCollection<String> input1 = p.apply(TextIO.read().from(filepath1); |
输出数据集
- 将结果数据集输出到目的地址的操作可以通过 Write Transform 来完成
- Write Transform 会将结果数据集输出到外部源
- 主要 Read Transform 能够支持的外部源,Write Transform 都支持
- 在 Pipeline 中,Write Transform 可以在任意步骤将结果集输出
- 可以将多步骤的 Transform 中产生的任何中间结果输出
本地文件
1 | output.apply(TextIO.write().to(filepath/output).withSuffix(".csv")); |
- 当输出结果超过一定大小时,Beam 会将输出的结果分块并写入到 output00、output01 中
- 可以使用 withSuffix 来指定文件格式
IO 连接器
- 在 Beam 中,Read Transform 和 Write Transform 都是 IO Connector 的实现类
- Beam 原生支持的 IO Connector 已经能覆盖大部分应用场景
- 基于文件读取输出的 FileIO 和 TFRecordIO
- 基于流处理的 KafkaIO 和 PubsubIO
- 基于数据库的 JdbcIO 和 RedisIO
自定义
- 自定义的 IO Connector 不需要非常通用,满足业务需求即可
- 实现自定义的 IO Connector,主要是要实现 Read Transform 和 Write Transform 的操作
自定义读取操作
有界数据
- 用 ParDo 和 GroupByKey 来模拟读取数据的逻辑 - 官方推荐
- 将读操作看作是 ParDo 和 GroupByKey 的多步骤 Transforms
- 继承 BoundedSource 抽象类去实现一个子类来实现读取逻辑
无界数据
- 必须继承 UnboundedSource 抽象类实现一个子类去实现读取逻辑
Source
- 无论是 BoundedSource 抽象类还是 UnboundedSource 抽象类,都继承了 Source 抽象类
- 为了能够在分布式环境下处理数据,Source 抽象类必须是可序列化的 - Serializable
多文件路径
用户提供一个 glob 文件路径,从相应的存储系统中读取数据
- 获取文件路径 ParDo
- 从用户输入的 glob 文件路径中生成一个 PCollection 的中间结果
- PCollection 中的每个字符串都对应一个具体的文件路径
- 读取数据集 ParDo
- 从上一步得到的 PCollection,从每个具体的文件路径读取文件内容
- 生成一个总的 PCollection 保存所有数据
NoSQL
NoSQL 允许按照键范围来并行读取数据集
- 确定键范围 ParDo
- 从用户输入的读取数据的键值生成一个 PCollection,用于保存可以有效并行读取的键范围
- 读取数据集 ParDo
- 从给定 PCollection 的键范围,读取相应的数据,并生成一个总的 PCollection 来保存所有数据
SQL
- 从关系型数据库中查询结果通常都是通过一个 SQL Query 来读取数据 - 只需要一个 ParDo
- 在 ParDo 中建立与数据库的连接并执行 Query,将返回的结果保存在一个 PCollection 中
自定义写入操作
- 只需要一个 ParDo 里面调用相应文件系统的写操作 API 来完成数据集的输出
- 如果输出数据集要写入到文件 - Beam 提供基于文件操作的 FileBasedSink 抽象类 - TextSink
- 要自定义 FileBasedSink 类,必须实现 Serializable 接口,保证输出操作可以在分布式环境下运行
- 自定义的类必须具有不可变性 - Immutability
- 私有字段,必须被声明为 final
- 如果类变量需要被修改,每次修改前必须先进行深拷贝,保证原有的数据不可变
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.