NO IMAGE

使用spark有一段時間了,期間遇到了不少問題,諸如out of memory,java.io.IOException: Filesystem closed,task任務過多導致效能低下等等。現一一列舉如下,並給出解決方案。

1. 記憶體問題,heap error,java.lang.OutOfMemoryError: PermGen space

spark的作業節點有driver和executor,遇到記憶體問題首先要搞清楚是driver節點還是executor節點。

driver節點的jvm opts可以通過–driver-java-options引數配置,直接通過命令列引數傳給SparkSubmit。

executor節點的jvm opts可以通過sparkconf配置,sparkconf.set(“spark.executor.extraJavaOptions”, “”-Xms1024m -Xmx3072m -XX:MaxPermSize=256m -XX:ThreadStackSize=512″”)

2. java.io.IOException: Filesystem closed

把shuffle方式配置成sortshuffle後,資料量加大後時不時會丟擲如下錯誤。

ava.io.IOException: Filesystem closed

        org.apache.hadoop.hdfs.DFSClient.checkOpen(DFSClient.java:707)

        org.apache.hadoop.hdfs.DFSInputStream.readWithStrategy(DFSInputStream.java:776)

        org.apache.hadoop.hdfs.DFSInputStream.read(DFSInputStream.java:837)

        org.apache.hadoop.hdfs.DFSInputStream.read(DFSInputStream.java:645)

        java.io.DataInputStream.readInt(DataInputStream.java:387)

        org.apache.hadoop.hive.ql.io.RCFile$Reader.readRecordLength(RCFile.java:1636)

        org.apache.hadoop.hive.ql.io.RCFile$Reader.nextKeyBuffer(RCFile.java:1675)

        org.apache.hadoop.hive.ql.io.RCFile$Reader.next(RCFile.java:1842)

        org.apache.hadoop.hive.ql.io.RCFileRecordReader.next(RCFileRecordReader.java:161)

        org.apache.hadoop.hive.ql.io.RCFileRecordReader.next(RCFileRecordReader.java:148)

        org.apache.hadoop.hive.ql.io.RCFileRecordReader.next(RCFileRecordReader.java:46)

        org.apache.spark.rdd.HadoopRDD$$anon$1.getNext(HadoopRDD.scala:239)

        org.apache.spark.rdd.HadoopRDD$$anon$1.getNext(HadoopRDD.scala:208)

        org.apache.spark.util.NextIterator.hasNext(NextIterator.scala:71)

        org.apache.spark.InterruptibleIterator.hasNext(InterruptibleIterator.scala:39)

        scala.collection.Iterator$$anon$11.hasNext(Iterator.scala:327)

        scala.collection.Iterator$$anon$11.hasNext(Iterator.scala:327)

        scala.collection.Iterator$$anon$11.hasNext(Iterator.scala:327)

        scala.collection.Iterator$$anon$11.hasNext(Iterator.scala:327)

        scala.collection.Iterator$$anon$11.hasNext(Iterator.scala:327)

        scala.collection.Iterator$$anon$11.hasNext(Iterator.scala:327)

        scala.collection.Iterator$$anon$13.hasNext(Iterator.scala:371)

        scala.collection.Iterator$$anon$11.hasNext(Iterator.scala:327)

        scala.collection.Iterator$$anon$11.hasNext(Iterator.scala:327)

        org.apache.spark.util.collection.ExternalSorter.insertAll(ExternalSorter.scala:229)

        org.apache.spark.shuffle.sort.SortShuffleWriter.write(SortShuffleWriter.scala:74)

仔細排查後發現executor節點因為記憶體消耗過大,out of memory了。這個問題,一方面要調大executor的記憶體。另一方面要控制shuffle任務的大小。

3. task數量過多

很多時候如果不去設定partition數量,spark會產生大量的partition。在筆者的測試裡,讀取hdfs裡面總共62個block,spark產生了1800多個partition,導致任務過多,每個任務執行時間只有幾百ms。可以通過rdd.coalesce調整partition數量。