在Pyspark,我正在尝试播放一个8GB左右的大型numpy阵列。但它失败并出现错误" OverflowError:无法序列化大于4GiB的字符串"。我有15g执行程序内存和25g驱动程序内存。我尝试过使用默认和kyro序列化程序。两者都没有工作并显示相同的错误。 任何人都可以建议如何摆脱这个错误和解决大型广播变量的最有效方法吗?
答案 0 :(得分:1)
PySpark不使用Java端序列化进行广播,因此使用Kryo或任何其他序列化设置都无济于事。它只是version 4之前的pickle协议的限制。
理论上应该可以调整PySpark代码以在Python 3.4+中使用特定版本的协议,但一般来说我不相信这是值得的。通常在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])
...
更聪明的方法是使用本地文件系统而不是变量分发文件,并通过memory-mapping访问这些文件。例如,您可以使用flat files或Memory-Mapped SQLite。
答案 1 :(得分:0)
这不是PySpark的问题,这是Spark工具的限制。
Spark使用scala数组来存储广播元素,因为Scala的最大整数是2 * 10 ^ 9,所以总字符串字节是2 * 2 * 10 ^ 9 = 4GB,您可以查看Spark代码。