利用 Apache Beam 和 Google Cloud Dataflow 进行大规模数据处理
在数据处理领域,当面对大规模数据时,传统的处理方式往往显得力不从心。Apache Beam 和 Google Cloud Dataflow 为我们提供了强大的解决方案。下面将详细介绍如何使用它们来处理大规模数据。
1. 什么是 Apache Beam
Apache Beam 是一个统一的编程模型,可用于构建数据处理管道。它支持多种执行引擎,允许开发者编写一次代码,然后在不同的分布式处理框架上运行。通过管道(pipelines)、PCollections 和转换(transforms)这三个基本概念,我们可以构建出强大的数据处理流程。
下面通过一个具体的例子来深入了解 Apache Beam。假设我们有一些文本数据,想要统计以字母 “a” 开头的单词数量。如果数据量较小,我们可以编写一个简单的脚本进行处理,但当数据量达到几百 GB 甚至更多时,传统方法就会变得非常耗时。这时,我们可以使用 Apache Beam 定义一个管道来完成这个任务,它可以将工作分布到多台计算机上,提高处理效率。
以下是一个简单的 Apache Beam 管道示例代码:
import re
import apache_beam as beam
with beam.Pipeline() as pipeline:
(pipeline
| beam.io.ReadFromText(input_file)
| 'Split' >> (beam.FlatMap(lambda x: re.findall(r'[A-Za-z\']+', x))
.with_output_types(unicode))
| 'Filter' >> beam.Filter(lambda x: x.lower().startswith('a'))
| 'Count' >> beam.combiners.Count.Globally()
| beam.io.WriteToText(output_file)
)
在这个代码中,我们首先创建了一个管道对象,然后从文本文件中读取数据。接着,使用
Split
转换将输入数据拆分成单词,使用
Filter
转换过滤掉不以 “a” 开头的单词,使用
Count
转换统计剩余单词的数量,最后将结果写入输出文件。
需要注意的是,上述代码中有一些变量(如
input_file
和
output_file
)未定义,不能直接运行。后续会给出完整的示例。
2. 什么是 Google Cloud Dataflow
Google Cloud Dataflow 是 Apache Beam 的一个完全托管的管道运行器。与其他运行器不同,使用 Cloud Dataflow 无需对底层资源进行初始设置。大多数其他系统需要先配置和管理机器,然后安装软件,最后才能提交管道进行执行。而 Cloud Dataflow 会自动处理这些工作,我们可以直接提交管道进行执行,无需额外的配置。
Cloud Dataflow 是 Google Cloud Platform 的一部分,它可以与其他 Google 云服务集成。例如,我们可以使用 Cloud Dataflow 执行管道,从 Cloud Storage 存储桶中读取数据,使用 Compute Engine 实例处理和转换数据,最后将输出写回到另一个 Cloud Storage 存储桶中。
3. 与 Cloud Dataflow 交互
在使用 Cloud Dataflow 之前,我们需要进行一些初始设置和配置。具体步骤如下:
1.
启用 Cloud Dataflow API
:
- 导航到 Cloud Console,在顶部的主搜索框中输入 “Dataflow API”。
- 搜索结果应该只有一个,点击它会进入一个带有 “Enable” 大按钮的页面。
- 点击该按钮,即可启用 API。
2.
安装 Apache Beam
:
使用
pip
安装 Apache Beam 并包含 Google Cloud Platform 扩展:
bash
$ pip install apache-beam[gcp]
这些扩展允许我们的代码直接与 GCP 服务交互,无需额外编写代码。
3.
获取凭证
:
使用
gcloud
命令行工具获取凭证,让代码能够访问 Cloud Dataflow 项目:
bash
$ gcloud auth application-default login
运行该命令后,会出现一个链接,点击它并在浏览器中使用 Google 账户进行身份验证。之后,命令会在后台下载凭证,代码会自动发现这些凭证。
4.
创建 Cloud Storage 存储桶
:
使用
gsutil
命令创建一个存储桶,用于存储输入、输出和临时数据:
bash
$ gsutil mb -l us gs://your-bucket-id-here
这个命令会创建一个使用多区域复制且位于美国的存储桶。
4. 创建管道
接下来,我们要创建一个完整的管道,以统计输入文本中以字母 “a” 开头的单词数量。以下是完整的代码:
import argparse
import re
import apache_beam as beam
from apache_beam.options import pipeline_options
PROJECT_ID = '<your-project-id-here>'
BUCKET = 'dataflow-bucket'
def get_pipeline_options(pipeline_args):
pipeline_args = ['--%s=%s' % (k, v) for (k, v) in {
'project': PROJECT_ID,
'job_name': 'dataflow-count',
'staging_location': 'gs://%s/dataflow-staging' % BUCKET,
'temp_location': 'gs://%s/dataflow-temp' % BUCKET,
}.items()] + pipeline_args
options = pipeline_options.PipelineOptions(pipeline_args)
options.view_as(pipeline_options.SetupOptions).save_main_session = True
return options
def main(argv=None):
parser = argparse.ArgumentParser()
parser.add_argument('--input', dest='input')
parser.add_argument('--output', dest='output',
default='gs://%s/dataflow-count' % BUCKET)
script_args, pipeline_args = parser.parse_known_args(argv)
pipeline_opts = get_pipeline_options(pipeline_args)
with beam.Pipeline(options=pipeline_opts) as pipeline:
(pipeline
| beam.io.ReadFromText(script_args.input)
| 'Split' >> (beam.FlatMap(lambda x: re.findall(r'[A-Za-z\']+', x))
.with_output_types(unicode))
| 'Filter' >> beam.Filter(lambda x: x.lower().startswith('a'))
| 'Count' >> beam.combiners.Count.Globally()
| beam.io.WriteToText(script_args.output)
)
if __name__ == '__main__':
main()
在这个代码中,我们定义了一些参数,如项目 ID 和存储桶名称。
get_pipeline_options
函数用于将命令行参数与默认参数组合,并转换为 Apache Beam 特定的管道选项。
main
函数负责解析命令行参数,创建管道并执行数据处理流程。
5. 本地执行管道
我们可以使用 Apache Beam 的
DirectRunner
在本地测试管道。首先,创建一个包含少量单词的文本文件,手动统计以 “a” 开头的单词数量,然后运行管道进行验证:
$ echo "You can avoid reality, but you cannot avoid the consequences of avoiding reality." > input.txt
$ python counter.py --input="input.txt" --output="output-" --runner=DirectRunner
查看输出文件,确认统计结果是否正确:
$ ls output-*
output--00000-of-00001
$ cat output--00000-of-00001
3
为了测试管道在处理大量数据时的性能,我们可以使用 Python 脚本生成一个更大的文件:
$ python -c "print (raw_input() + '\n') * 10**5" < input.txt > input-10e5.txt
$ wc -l input-10e5.txt
100001 input-10e5.txt
$ du -h input-10e5.txt
7.9M input-10e5.txt
再次运行管道:
$ python counter.py --input=input-10e5.txt --output=output-10e5- --runner=DirectRunner
$ cat output-10e5-*
300000
可以看到,管道能够正确处理大量数据。不过,处理更大的数据量可能会需要较长时间,因为在单台机器上处理大量数据的效率有限。
以下是整个流程的 mermaid 流程图:
graph LR
A[创建输入文件] --> B[本地执行管道测试小数据量]
B --> C[生成大数据量文件]
C --> D[本地执行管道测试大数据量]
通过以上步骤,我们了解了如何使用 Apache Beam 和 Google Cloud Dataflow 处理大规模数据。从定义管道到配置环境,再到本地测试,我们逐步掌握了使用这些工具的方法。在下一部分,我们将介绍如何使用 Cloud Dataflow 执行管道,进一步发挥其分布式处理的优势。
利用 Apache Beam 和 Google Cloud Dataflow 进行大规模数据处理
6. 使用 Cloud Dataflow 执行管道
由于前面已经完成了所有的设置工作,使用 Cloud Dataflow 执行管道就变得非常简单,只需更改运行器并更新输入和输出文件即可。具体操作步骤如下:
1.
上传文件到 Cloud Storage 存储桶
:
使用
gsutil
命令将本地文件上传到之前创建的存储桶中:
bash
$ gsutil -m cp input-10e5.txt gs://dataflow-bucket/input-10e5.txt
这里的
-m
标志表示使用多个并发连接上传文件,以提高上传速度。
2.
使用 Cloud Dataflow 运行管道
:
运行以下命令,指定输入文件、输出文件和运行器为
DataflowRunner
:
bash
$ python counter.py \
--input=gs://dataflow-bucket/input-10e5.txt \
--output=gs://dataflow-bucket/output-10e5- \
--runner=DataflowRunner
按下回车键后,Cloud Dataflow 会接受作业并启动资源进行计算。此时,你会看到一些日志输出,显示作业已提交。
**注意**:如果遇到无法识别 `gs://` 路径的错误(例如 `ValueError: Unable to get the Filesystem for path gs://…`),请确保安装了 Apache Beam 的 GCP 扩展,通常可以通过运行 `pip install apache-beam[gcp]` 来解决。
-
监控作业进度 :
提交作业后,进程会正常退出。要监控作业的进度和完成情况,可以导航到 Cloud Console 中的 Cloud Dataflow UI。在那里,你会看到新创建的作业列表,点击作业名称可以查看作业的详细信息,包括管道图和作业细节。管道图与之前的设计相似,这表明 Dataflow 正确理解了我们的管道意图。大多数工作会很快完成,你可能只能看到每个阶段从运行状态变为成功状态。作业完成大约需要几分钟时间,这主要是因为需要进行一些设置工作,如启动虚拟机、配置磁盘、升级和安装软件,以及作业完成后关闭资源。
在作业详细信息页面的右侧,你可以看到作业的区域、开始时间、已用时间等信息,以及执行管道所涉及的资源详细信息。例如,一个作业可能使用了约 276 MB - 小时的内存和不到 0.07 vCPU - 小时的计算时间。
7. 处理更大的数据量
为了进一步测试 Cloud Dataflow 的性能,我们可以增加输入数据的量。以下是具体步骤:
1.
生成更大的文件
:
使用 Python 脚本生成一个包含 1000 万行的文本文件:
bash
$ python -c "print (raw_input() + '\n') * 10**7" < input.txt > input-10e7.txt
2.
上传文件到 Cloud Storage 存储桶
:
bash
$ gsutil -m cp input-10e7.txt gs://dataflow-bucket/input-10e7.txt
3.
运行管道
:
bash
$ python counter.py \
--input=gs://dataflow-bucket/input-10e7.txt \
--output=gs://dataflow-bucket/output-10e7- \
--runner=DataflowRunner
在 Cloud Console 中查看新作业的概述时,由于数据量较大,你可以看到作业在运行过程中的详细信息。每个阶段会显示正在处理的元素数量,并且可以看到数据在管道中流动的过程,每个阶段会同时处理数据块,而不是等待前一个阶段完全完成后再开始。
例如,在 `ReadFromText` 步骤中,数据会根据换行符被分割成可管理的块,然后传递给 `Split` 步骤进行单词拆分。整个过程就像一条装配线,每个阶段并行计算,提高了处理效率。
8. 总结
通过本文的介绍,我们学习了如何使用 Apache Beam 和 Google Cloud Dataflow 进行大规模数据处理。以下是整个过程的关键步骤总结:
| 步骤 | 操作内容 |
|---|---|
| 1 | 了解 Apache Beam 的基本概念,包括管道、PCollections 和转换,并通过代码示例实现一个简单的数据处理管道 |
| 2 | 认识 Google Cloud Dataflow,它是一个完全托管的管道运行器,无需初始设置底层资源 |
| 3 | 进行与 Cloud Dataflow 交互的初始设置,包括启用 API、安装 Apache Beam 及扩展、获取凭证和创建 Cloud Storage 存储桶 |
| 4 | 创建一个完整的管道代码,用于统计输入文本中以字母 “a” 开头的单词数量 |
| 5 |
使用
DirectRunner
在本地测试管道,验证其在小数据量和大数据量下的正确性
|
| 6 | 使用 Cloud Dataflow 执行管道,上传文件到存储桶,指定输入输出文件和运行器 |
| 7 | 处理更大的数据量,测试 Cloud Dataflow 的性能和并行处理能力 |
以下是整个流程的 mermaid 流程图:
graph LR
A[学习 Apache Beam 概念] --> B[了解 Cloud Dataflow]
B --> C[设置 Cloud Dataflow 环境]
C --> D[创建管道代码]
D --> E[本地测试管道]
E --> F[使用 Cloud Dataflow 执行管道]
F --> G[处理更大数据量]
通过这些步骤,我们可以充分利用 Apache Beam 和 Google Cloud Dataflow 的优势,高效地处理大规模数据。无论是小型项目还是大型企业级应用,这些工具都能提供强大的支持。希望本文能帮助你更好地掌握这些技术,应对各种数据处理挑战。
超级会员免费看
1275

被折叠的 条评论
为什么被折叠?



