确定Spark中数据偏差的原因

时间:2017-10-06 10:02:59

标签: apache-spark apache-spark-sql spark-dataframe

我正在研究一个Spark SQL作业(Spark 1.6.0),由于200个分区上的数据严重偏差而导致性能不佳,大部分数据都在1个分区中: Index,ID,Attempt,Status,Locality Level,Executor ID/Host,Launch Time,Duration,GC Time,Shuffle Read Size/Records 我想知道的是......在用户界面中是否有任何东西可以帮助我找到有关数据分区方式的更多信息?从这看起来,我不知道数据帧被分区的列。我怎么能找到它? (除了查看代码之外 - 我想知道日志和/或用户界面中是否有任何可以帮助我的内容)?

其他细节,这是使用Spark的数据帧API,Spark版本1.6。基础数据以镶木地板格式存储。

1 个答案:

答案 0 :(得分:2)

Spark UI和日志对此不会有太大帮助。 Spark使用simple hash partitioning算法作为几乎所有内容的默认值。正如您在此处所看到的,这基本上回收了Java hashCode方法。

我建议如下:

  • 尝试通过采样和打印RDD或数据帧的内容进行调试。查看密钥的数据分布(即低差异或低基数)是否存在明显问题。
  • 如果这样做无效,您可以从日志和UI返回来确定我们有多少分区。您可以使用spark找到hashCode数据,然后取模数来查看碰撞情况。

找到碰撞源后,您可以尝试使用一些技术将其删除:

  • 查看是否有更好的密钥可以使用
  • 看看你是否可以改进密钥的hashCode功能(Java中的默认功能并不是那么好)
  • 通过执行初始分散/收集步骤以强制执行某些并行操作并减少该分区的处理开销,查看是否可以通过两个步骤处理数据。对于这里提到的那些,这可能是最棘手的优化。基本上,使用随机数生成器对数据进行一次分区以强制数据的初始并行组合,然后使用自然分区器再次推送数据以获得最终结果。这要求您应用的操作具有传递性和关联性。这种技术在网络中击中了两次,因此非常昂贵,除非数据实际上是高度偏斜的。