Hive-16061パッチの導入後、より深刻なOOMの問題が発生しました

このパッチは、一部のHive出力がbeelineコンソールに出力されない問題を修正するために使用されます:
https ://issues.apache.org/jira/browse/HIVE-16061

漏れたオブジェクトを見つけます

ファイルをダンプした後、リークされたオブジェクトがこのマップの
ここに画像の説明を挿入
クエリ対応するキーであることが簡単にわかります
ここに画像の説明を挿入
。正常に削除されました。クライアントが再接続して多数のキーを追加しました。これらのキー
ここに画像の説明を挿入
正常に機能しなかった可能性あります。クライアントが新しく接続されたときに削除されました。ディスク上の対応するフォルダが削除されました。ここでメモリリークが発生したことを確認できます。

詳細な分析

まず第一に、見つけることは難しくありません

  • MAPはプライベートオブジェクトであるため、MAPに対する操作は通常AbstractManagerを介して行われます。
  • MAPは静的であり、同様のオブジェクト間で共有されます
  • MAP参照は不変であり、MAPの作成と置換のそのような操作はありません

ただし、removeのベースとなるAbstractManagerの名前はプライベートです。つまり、複数のAbstractManager実装クラスがMAPを共有し、それらのrelease()メソッドが呼び出されると、それらは独自の名前に従ってMAPから削除されます。
ここに画像の説明を挿入
前の記事の分析から、MAPの多くのキーは削除されていませんが、これらのAbstractManagerのrelease()メソッドが呼び出されていないことを意味しますか?
ここに画像の説明を挿入
この考え方に従って、AbstractOutputStreamAppender.stop()が呼び出されると、this.manager.release()が呼び出されます。

ここに画像の説明を挿入

そのマネージャーもプライベートであり、他のオブジェクトがこれを操作することはなく、リリースは再度停止されたときにのみ発生します。

AbstractOutputStreamAppenderの実装クラスが正しく停止されている場合、マネージャーも正しくreleased()されている必要があり、MAPにはそれほど多くのキーがありませんが、逆のことが当てはまります。つまり、AbstractOutputStreamAppenderとAbstractManagerの実装クラスの合計にはまた、リークされました。
ここに画像の説明を挿入

メソッドスタックを深く掘り下げると、特定の実装クラスがわかります。
ここに画像の説明を挿入
このクラスのオブジェクトを見ると、多くの実装クラスがあり
ここに画像の説明を挿入
前の接続から残しておく必要があることがわかります。この実装クラスは静的に呼び出されます。LogUtilsによるものであり、LogUtilsのリークがないはずです。次に、メソッドスタックを見ると、LogUtilsがクエリを停止するアペンダーであることがわかります。これは、以前にクエリされたキーを削除できる理由も説明できます。

ここに画像の説明を挿入

現在、接続の最後にアペンダーを見つけて正しく停止する限り、この問題は解決できます。

多くのブレークポイントデバッグ部分を省略し、cleanupSessionLogDirメソッドを見つけました

修正してみてください

HiveSessionImplのcleanupSessionLogDir()でこれらのオブジェクトをStop()して、ファイルが役に立たなくなったときにファイルがstopped()であることを確認できるようにします。

sessionLogDir.list()はこれらのファイル名を取得できます

以前の分析では、LogUtils.stopQueryAppender(LogDivertAppender.QUERY_ROUTING_APPENDER、queryId)がこれらを閉じることができることがわかりました

//stopQueryAppender 
String[] queryIdArr = sessionLogDir.list();
for(String queryId:queryIdArr) {
  LogUtils.stopQueryAppender(LogDivertAppender.QUERY_ROUTING_APPENDER, queryId);
}

コンパイルのために送信し、リリースしてオンラインにし、再テストし、初めて接続し、問題が発生した場所MAP.remove(this.name)にクエリを開始すると、マップに27 kvがあり、30kvしかないことがわかりました。が再び接続され、このセッションのみがあります。Kv
ここに画像の説明を挿入
が再度テストされ、MAPにはまだ30 kvしかありません
ここに画像の説明を挿入
が、RandomAccessFileAppenderにはまだ78があり、3つのセッションは27、26、および25です
ここに画像の説明を挿入
。GCをトリガーしない可能性があり、その後消えます。 GC。つまり、少なくともMAPリークの問題は解決されました。

おすすめ

転載: blog.csdn.net/weixin_44112790/article/details/112317201