在 Pyspark 中,我正在尝试广播大小约为 8GB 的大型 numpy 数组。但它失败并出现错误“OverflowError:无法序列化大于 4GiB 的字符串”。我有 15g 执行程序内存和 25g 驱动程序内存。我尝试过使用默认序列化器和 kyro 序列化器。两者都不起作用并显示相同的错误。 谁能建议如何消除此错误以及处理大型广播变量的最有效方法?
最佳答案
PySpark 不使用 Java 端序列化进行广播,因此使用 Kryo 或任何其他序列化设置都无济于事。这只是 version 4 之前的 pickle 协议(protocol)的限制。 .
理论上,应该可以调整 PySpark 代码以使用 Python 3.4+ 中协议(protocol)的特定版本,但一般来说,我不相信这是值得的。一般来说,在 PySpark 中广播大型变量,因为它不在执行器之间共享。
如果你确实需要这个,最简单的解决方案就是将数组分割成多个大小小于 4GB 的 block 。它不会使 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])
...
处理这个问题的更聪明的方法是使用本地文件系统而不是变量来分发文件,并通过 memory-mapping 访问这些文件。 。例如,您可以使用 flat files或Memory-Mapped SQLite .
关于python - 在 pyspark 中广播大型数组(~ 8GB),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34998280/