我如何确定我的 Foundry 工作中偏斜任务的价值?
How do I identify the value of a skewed task of my Foundry job?
我调查了我的工作,。我如何确定导致偏差的任务中的实际值是多少?
我的 Python 转换代码如下所示:
from transforms.api import Input, Output, transform
@transform(
...
)
def my_compute_function(...):
...
df = df.join(df_2, ["joint_col"])
...
理论
倾斜问题源于任何导致您工作交换的事情。引起交换的事物包括但不限于:join
s, window
s, groupBy
s.
这些操作会导致数据根据所用 DataFrame 中找到的值在执行器之间移动。这意味着当一个使用过的 DataFrame 在指示交换的列上有许多重复值时,这些行最终都在同一个任务中,从而增加了它的大小。
例子
让我们为您的联接考虑以下数据分布示例:
DataFrame 1 (df1)
| col_1 | col_2 |
|-------|-------|
| key_1 | 1 |
| key_1 | 2 |
| key_1 | 3 |
| key_1 | 1 |
| key_1 | 2 |
| key_2 | 1 |
DataFrame 2 (df2)
| col_1 | col_2 |
|-------|-------|
| key_1 | 1 |
| key_1 | 2 |
| key_1 | 3 |
| key_1 | 1 |
| key_2 | 2 |
| key_3 | 1 |
这些 DataFrame 在 col_1
上连接在一起时将在执行程序中分布以下数据:
- 任务 1:
- 收到:来自 df1
的 5 行 key_1
- 收到:来自 df2
的 4 行 key_1
- 总输入:9 行数据发送至 task_1
- 结果:5 * 4 = 20行输出数据
- 任务 2:
- 收到:来自 df1
的 key_2
的 1 行
- 收到:来自 df2
的 key_2
的 1 行
- 总输入:2 行数据发送到 task_2
- 结果:1 * 1 = 1行输出数据
- 任务 3:
- 收到:来自 df2
的 key_3
的 1 行
- 总输入:1 行数据发送到 task_3
- 结果:1 * 0 = 0 行输出数据(缺少键;在 df1 中找不到键)
因此,如果您查看每个任务的输入和输出行数,您会发现任务 1 的数据远多于其他任务。 此任务有偏差。
身份证明
现在的问题是我们如何确定 key_1
是偏差的罪魁祸首,因为这在 Spark(为连接提供动力的底层引擎)中是不可见的。
如果我们看上面的例子,我们会发现我们需要知道的只是联合列的每个键的实际计数。这意味着我们可以:
- 在联合键上聚合连接的每一侧并计算每个键的行数
- 将联接每一侧的计数相乘以确定输出行计数
最简单的方法是在 Foundry 中打开分析(轮廓)工具并执行以下分析:
添加 df1
作为第一个路径的输入
添加Pivot Table
板,使用col_1
作为行,Row count
作为聚合
单击 ⇄ Switch to pivoted data
按钮
使用Multi-Column Editor
板只保留col_1
和COUNT
列。为它们中的每一个添加前缀 df1_
,导致路径的输出仅为 df1_col_1
和 df1_COUNT
.
将df2
添加为第二条路径的输入
添加Pivot Table
板,再次使用col_1
作为行,Row count
作为聚合
单击 ⇄ Switch to pivoted data
按钮
使用Multi-Column Editor
板只保留col_1
和COUNT
列。为它们中的每一个添加前缀 df2_
,导致路径的输出仅为 df2_col_1
和 df2_COUNT
.
使用第一条路径(df1_col_1
和 df1_COUNT1
)的结果创建第三条路径
添加一个Join
板,使连接的右侧成为第二条路径(df2_col_1
和df2_col_1
)的结果。确保连接类型是 Full join
从右边开始添加所有列(不需要加前缀,所有列都是唯一的
配置加入板以加入 df1_col_1
等于 df2_col_1
添加一个 Expression
板来创建一个新列,output_row_count
将两个 COUNT
列相乘
添加一个按 output_row_count
降序
排序的 Sort
板
如果您现在预览结果数据,您将有一个来自连接两侧的导致倾斜的键的排序列表
我调查了我的工作,
我的 Python 转换代码如下所示:
from transforms.api import Input, Output, transform
@transform(
...
)
def my_compute_function(...):
...
df = df.join(df_2, ["joint_col"])
...
理论
倾斜问题源于任何导致您工作交换的事情。引起交换的事物包括但不限于:join
s, window
s, groupBy
s.
这些操作会导致数据根据所用 DataFrame 中找到的值在执行器之间移动。这意味着当一个使用过的 DataFrame 在指示交换的列上有许多重复值时,这些行最终都在同一个任务中,从而增加了它的大小。
例子
让我们为您的联接考虑以下数据分布示例:
DataFrame 1 (df1)
| col_1 | col_2 |
|-------|-------|
| key_1 | 1 |
| key_1 | 2 |
| key_1 | 3 |
| key_1 | 1 |
| key_1 | 2 |
| key_2 | 1 |
DataFrame 2 (df2)
| col_1 | col_2 |
|-------|-------|
| key_1 | 1 |
| key_1 | 2 |
| key_1 | 3 |
| key_1 | 1 |
| key_2 | 2 |
| key_3 | 1 |
这些 DataFrame 在 col_1
上连接在一起时将在执行程序中分布以下数据:
- 任务 1:
- 收到:来自 df1 的 5 行
- 收到:来自 df2 的 4 行
- 总输入:9 行数据发送至 task_1
- 结果:5 * 4 = 20行输出数据
key_1
key_1
- 任务 2:
- 收到:来自 df1 的
- 收到:来自 df2 的
- 总输入:2 行数据发送到 task_2
- 结果:1 * 1 = 1行输出数据
key_2
的 1 行key_2
的 1 行 - 任务 3:
- 收到:来自 df2 的
- 总输入:1 行数据发送到 task_3
- 结果:1 * 0 = 0 行输出数据(缺少键;在 df1 中找不到键)
key_3
的 1 行
因此,如果您查看每个任务的输入和输出行数,您会发现任务 1 的数据远多于其他任务。 此任务有偏差。
身份证明
现在的问题是我们如何确定 key_1
是偏差的罪魁祸首,因为这在 Spark(为连接提供动力的底层引擎)中是不可见的。
如果我们看上面的例子,我们会发现我们需要知道的只是联合列的每个键的实际计数。这意味着我们可以:
- 在联合键上聚合连接的每一侧并计算每个键的行数
- 将联接每一侧的计数相乘以确定输出行计数
最简单的方法是在 Foundry 中打开分析(轮廓)工具并执行以下分析:
添加
df1
作为第一个路径的输入添加
Pivot Table
板,使用col_1
作为行,Row count
作为聚合单击
⇄ Switch to pivoted data
按钮使用
Multi-Column Editor
板只保留col_1
和COUNT
列。为它们中的每一个添加前缀df1_
,导致路径的输出仅为df1_col_1
和df1_COUNT
.将
df2
添加为第二条路径的输入添加
Pivot Table
板,再次使用col_1
作为行,Row count
作为聚合单击
⇄ Switch to pivoted data
按钮使用
Multi-Column Editor
板只保留col_1
和COUNT
列。为它们中的每一个添加前缀df2_
,导致路径的输出仅为df2_col_1
和df2_COUNT
.使用第一条路径(
df1_col_1
和df1_COUNT1
)的结果创建第三条路径添加一个
Join
板,使连接的右侧成为第二条路径(df2_col_1
和df2_col_1
)的结果。确保连接类型是Full join
从右边开始添加所有列(不需要加前缀,所有列都是唯一的
配置加入板以加入
df1_col_1
等于df2_col_1
添加一个
Expression
板来创建一个新列,output_row_count
将两个COUNT
列相乘添加一个按
排序的output_row_count
降序Sort
板如果您现在预览结果数据,您将有一个来自连接两侧的导致倾斜的键的排序列表