GO言語のパフォーマンス問題の発見と解決

GO言語のパフォーマンス問題の発見と解決

事件の原因

この事件は、社内の同僚が社内メーリンググループに質問を投稿したことから始まりました。 go1.8.3 で書かれたビジネス プログラムをしばらく実行した後、一部の goroutine がロック ForkLock を待機して停止しました。同僚は、これは go1.8.3 のバグだと考えており、go1.10 にアップグレードした後も再発しませんでした。これを理解するために、同僚が github https://github.com/golang/go/issues/26836 に問題を投稿し、再現を何度も試みましたが、うまくいきませんでした。

問題が発生したビジネスコードを参照しました。大まかな使用方法は、親プロセスが os/exec の下のコマンドを呼び出して子プロセスを開き、シェル コマンドを実行することです。次に、コマンドは golang によってカプセル化された forkExec を呼び出して子プロセスを開き、コマンドを実行します。 forkExec は ForkLock を使用します。

問題分析

ForkLock は、次のような状況を回避するために存在します。複数の goroutine が同時に exec を fork する場合、子プロセスが必要なファイル記述子のみを継承するには、親プロセスがこれらのファイル記述子を作成するときに O_CLOEXEC フラグを追加して、これらの記述子が子プロセスで閉じられ、子プロセスが必要に応じて継承する必要がある記述子を開くことができるようにする必要があります。

Linux 2.6.27 以降では、ファイルやパイプを開いたり、O_CLOEXEC を設定したりすることはアトミック操作なので、大きな問題はありません。ただし、golang ではカーネル バージョンが 2.6.23 以上である必要があります。さらに、Unix システムでは、オープンと O_CLOEXEC の設定は 2 つの操作です。 2 つの操作間でフォークが発生した場合、子プロセスは必要のないファイル記述子を継承する可能性があるため、ロックが必要になります。 forkExec のソースコードに注目してください。

問題の現象から判断すると、goroutine が forkExecPipe または forkAndExecInChild ステップでスタックし、ロックが解除されない状態になっていると考えられます。そのため、一部のゴルーチンはロックを取得できず、飢餓状態になります。 forkExecPipe*** はカーネル pipe2 を呼び出し、forkAndExecInChild*** はカーネルの clone と exec を呼び出します。

推測

pipe2 は高速なシステム コールなので、ブロックされる可能性があるシステム コールは clone と exec です。なお、この問題はgo1.10では再発しません。 forkAndExecInChild 関数における go1.8 コードと go1.9 の違いを比較します。

1.8 に行く

1.9 へ

go1.9 では CLONE_VFORK と CLONE_VM が追加されました。 SIGCHILD のみを使用したクローン作成は、fork に似ていると考えられます (*** 両方とも do_fork を呼び出します)。 fork の問題は、親プロセスがより多くのメモリを占有するため、パフォーマンスが低下することです。詳細については、次のリンクを参照してください: https://bugzilla.redhat.com/show_bug.cgi?id=682922

このケースは 2011 年に提案され、今年 7 月時点でも更新中でした。この場合に反映される問題は、Linux カーネルがコピーオンライト メカニズムを導入したにもかかわらず、フォーク中にページ テーブルをコピーする必要があることです。プロセスの仮想メモリが大きいほど、コピーする必要があるページ テーブル エントリの数が多くなり、フォークが遅くなります。 Golang ディスカッション グループの誰かがテストしたところ、ヒープ サイズが 2G の場合、フォークにかかる時間はミリ秒単位まで短縮される可能性がある一方、通常は数十マイクロ秒であり、その差は数千倍にもなるとのことです。

Go1.9 では、子プロセスと親プロセスがメモリを共有できるようにするために、これら 2 つのパラメータが追加されました。これは、vfork を呼び出すのと同等です。ページテーブルをコピーする必要がないため、作成速度が速くなります。テスト結果から、数十マイクロ秒で安定しています。

したがって、go1.9 より前のバージョンで書かれたプログラムでは、プログラムのメモリ使用量が十分に大きく、プロセス作成の頻度が十分に高い場合、ForkLock は長時間待機することになるというのが妥当な推測です。

実験的デモンストレーション

go1.8.3 を使用してテスト プログラムを作成し、2 コア 4G 仮想マシン (カーネル 3.10.0-693.17.1.el7.x86_64) でテストしました。

10 秒ごとに、プログラムに SIGUSR1 信号が送信され、ランタイム スタックが印刷されます。しばらく実行すると、一部の goroutine では ForkLock を取得するのにかかる時間がどんどん長くなります。以下の2枚の写真をご覧ください。

ただし、go1.9以上では上記のような状況は発生しませんでした。この結果は問題を説明するのに十分だと思います。バージョンを go1.9 以上にアップグレードすると、この問題を解決できます。

***で書かれた

vfork は、ページ テーブル エントリをコピーするフォークによって発生するパフォーマンスの問題を解決するように設計されています。ほとんどのシナリオでは、exec は fork の後に呼び出されます。 Exec はすべてのページ テーブルを削除し、新しいページ テーブルをリセットします。ページ テーブル エントリを再度コピーする必要はまったくありません。ただし、vfork の親プロセスと子プロセスはメモリを共有するため、使用時には十分に注意する必要があります。子プロセスが変数を変更すると、親プロセスに影響し、カーネルは親プロセスを一時停止して、子プロセスを先に実行させます。これらの制限により、vfork は基本的に exec を使用するシナリオに制限され、fork ほど汎用的ではありません。

vfork は注意して使用する必要があり、go1.9 が vfork とともにリリースされる前に、rawVforkSyscall が戻った後も命令は親プロセス セグメントで実行されるため、子プロセスが両者の共有スタックを破壊する可能性があるため、コードが十分に堅牢ではないという意見がありました。そのため、図に示すように、この相互影響を解決するために、rawVforkSyscall が親プロセス セグメントで何もせず、戻った後に直接戻ることを許可するコミットが提案されました。

さらに詳しく知りたい場合は、Rob Pike 氏や他のユーザーがコメントしているこのコミットのレビューを参照してください。

https://go-review.googlesource.com/c/go/+/46173

<<:  クラウドコンピューティングの相互接続の未来とは?

>>:  アリババクラウドとHuyaが共同でライブストリーミング業界向けのエッジノードとクラウドエンタープライズネットワークサービスを初めて開始

推薦する

ブラックハットSEOとホワイトハットSEOは価値判断ではない

ブラックハット SEO は、短期間で成功したいと願う一部のウェブマスターがよく使用する戦術です。検索...

トラフィック制御の鍵: Traefik プロバイダーを理解するための 360 度ガイド

こんにちは、皆さん。私はルガです。今日は、クラウド ネイティブ ゲートウェイ エコシステムに関連する...

製品の観点から、SEO プロモーターとしての資格はありますか?

まず、疑問を提起したいと思います。ウェブサイトのプロモーションと社内の製品販売を組み合わせたSEO担...

#Cyber​​Monday# liteserver: 月額 2.5 ユーロ、KVM/1G メモリ/512G ハードディスク/6T トラフィック/オランダ データセンター

liteserver (2007~) オランダデータセンターのVPSの3大カテゴリはブラックフライデ...

ZoroCloud: 香港/米国 VPS、トリプルネットワーク CN2GIA+CUII、ネイティブ IP+高防御保護、30% 割引 - 月額 22 元から

Zorocloud では現在、米国 VPS と香港 VPS の特別プロモーションを実施しており、月払...

Amazon Elasticsearch Service が Amazon OpenSearch Service に

AWSは、クラウドサービス製品「Amazon Elasticsearch Service」の名称を「...

リーンでアジャイルなデザインの問題を解決するため、テンセントはデザインをクラウドに移行

[51CTO.com からのオリジナル記事] インターネット業界では、「車輪の再発明をするな」という...

企業サイトはキーワード密度を合理的に改善することで、最高の最適化効果を達成できます。

かつてはキーワード密度が非常に重要で、ウェブサイトのキーワードランキングに影響を与えるほどだったこと...

コンテナ クラウド プラットフォームは、どのようにリスクを管理し、主要なテクノロジ ルートを選択するのでしょうか?

序文コンテナクラウドプロジェクトは、当社がインフラクラウドコンピューティングPaaSプラットフォーム...

FSGP 企業 Weibo マーケティング エンターテイメント フレームワーク F フレームワーク - 戦い: 口論

ここ数ヶ月、私は企業がどのようにWeiboマーケティングを展開できるかを研究してきました。かつてA5...

Baidu Newsは新たな改訂を完了したが、一部のウェブサイトのデータ更新に影響する可能性がある。

Baidu 製品の改訂速度は加速しています。たとえば、数日前、Baidu MP3 が Baidu M...

dedipath: 旧正月、INAP VPS 4.9% オフ プロモーション、無制限トラフィック

Dedipath の INAP データ センターは、実際にはしばらく前から市場に出回っていますが、V...

hostflyte: Coresite データセンター cn2 gt シリーズ VPS、Windows 搭載、年間 18 ドルから、防御機能内蔵

Hostflyte の最新ニュース: 新しいデータセンター、ロサンゼルス CoreSite (AS3...

世界のインターネットの半分を麻痺させたこのエッジ クラウド コンピューティング企業とは誰でしょうか?

昨日、世界中のインターネット界は、それほど小さくない「ネットワーク停止」インシデントに遭遇しました。...

共同購入ウェブサイトの開発:勝利の戦略

2012年から2013年にかけて、共同購入ウェブサイトの数は雨後の筍のように急増しました。国際資本市...