Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache spark Spark Streaming—垃圾收集时间长_Apache Spark_Spark Streaming - Fatal编程技术网

Apache spark Spark Streaming—垃圾收集时间长

Apache spark Spark Streaming—垃圾收集时间长,apache-spark,spark-streaming,Apache Spark,Spark Streaming,我正在运行一个Spark流媒体应用程序,它有1个小时的批处理来连接两个数据源,并将输出写入磁盘。一个数据源的总大小约为每小时40 GB(拆分为多个文件),而第二个数据源的大小约为每小时600-800 MB(也拆分为多个文件)。由于应用程序的限制,我可能无法运行较小的批处理。目前,在一个拥有140个内核和700 GB RAM的集群中生成输出大约需要20分钟。我运行7个工人和28个执行器,每个都有5个内核和22 GB的RAM 我在40 GB的数据源上执行mapToPair()、filter()和Re

我正在运行一个Spark流媒体应用程序,它有1个小时的批处理来连接两个数据源,并将输出写入磁盘。一个数据源的总大小约为每小时40 GB(拆分为多个文件),而第二个数据源的大小约为每小时600-800 MB(也拆分为多个文件)。由于应用程序的限制,我可能无法运行较小的批处理。目前,在一个拥有140个内核和700 GB RAM的集群中生成输出大约需要20分钟。我运行7个工人和28个执行器,每个都有5个内核和22 GB的RAM

我在40 GB的数据源上执行mapToPair()、filter()和ReduceByAndWindow(1小时批处理)。大部分计算时间都花在这些操作上。让我担心的是每个执行器的垃圾收集(GC)执行时间,从25秒到9.2分钟。我在下面附上两个截图:一个列出GC时间,另一个打印单个执行者的GC注释。我预计花费9.2分钟进行垃圾收集的执行者最终会被Spark驱动程序杀死

我认为这些数字太高了。你有什么关于保持低GC时间的建议吗?我已经在使用Kryo序列化程序、++useConMarkSweepGC和spark.rdd.compress=true

还有什么能帮上忙的吗?

编辑

这是我的代码片段:

// The data feed is then mapped to a Key/Value RDD. Some string in the original RDD Stream will be filtered out according to the business logic 
JavaPairDStream<String, String> filtered_data = orig_data.mapToPair(parserFunc)
                                                   .filter(new Function<scala.Tuple2<String, String>, Boolean>() {
                                                     @Override
                                                     public Boolean call(scala.Tuple2<String, String> t) {
                                                       return (!t._2().contains("null"));
                                                     }
                                                   });

// WINDOW_DURATION = 2 hours, SLIDE_DURATION = 1 hour. The data feed will be later joined with another feed. 
// These two feeds are asynchronous: records in the second data feed may match records that appeared in the first data feed up to 2 hours before. 
// I need to save RDDs of the first data feed because they may be joined later. 
// I'm using reduceByKeyAndWindow() instead of window() because I can build this "cache" incrementally. 
// For a given key, appendString() simply appends new a new string to the value, while removeString() removes the strings (i.e. parts of the values) that go out of scope (i.e. out of  WINDOW_INTERVAL)
JavaPairDStream<String, String> windowed_data = filtered_data.reduceByKeyAndWindow(appendString, removeString, Durations.seconds(WINDOW_DURATION), Durations.seconds(SLIDE_DURATION))
                                                 .flatMapValues(new Function<String, Iterable<String>>() {
                                                   @Override
                                                   public Iterable<String> call(String s) {
                                                     return Arrays.asList(s.split(","));
                                                   }
                                                 });

// This is a second data feed, which is also transformed to a K/V RDD for the join operation with the first feed
JavaDStream<String> second_stream = jssc.textFileStream(MSP_DIR);

JavaPairDStream<String, String> ss_kv = second_stream.mapToPair(new PairFunction<String, String, String>() {
                                                @Override
                                                public scala.Tuple2<String, String> call(String row) {
                                                  String[] el = row.split("\\|");
                                                  return new scala.Tuple2(el[9], row);
                                                }
                                              });


JavaPairDStream<String, String> joined_stream = ss_kv.join(windowed_data)

// Use foreachRDD() to save joined_stream to HDFS
//然后将数据提要映射到键/值RDD。原始RDD流中的一些字符串将根据业务逻辑过滤掉
JavaPairDStream filtered_data=orig_data.mapToPair(parserFunc)
.filter(新函数(){
@凌驾
公共布尔调用(scala.Tuple2 t){
返回(!t._2()包含(“null”);
}
});
//窗口持续时间=2小时,幻灯片持续时间=1小时。数据馈送稍后将与另一个馈送连接。
//这两个提要是异步的:第二个数据提要中的记录可能与前两个小时第一个数据提要中出现的记录相匹配。
//我需要保存第一个数据源的RDD,因为它们以后可能会加入。
//我使用ReduceByAndWindow()而不是window(),因为我可以增量地构建这个“缓存”。
//对于给定的键,appendString()只需将新字符串附加到值,而removeString()则删除超出范围(即超出窗口间隔)的字符串(即部分值)
JavaPairDStream windowed_data=筛选的_数据。ReduceByAndWindow(追加字符串、重新投资、持续时间.seconds(窗口持续时间)、持续时间.seconds(幻灯片持续时间))
.flatMapValues(新函数(){
@凌驾
公共Iterable调用(字符串s){
返回数组.asList(s.split(“,”);
}
});
//这是第二个数据提要,它也被转换为K/V RDD,用于与第一个提要的连接操作
JavaDStream second_stream=jssc.textFileStream(MSP_DIR);
JavaPairDStream ss_kv=second_stream.mapToPair(新的PairFunction(){
@凌驾
公共scala.Tuple2调用(字符串行){
字符串[]el=行。拆分(“\\\\”);
返回新的scala.Tuple2(el[9],行);
}
});
JavaPairDStream joined_stream=ss_kv.join(加窗_数据)
//使用foreachRDD()将连接的\u流保存到HDFS

请添加您的代码。另外,为什么要使用“按窗口减少”?您是否定义了一个窗口?也许您使用的是带有大窗口的小批量?我编辑了我的评论,其中包括一段代码。最终连接的两个数据源是异步的,这就是我使用窗口操作的原因。批处理大约为40GB,时间窗口为一小时。输出时间是20分钟,但GC时间对我来说似乎很高批处理时间是多少?窗口持续时间和幻灯片持续时间?还是不确定你想做什么。你能添加更多的代码吗?为什么您需要spark流媒体,而不仅仅是每小时执行一次spark作业?我添加了新代码和注释。批处理时间为1小时,窗口为2小时,幻灯片为1小时。我之所以使用Spark流媒体,是因为数据经常出现,至少每小时一次。我加入2个数据源。第二条可能有记录出现在第一条流中2小时之前。我将第一个提要的记录保存了2个小时,并使用reduceByAndWindow()递增地更新每个给定键的值。在我的例子中,键和值都是字符串,所以我定义了两个函数,它们在字符串进入/离开范围时添加/删除字符串。我是Spark的新手,所以任何建议都会对Marco有所帮助,你知道问题出在哪里吗?