我知道菲尔,这真难 😣
脑 🧠
「不要试图同时做几件事情。这会降低工作效率,导致错误,并妨碍创新思维。」
———— 一位 聪明的 神经科学专家
————
当然可以,去告诉你经理吧 😑。他总是让我同时处理多项任务,尽管我在所有任务上都失败了!🤕
但在数据工程的世界里,多任务处理随处可见。每当分配任务给Spark执行器时,你都能看到这一点。任务被并行执行。
说实话,其实就连Spark有时候也会应付不来多任务,因为人类总是贪心不足,总是想要更多 😒
让我们来看一个这样的例子,看看为什么Spark不能同时处理多个任务。
用例和简单方法一个美好的早晨,你的经理 ping 你,让你数一下项目中所有表的行数。这事儿,奇怪,你现在还能说什么呢?
现在这些表格超过了10GB。让我来展示一下在这种情况下简单的处理方式:
table_paths = [
"dbfs:/user/hive/warehouse/t1", # 数据库表t1的路径
"dbfs:/user/hive/warehouse/t2", # 数据库表t2的路径
"dbfs:/user/hive/warehouse/sports_details", # 体育详情表的路径
"dbfs:/user/hive/warehouse/silvertable", # 银色表的路径
]
def get_count(table):
count = spark.read.format("delta").load(table).count()
return (table, count)
# 使用线程池的代码实现
result = []
for table in table_paths:
result.append(get_count(table))
# 创建数据帧
results_df = spark.createDataFrame(result, ["table_name", "row_count"])
results_df.display() # 显示结果数据帧
我们在代码里都做了些什么?
- 我们创建了一个函数,该函数读取列表中的每一个数据表
- 该函数读取数据表,并将 {table: count} 对存储到字典中
你看出有什么问题吗?🤔其实这些表格可以并行读取,这样能加快速度。
如果加载一个表需要5分钟,用这种简单的方法,计算每个表的行数(假设共有4个表)就需要20分钟!
在Spark UI中,任务执行看起来像这样:
简单方法中的任务运行
你可以很清楚地看到,这些员工一个接一个地被处理掉。我们必须解决这个问题!!😤
另一种使用Python多线程的方法这里的关键在于:
这些工作各自独立,可以同时进行。
不过,理想状态下,我们不能用Spark并行执行任务。这就需要根据个人喜好添加Python。
ThreadPoolExecutor
线程池执行程序详解
ThreadPoolExecutor
是 Python 的 concurrent.futures
模块中的一个高级 API,它简化了 基于线程的并行。它让你可以轻松管理线程池,并行执行任务更高效。
这类似于Spark中的任务并行处理——但说实话,没那么强大和高效。
在我们的例子中,我们不用“for 循环”(我们在简单的方法中使用过),而是使用 ThreadPoolExecutor
来并行执行每个表的 get_count
函数。
下面这是优化后的代码:
def get_count(table):
count = spark.read.format("delta").load(table).count()
return (table, count)
# 使用 ThreadPoolExecutor 实现代码
with ThreadPoolExecutor(max_workers=4) as executor:
result = list(executor.map(get_count, table_paths))
# 创建数据框
# 其中 table_paths 是表路径的列表
results_df = spark.createDataFrame(result, ["table_name", "row_count"])
# 显示结果数据框
results_df.display()
在上面的代码片段中,我们使用了 executor.map 函数将 “get_count” 函数与 “table_paths” 列表对应起来,并行处理每个对应的元素,这样。
最后,我们将所有执行程序的结果整理成一个列表。
看看在 Spark UI 中任务运行是什么样的。
并行执行任务
超棒的吧?😉😏
我们也可以用Databricks工作流来做这个。创建一个以表名作为参数的笔记本,并行运行这个笔记本来处理多个表。但这多没意思啊!😎(这样做不仅更耗时,还更费钱)。
在很多场景中,我们需要并行执行任务。
- 同时从多个来源摄取数据 — 青铜层
- 并行执行数据聚合和计算操作 — 银层
- 并行执行复杂的数据验证和质量检查。
- 并行处理对数据子集的不同数据转换 — 银层
- 在不同的数据场景上运行模拟或情景分析。
在这里我想提到,通过阅读这篇[文章],我对这个话题有了理解。这篇文章很有趣!
有多种方法可以实现我们讨论的用例。但这些方法可能需要使用新的服务或工具。
为什么不先利用我们已有的资源,而不是去寻找我们还没有的。🫰
如果你们喜欢这篇博客,请给它点个赞👏,让更多的数据工程师能看到这篇博客。
谢谢你阅读! 😁😊
共同学习,写下你的评论
评论加载中...
作者其他优质文章