Python 在pyspark中广播大型阵列(~8GB)

Python 在pyspark中广播大型阵列(~8GB),python,apache-spark,python-3.4,pyspark,Python,Apache Spark,Python 3.4,Pyspark,在Pyspark中,我尝试广播一个大小约为8GB的大型numpy阵列。但它失败了,错误为“OverflowerError:无法序列化大于4GiB的字符串”。我有15g的执行器内存和25g的驱动程序内存。我尝试过使用默认和kyro序列化程序。两者都不起作用,并且显示出相同的错误。 有人能建议如何消除此错误以及处理大型广播变量的最有效方法吗?PySpark不使用Java端序列化进行广播,因此使用Kryo或任何其他序列化设置都没有帮助。这只是以前pickle协议的一个限制 从理论上讲,在Python3

在Pyspark中,我尝试广播一个大小约为8GB的大型numpy阵列。但它失败了,错误为“OverflowerError:无法序列化大于4GiB的字符串”。我有15g的执行器内存和25g的驱动程序内存。我尝试过使用默认和kyro序列化程序。两者都不起作用,并且显示出相同的错误。
有人能建议如何消除此错误以及处理大型广播变量的最有效方法吗?

PySpark不使用Java端序列化进行广播,因此使用Kryo或任何其他序列化设置都没有帮助。这只是以前pickle协议的一个限制

从理论上讲,在Python3.4+中调整PySpark代码以使用特定版本的协议是可能的,但一般来说,我不相信这是值得的。通常,在PySpark中广播大变量,因为它不在执行者之间共享

如果确实需要,最简单的解决方案就是将阵列拆分为大小小于4GB的多个块。这不会使PySpark广播更高效,但会解决您的问题

offset = ...
a_huge_array = np.array(...)

a_huge_array_block_1 = sc.broadcast(a_huge_array[0:offset])
a_huge_array_block_2 = sc.broadcast(a_huge_array[offset:2*offset])
...

更聪明一点的处理方法是使用本地文件系统而不是变量分发文件,并通过访问这些文件。例如,您可以使用或。

这不是PySpark的问题,这是Spark机具的限制


Spark使用scala数组存储广播元素,因为scala的最大整数是2*10^9,所以总字符串字节数是2*2*10^9=4GB,您可以查看Spark代码。

谢谢您的解释。您是否建议将这样大的阵列(~8GB)作为并行集合进行分区?此外,当您说“分发文件而不是变量”时,您的意思是将其保存到HDFS文件并通过执行器访问?否和否。在第一种情况下,您可以使用由偏移量分区的多个广播。在第二种情况下,本地文件系统+
SparkFiles
或标准工具(例如rsync)。