Spark在生成非关联功能时表现不佳

时间:2016-03-24 18:39:29

标签: apache-spark

我一直使用Spark作为我自己的功能生成项目的工具。对于这个特定的项目,我有两个数据源,我加载到RDD如下:

  • Datasource1:RDD1 = [(key,(time,quantity,user-id,...)j] => ... =>一堆其他属性,例如transaction-id等。
  • Datasource2:RDD2 = [(key,(t1,t2)j)]

在RDD1中,time表示事件发生的时间戳,在RDD2中,表示每个功能的可接受时间间隔。功能键是“键”。我有两种类型的功能如下:

  1. 关联功能:项目数
  2. 非关联功能:示例:唯一用户数
  3. 对于每个功能键,我需要查看哪些事件属于间隔(t1,t2),然后聚合这些事物。所以,我有一个join,然后是reduce操作,如下所示:

    `RDD1.join(RDD2).map((key,(v1,v2))=>(key,featureObj)).reduceByKey(...)`
    

    我的功能的初始值是featureObj =(0,set([]))其中第一个参数保留项目数,第二个参数保存唯一用户ID的数量。我还对输入数据进行分区,以确保RDD1和RDD2使用相同的分区程序。

    现在,当我运行作业来计算关联特征时,它在16 m2.xlarge的集群上运行得非常快,仅需3分钟。在我添加第二个的那一刻,计算时间跳到5分钟。我试图添加一些其他非关联功能,每次运行时间都会快速增加。现在,我的工作在15分钟内运行15个功能,其中10个是非关联的。我还尝试使用KyroSerializer并以序列化形式保留RDD,但没有发生任何特殊情况。由于我将开始实现更多功能,这个问题似乎成了瓶颈。

    PS。我试图在一个大主机(128GB Ram和16个核心)上执行相同的任务。凭借145项功能,整个工作在10分钟内完成。我的印象是主要的Spark瓶颈是JOIN。我检查了我的RDD并注意到两者都以相同的方式共同分区。作为一个单独的工作是调用这两个RDD,我认为它们也位于同一位置?但是,spark web-console仍显示“2.6GB”shuffle-read和“15.6GB”shuffle-write。

    有人可以告诉我,如果我在这里真的疯了吗?我是否将Spark用于错误的应用程序?感谢您的提前评论。

    最诚挚的问候,

    阿里

1 个答案:

答案 0 :(得分:0)

我注意到随机操作也表现不佳。事实证明,当数据在同一个执行器(地点PROCESS_LOCAL)内从一个核心转移到另一个核心时,shuffle运行速度非常快,但在所有其他情况下比预期慢得多,甚至NODE_LOCAL也非常慢。这可以在Spark UI中看到。

对CPU和垃圾收集监控的进一步调查发现,在某些时候垃圾收集使我的集群中的一个节点没有响应,这也会阻止其他节点将数据从这个节点转移到该节点。

您可以调整很多选项以提高垃圾收集性能。一个重要的事情是为G1垃圾收集器启用大量对象的早期回收,这需要java 8u45或更高版本。

就我而言,最大的问题是netty中的内存分配。当我通过设置spark.shuffle.io.preferDirectBufs = false关闭直接缓冲内存时,我的作业运行得更加稳定。