Apache spark spark sql中的有状态UDF,或者如何在spark sql中获得mapPartitions性能优势?
在转换导致创建或加载昂贵资源的情况下(例如,对外部服务进行身份验证或创建db连接),使用map-over-map分区可以显著提高性能 mapPartition允许我们为每个分区初始化一次昂贵的资源,而不是像标准map那样为每行初始化一次 但是如果我使用的是dataframes,那么我应用自定义转换的方式就是指定在逐行基础上运行的用户定义函数——因此我失去了mapPartitions对每个块执行一次重载的能力 spark sql/dataframe中是否有解决此问题的方法? 更具体地说: 我需要对一堆文档执行特征提取。我有一个函数,输入一个文档,输出一个向量Apache spark spark sql中的有状态UDF,或者如何在spark sql中获得mapPartitions性能优势?,apache-spark,optimization,pyspark,user-defined-functions,Apache Spark,Optimization,Pyspark,User Defined Functions,在转换导致创建或加载昂贵资源的情况下(例如,对外部服务进行身份验证或创建db连接),使用map-over-map分区可以显著提高性能 mapPartition允许我们为每个分区初始化一次昂贵的资源,而不是像标准map那样为每行初始化一次 但是如果我使用的是dataframes,那么我应用自定义转换的方式就是指定在逐行基础上运行的用户定义函数——因此我失去了mapPartitions对每个块执行一次重载的能力 spark sql/dataframe中是否有解决此问题的方法? 更具体地说: 我需要对
计算本身涉及初始化到外部服务的连接。我不想也不需要为每个文档初始化它。这在规模上具有不可忽略的开销。通常,您有三个选项:
- 将
转换为DataFrame
并直接应用RDD
。由于您使用PythonmapPartitions
,您已经破坏了某些优化并支付了serde成本,而使用udf
平均不会使情况变得更糟RDD
- 懒散地(另见)
- 如果数据可以用箭头序列化,则使用矢量化的
(Spark 2.3及更高版本)。不幸的是,您不能将它直接用于pandas\u udf
,因此您必须展开向量并在稍后折叠,因此这里的限制因素是向量的大小。此外,您还必须小心控制分区的大小VectorUDT
请注意,使用
UserDefinedFunctions
可能需要变量。我担心没有直接的方法来实现这一点。Lazy init和pandas udf听起来很有趣。顺便说一句,在单例对象中维护状态怎么样?为什么不也提到这个呢?主要是因为我觉得在Python中使用单例对象不是一个好的实践。此外,问题更多地与范围有关,而不是其他任何问题。