并行Spark收集功能

时间:2019-09-19 17:15:32

标签: python apache-spark pyspark

我注意到spark的功能collect在处理大量数据时非常慢,因此我试图使用并行化来解决此问题。

我的main方法创建了spark会话,并将其传递给get_data函数。

def main():
    spark = SparkSession.builder.appName('app_name').getOrCreate()
    return get_data(spark)

在这里我尝试并行化收集功能

def get_data(spark):
    df = all_data(spark)
    data = spark.sparkContext.parallelize(df.select('my_column').distinct().collect())
    return map(lambda row: row['my_column'], data)

这不起作用,并返回此错误:

  

TypeError:“ RDD”对象不可迭代

有人对get_data函数如何并行化或提高性能有任何想法。

1 个答案:

答案 0 :(得分:2)

以下是使用broadcast变量的 static dynamic 方法的示例(每个执行程序存储器中均保留有只读变量;避免传输复制驱动程序上的列表以获取每个分布式任务),以检索列的不同值。另外,如果您在pivot期间未提供硬编码的值,则会触发额外作业(广泛的转换顺序)以获取该列的不同值。

免责声明=>对于动态方法,在性能方面可能会有更好的选择

print(spark.version)
2.4.3

import pyspark.sql.functions as F

# sample data
rawData = [(1, "a"),
           (1, "b"),
           (1, "c"),
           (2, "a"),
           (2, "b"),
           (2, "c"),
           (3, "a"),
           (3, "b"),
           (3, "c")]

df = spark.createDataFrame(rawData).toDF("id","value")

# static list example
l = ["a", "b", "c"]
l = spark.sparkContext.broadcast(l)

pivot_static_df = df\
  .groupby("id")\
  .pivot("value", l.value)\
  .agg(F.expr("first(value)"))

pivot_static_df.show()
+---+---+---+---+
| id|  a|  b|  c|
+---+---+---+---+
|  1|  a|  b|  c|
|  3|  a|  b|  c|
|  2|  a|  b|  c|
+---+---+---+---+

# dynamic list example
v = df.select("value").distinct().rdd.flatMap(lambda x: x).collect()
v = spark.sparkContext.broadcast(v)

print(v.value)

pivot_dynamic_df = df\
  .groupby("id")\
  .pivot("value", l.value)\
  .agg(F.expr("first(value)"))

pivot_dynamic_df.show()
['c', 'b', 'a']
+---+---+---+---+
| id|  a|  b|  c|
+---+---+---+---+
|  1|  a|  b|  c|
|  3|  a|  b|  c|
|  2|  a|  b|  c|
+---+---+---+---+