これは、外部メモリspark.executor.memoryOverhead = 4096メートルを改善します
再実行したSQLの変更は、次のエラーが報告されました
19/12/25午後3時49分02秒ERRORのShuffleBlockFetcherIterator:ブロック(複数可)を取得できませんでしたbigdata-データノードから:7339 io.netty.util.internal.OutOfDirectMemoryError:割り当てに失敗しました 16777216 バイト(複数可)を直接メモリ(使用の: 5726797824:5721030656、最大) :io.netty.util.internal.PlatformDependent.incrementMemoryCounter(PlatformDependent.javaで 640 ) :io.netty.util.internal.PlatformDependent.allocateDirectNoCleaner(PlatformDependent.javaで 594 ) io.netty.bufferで.PoolArena $ DirectArena.allocateDirect(PoolArena.java: 764 ) io.netty.buffer.PoolArena $ DirectArena.newChunk(PoolArena.java時: 740) :io.netty.buffer.PoolArena.allocateNormal(PoolArena.javaにおける 244 ) :io.netty.buffer.PoolArena.allocate(PoolArena.javaにおける 226 ) :io.netty.buffer.PoolArena.allocate(PoolArena.javaで 146 ) io.netty.buffer.PooledByteBufAllocator.newDirectBuffer(PooledByteBufAllocator.java時: 324 ) io.netty.buffer.AbstractByteBufAllocator.directBuffer(AbstractByteBufAllocator.java時: 185 ) io.netty.buffer.AbstractByteBufAllocator.directBufferで(AbstractByteBufAllocator.java: 176 ) io.netty.buffer.AbstractByteBufAllocator.ioBuffer(AbstractByteBufAllocator.java時: 137) :io.netty.channel.DefaultMaxMessagesRecvByteBufAllocator $ MaxMessageHandle.allocate(DefaultMaxMessagesRecvByteBufAllocator.javaで 80 ) :io.netty.channel.nio.AbstractNioByteChannel $ NioByteUnsafe.readで(AbstractNioByteChannel.java 122 ) io.netty.channel.nio.NioEventLoopで.processSelectedKey(NioEventLoop.java: 645 ) io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimizedで(NioEventLoop.java: 580 ) io.netty.channel.nio.NioEventLoop.processSelectedKeysで(NioEventLoop.java: 497 ) IOました。 netty.channel.nio.NioEventLoop.run(NioEventLoop.java: 459 ) io.netty.util.concurrent.SingleThreadEventExecutor $で5.run(SingleThreadEventExecutor.java:858 ) io.netty.util.concurrent.DefaultThreadFactory $ DefaultRunnableDecorator.runで(DefaultThreadFactory.java: 138)
ビューの間違った箇所から外部ヒープメモリオーバーフローです
大きい地図データが設定を超える捕捉する必要性を減少させるときにスパーク用途は、各マップに対応した出力を得る減らすために、それぞれのニーズをネットワーク伝送用部分網状骨格をシャッフルするが、網状キャッシュメモリヒープ外シャッフルを適用します制限は、彼らがこの間違ったことを報告しました。
私たちは、spark2.4ソースが新しいコンフィギュレーションを発見見て
プライベート [スパーク]ヴァルMAX_REMOTE_BLOCK_SIZE_FETCH_TO_MEM = ConfigBuilder(「spark.maxRemoteBlockSizeFetchToMem」) の.doc(「ブロックのサイズがこのしきい値を超えている場合、リモートブロックがディスクにフェッチされます。」+ バイト数」。これは巨大な要求を回避することであるがあまりにもかかり多くのメモリ。私たちは、この「+有効にすることができます (例えば200メートル)。特定の値を設定することにより、 『設定をこの設定が反映されます注意してください』 + 『両方シャッフルフェッチとブロックマネージャは、リモート・フェッチブロック。』 +が有効なユーザーの場合は 」外部シャッフルサービスを、外部シャッフル」+ときに、この機能は働いていたことができる 『サービスがスパーク2.2よりも新しいです。』) .bytesConf(ByteUnit.BYTE) // フェッチ-に-MEMは、我々は可能性があるので、メッセージは、2ギガバイトよりも大きい場合に失敗することが保証されて // も使用などフェッチ・ツー・ディスク、その場合には。メッセージには、ほかにいくつかのメタデータが含ま // ブロックデータそのものへの(特にUploadBlockにメタデータをたくさん持っている)ので、私たちは去る // 余分な部屋を。 .createWithDefault(Int.MaxValue - 512)
ブロックを回避するためにメモリにロード引っ張っ過度から遠隔シャッフルします。ディスクに書き込まれ、この設定されたサイズのオーバーフローを越えて
ヴァルwrappedStreams = 新しいShuffleBlockFetcherIterator( 文脈、 blockManager.shuffleClient、 blockManager、 mapOutputTracker.getMapSizesByExecutorId(handle.shuffleId、startPartition、endPartition)、 serializerManager.wrapStream、 // 注:接尾辞は、下位互換性のために提供されていないときに我々はgetSizeAsMbを使用 SparkEnv.get。 conf.getSizeAsMb( "spark.reducer.maxSizeInFlight"、 "48メートル")* 1024 * 1024 、 SparkEnv.get.conf.getInt( "spark.reducer.maxReqsInFlight" 、Int.MaxValue)、 SparkEnv.get.conf.get( config.REDUCER_MAX_BLOCKS_IN_FLIGHT_PER_ADDRESS)、 SparkEnv.get.conf.get(config.MAX_REMOTE_BLOCK_SIZE_FETCH_TO_MEM)、 SparkEnv.get.conf.getBoolean( "spark.shuffle.detectCorrupt"、真))
次回のフォローアップに行きます
// リクエストが大きすぎると、ディスクへのリモートシャッフルブロックを取得します。シャッフルデータがされているので 、// 既に(関連のconfigs WRT)ワイヤー上で暗号化および圧縮され、私達はちょうどフェッチすることができます // データを直接ファイルに書き込みます。 もし(req.size> maxReqSizeShuffleToMem){ shuffleClient.fetchBlocks(address.host、address.port、address.executorId、blockIds.toArray、 blockFetchingListener、この) } 他{ shuffleClient.fetchBlocks(address.host、address.port、アドレス。 executorId、blockIds.toArray、 blockFetchingListener、NULL ) } }
スパークは、default.conf設定ファイルで
spark.maxRemoteBlockSizeFetchToMem 512メートル
再実行したSQLを試してみてください
あなたは、シャッフルのファイルを見ることができるタスクである大きすぎるか遅い時々は、次のエラーを報告しましたので、偉大な不思議ではより多くのメモリが死ぬように見える与えることによって失敗されます
FetchFailed(BlockManagerId(1958、bigdata-odatanode、7339、なし)、shuffleId = 18、mapId = 1、reduceId = 1、メッセージ= org.apache.spark.shuffle.FetchFailedException:bigdataから接続 -datanode / IP:7339を閉じた 時:org.apache.spark.storage.ShuffleBlockFetcherIterator.throwFetchFailedException(ShuffleBlockFetcherIterator.scala 554 ) :org.apache.spark.storage.ShuffleBlockFetcherIterator.next(ShuffleBlockFetcherIterator.scalaで 485 ) org.apache.spark.storage.ShuffleBlockFetcherIterator.nextで( ShuffleBlockFetcherIterator.scala: 64 ) scala.collection.Iterator $$アノン$で 12.nextCur(Iterator.scala:435 ) scala.collection.Iterator $$アノン$で:12.hasNext(441 Iterator.scala ) scala.collection.Iterator $$アノン$で:11.hasNext(409 Iterator.scala ) org.apache.spark.util.CompletionIterator.hasNext(CompletionIterator.scala:時 31 ) で:org.apache.spark.InterruptibleIterator.hasNext(InterruptibleIterator.scala 37 ) scala.collection.Iterator $$アノン$で:11.hasNext(409 Iterator.scala ) org.apache.spark.sql.catalyst.expressions.GeneratedClassで$ GeneratedIteratorForCodegenStage40.sort_addToSorter_0 $(不明なソース) org.apache.spark.sql.catalyst.expressions.GeneratedClass $ GeneratedIteratorForCodegenStage40.processNextで(不明なソース) :org.apache.spark.sql.execution.BufferedRowIterator.hasNext(BufferedRowIterator.javaにおける 43 ) org.apache.spark.sql.execution.WholeStageCodegenExec $$ anonfun $で 636:13 $$アノン$ 1.hasNext(WholeStageCodegenExec.scala ) org.apache.spark.sql.execution.RowIteratorFromScala.advanceNext(RowIterator.scala時: 83 ) org.apache.spark.sql.execution.joins.SortMergeJoinScanner.advancedStreamedで(SortMergeJoinExec.scala: 794 ) org.apacheました。 spark.sql.execution.joins.SortMergeJoinScanner.findNextOuterJoinRows(SortMergeJoinExec.scala: 755 ) org.apache.spark.sql.execution.joins.OneSideOuterIterator.advanceStream(SortMergeJoinExec.scala時: 917) org.apache.spark.sql.execution.joins.OneSideOuterIterator.advanceNext(SortMergeJoinExec.scala時: 953 ) :org.apache.spark.sql.execution.RowIteratorToScala.hasNextで(RowIterator.scala 68 ) org.apacheました。 spark.sql.catalyst.expressions.GeneratedClass $ GeneratedIteratorForCodegenStage45.processNext(不明出典) :org.apache.spark.sql.execution.BufferedRowIterator.hasNext(BufferedRowIterator.javaで 43 ) org.apache.spark.sql.execution.WholeStageCodegenExecで$$ anonfun $ 13 $$アノン$ 1.hasNext(WholeStageCodegenExec.scala:636 ) org.apache.spark.sql.execution.datasources.FileFormatWriter $ .ORG $ apacheの$スパーク$のsql $実行$データソースで$ FileFormatWriter $$ executeTask(FileFormatWriter.scala: 232 ) org.apache.spark.sql.executionで。 datasources.FileFormatWriter $$ anonfun $書き込み$ 1.apply(FileFormatWriter.scala:170 ) org.apache.spark.sql.execution.datasources.FileFormatWriterで$$ anonfun $書き込み$ 1.apply(FileFormatWriter.scala:169 ) で、 org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala: 90 ) :org.apache.spark.scheduler.Task.run(Task.scalaで 123 ) org.apache.spark.executor.Executor $ TaskRunner $で$ anonfun $ 10.apply(Executor.scala:408 ) :org.apache.spark.util.Utils $ .tryWithSafeFinally(Utils.scalaで 1360 ) :org.apache.spark.executor.Executor $ TaskRunner.runで(Executor.scala 414 ) java.util.concurrent.ThreadPoolExecutorで。 :runWorker(ThreadPoolExecutor.java 1149 ) :java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.javaで 624 ) :java.lang.Thread.run(Thread.javaで 748 ) にjava.io.IOException:によって引き起こさ:bigdataから接続 -datanode / IP:7339を閉じた状態
このエラーは、ハートビートタイムアウト切断問題で、分析がexcutorのGCまたはファイルがファイルもゆっくり実行するには大きすぎること、その後何のフルGCを観察するには大きすぎるではありませんexcutor見つけることができます。
並列処理の並列設定の現在の転送大程度を続行
spark.sql.shuffle.partitions 1000年
5000の変更
SQL速く多くを再実行しました
上記のエラーが低減されます