EMR上的Pyspark:如何在不破坏Spark的情况下在一个鸡蛋中调用udf()?

时间:2018-01-17 19:42:28

标签: apache-spark pyspark user-defined-functions amazon-emr egg

我在EMR的Pyspark看到一个问题,如果我导入了一个叫pyspark.sql.functions.udf()的鸡蛋,那么Spark处理会挂起。

我正在使用Spark 2.1.0,Zeppelin 0.6.2,Ganglia 3.7.2运行emr-5.3.1的EMR集群。

我希望能够创建一个可以用于各种工作的UDF库。

在我正在运行的Zeppelin笔记本中:

%pyspark
sc.addPyFile("s3://your_s3_path/my_egg-0.1-py2.7.egg")
from my_egg import *

obj = MyClass(sqlContext)
obj.do_map()

my_egg中的代码是:

from pyspark.sql.types import *

def my_scalar_func(input):
    return input

from pyspark.sql.functions import udf

# This is the line that causes the whole thing to hang. Uncomment it to reproduce the issue
udf_my_scalar_func = udf(my_scalar_func, StringType())

def my_map_func(row):
    return row

class MyClass(object):
    def __init__(self, sqlContext):
        self.sqlContext = sqlContext
        self.raw_data = [{"id": 1, "name": "first"}]
        self.schema = StructType([StructField("id", IntegerType(), False), StructField("name", StringType(), False)])

    def do_map(self):
        print "Creating data frame"
        self.df = self.sqlContext.createDataFrame(self.raw_data, self.schema)
        print "Data frame: {0}".format(self.df.collect())
        self.rdd = self.df.rdd.map(my_map_func)
        # The collect() call hangs if the UDF line above is uncommented
        print "Mapped RDD: {0}".format(self.rdd.collect())

处理在do_map()的最后一行(执行rdd.map()和collect()的过程中)挂起。我已经等了3个小时才杀了这份工作。

如果我注释掉定义udf_my_scalar_func的行,则整个过程会在不到一秒的时间内执行。

请注意,udf_my_scalar_funcmy_scalar_func永远不会被调用,并且与实际执行的代码没有任何关系。

我对Spark和Pyspark内部的了解不足以弄清楚为什么会这样。怎么解释?有没有办法在一个鸡蛋中定义一个UDF?或者是否有另一种方法可以创建一个UDF库,这些UDF可以轻松访问提交给集群的Pyspark作业?

我创建了一个Github仓库,其中包含一系列完整步骤来重现此问题,包括在https://github.com/ss-emonsen/emr_udf_egg创建EMR群集。

0 个答案:

没有答案