あまりにも多くのバックグラウンドジョブを開始するとどうなりますか?


13

Expectスクリプトを使用して、700個のネットワークデバイスで作業を行う必要があります。順番に実行できますが、これまでの実行時間は約24時間です。これは主に、接続の確立にかかる時間と、これらのデバイス(古いデバイス)からの出力の遅延が原因です。2つの接続を確立し、それらを正常に並列に実行することはできますが、どこまでプッシュできますか?

700個すべてを一度に実行できるとは思いませんが、noにはある程度の制限があります。VMが管理できるTelnet接続の数。

このようなループで700個を開始しようとした場合:

for node in `ls ~/sagLogs/`; do  
    foo &  
done

  • CPU 12 CPU x Intel(R)Xeon(R)CPU E5649 @ 2.53GHz

  • メモリ47.94 GB

私の質問は:

  1. 700のインスタンスすべてをおそらく同時に実行できますか?
  2. サーバーが制限に達するまで、どこまで到達できますか?
  3. その制限に達すると、次の反復の開始を待つだけfooですか、それともボックスがクラッシュしますか?

残念ながら企業の実稼働環境で実行しているので、何が起こるかを正確に試すことはできません。


3
parallel約50の同時実行ジョブを使用して、幸運に恵まれました。これは、1から700の並列処理の間の優れた媒体です。他の良い点は、バッチレスです。停止した単一の接続は、それ自体のみを停止させ、他の接続は停止させません。主な欠点はエラー管理です。これらのシェルベースのアプローチはどれもエラーを適切に処理しません。自分で成功を手動で確認し、自分で再試行する必要があります。
アダム

1
現在、タスクキューは700ですが、サイズを拡張できますか?スワップ領域が大きくなるのを監視します-これは、メモリ制限に達したことを示しています。また、cpu%は(linux / unixの)適切な測定値ではなく、負荷平均(実行キューの長さ)を考慮する方が適切です。
ChuckCottrill

1
私がまだ新しい仕事で生産を中断した最も最近の方法は、100万件以上の短命のバックグラウンドジョブを一度に誤って実行することでした。それらはJVMに関係していたので(待機を待ってピッチフォークを停止)、結果はスレッドを開始できなかった数十万のエラーレポートファイルに「限定」されました。
michaelb958--GoFundMonica


1
@KuboMDそして、誰もあなたのコードを使いたくない限り。
l0b0

回答:


17

700のインスタンスすべてをおそらく同時に実行できますか?

それはあなたが同時に意味するものに依存します。私たちがうるさいなら、利用できません(おそらくそうではありません)。ただし、システム上に十分なRAMやスワップスペースがあれば、現実的には可能です。UNIXとそのさまざまな子供たちは、膨大なレベルの同時実行性の管理に非常に優れているため、大規模なHPCの使用で非常に人気があります。

サーバーが制限に達するまで、どこまで到達できますか?

これは、さらに多くの情報なしに具体的に答えることは不可能です。ほとんどの場合、満たすのに十分なメモリが必要です。

  • 1つのジョブのランタイムメモリ要件全体、700倍。
  • その数のジョブを管理するためのbashのメモリ要件(bashはこれについて恐ろしいことではありませんが、ジョブ制御はメモリ効率がよくありません)。
  • システム上のその他のメモリ要件。

あなたがそれを満たしていると仮定すると(再び、わずか50GBのRAMで、あなたはまだ他の問題に対処する必要があります:

  • ジョブ制御のbashによって無駄になるCPU時間はどれくらいですか?おそらくそれほど多くはありませんが、何百もの仕事があるため、それは重要です。
  • これに必要なネットワーク帯域幅はどれくらいですか?これらすべての接続を開くだけで、帯域幅と待機時間に応じて、ネットワークが数分間圧倒される場合があります。
  • 私がおそらく考えもしなかった他の多くのこと。

その制限に達すると、fooから次の反復を開始するのを待つだけですか、それともボックスがクラッシュしますか?

どの制限に達するかによります。メモリの場合、システム上で何かが死ぬ(具体的には、メモリを解放しようとしてカーネルに殺される)か、システム自体がクラッシュする可能性があります(メモリ不足時に意図的にクラッシュするようにシステムを構成することは珍しいことではありません)。CPU時間の場合、問題なく動作し続けるだけで、システムで他のことを実行することは不可能です。ネットワークの場合は、他のシステムまたはサービスがクラッシュする可能性があります。


あなたが本当にここで必要なのは、同時にすべてのジョブを実行することではありません。代わりに、それらをバッチに分割し、バッチ内のすべてのジョブを同時に実行し、終了させて​​から次のバッチを開始します。これにはGNU Parallel(https://www.gnu.org/software/parallel/)を使用できますが、実稼働環境ではその規模では理想的とは言えません(それを使用する場合は、あまり攻撃的になりすぎないでください。私が言ったように、あなたはネットワークを圧倒し、さもなければ触れないシステムに影響を与えるかもしれません)。Ansible(https://www.ansible.com/のような適切なネットワークオーケストレーションツールを検討することをお勧めします。)、同時実行の問題を解決するだけでなく(Ansibleは上記のようにバッチ処理を自動的に行います)、他の多くの便利な機能(タスクのべき等の実行、素敵なステータスレポート、ネイティブの統合など)を提供します非常に多くの他のツール)。


(bash、perl、pythonなどを使用して)限られた数のバックグラウンドタスクを実行し、タスクの完了を監視し、以前のタスクが完了するとより多くのタスクを実行する方法があります。簡単なアプローチは、サブディレクトリ内のファイルで表されるタスクのバッチを収集し、一度にバッチを処理することです。他の方法もあります
...-ChuckCottrill

これにはUnixライクなシステムも含まれますか?そして、「ガンパラレル」とは何ですか?
ビスワプリヨ

2
@ChuckCottrillはい、これを実現する方法は他にもあります。このタイプのことを扱った私自身の経験を考えると、特に規模に関して数十のシステムを過ぎた後は、ほとんどの場合、実際のオーケストレーションツールを入手する方が、独自のソリューションを試すよりも優れています。
オースティンヘメルガルン


3
@森林これらのジョブが引き起こす可能性のある影響からネットワークの残りの部分(おそらくローカルシステムをクラッシュさせるよりも潜在的にはるかに大きな問題です)。
オースティンヘメルガルン

12

説明した方法でバックグラウンドジョブとして実行できるインスタンスの数を具体的に言うのは困難です。ただし、通常のサーバーでは、正しく実行する限り、700の同時接続を確実に維持できます。Webサーバーは常にこれを行います。

GNUパラレル(https://www.gnu.org/software/parallel/)またはこれに似た何かを使用してこれを達成することをお勧めしますか?バックグラウンドジョブアプローチには多くの利点があります。

  • 同時セッションの数は簡単に変更できます。
  • そして、新しいセッションを開始する前に、セッションが完了するまで待機します。
  • 中止するのが簡単です。

クイックスタートについてはこちらをご覧くださいhttps : //www.gnu.org/software/parallel/parallel_tutorial.html#A-single-input-source


1
面白い!これを見てみましょう。(Parallelの助けを借りずに)この種の操作を試みると、ハイパーバイザーがクラッシュするリスクがあるかどうかを知っていますか?
KuboMD

2
@KuboMDとてもありふれたものでハイパーバイザーをクラッシュできるなら、それはハイパーバイザーのバグです:)
hobbs

余談ですが、Webサーバーは多くの場合、スレッド処理またはイベントベースの処理を使用します(例:gunicorn.org
ChuckCottrill

10

&並列処理に使用することは、いくつかのことを行うとき、および進行状況を監視するときに問題ありません。ただし、企業の実稼働環境で実行している場合は、より適切に制御できるものが必要です。

ls ~/sagLogs/ | parallel --delay 0.5 --memfree 1G -j0 --joblog my.log --retries 10 foo {}

これはのfoo各ファイルに対して実行されます~/sagLogs。0.5秒ごとにジョブを開始し、1 GBのRAMが空いている限りできるだけ多くのジョブを並行して実行しますが、システムの制限(ファイルやプロセスの数など)を尊重します。通常、これは、許可されているオープンファイルの数を調整していない場合、250のジョブを並行して実行することを意味します。開いているファイルの数を調整する場合、十分なメモリがある限り、32000を並行して実行しても問題ありません。

ジョブが失敗した場合(つまり、エラーコードを返します)、10回再試行されます。

my.log ジョブは(場合によっては再試行後に)成功するかどうかを通知します。


これは非常に有望に見えます、ありがとう。
KuboMD

簡単なテストを実行しcat ~/sagLogs/* >> ~/woah | parallel、高速で神聖なモリーを実行しました。瞬きする1,054,552行。
KuboMD

3
あなたが与えたコマンドは二重のリダイレクトを持っているので、私はそれがあなたが意図したことをしないと思います。GNU Parallelはジョブごとに10ミリ秒のオーバーヘッドがあるため、1Mのジョブには3時間程度かかります。
オレ丹下

1
単にファイルを連結するだけの場合は、まったく適用されません。
オレ丹下

1
@KuboMDのような些細なCPUビジーループは、いじくり回すのに有効awk 'BEGIN{for(i=rand()*10000000; i<100000000;i++){}}' です。または、多くのCPU時間を使用せずにジョブを実行中sleep 10に保つようなタスクで試してみてくださいn。たとえばtime parallel sleep ::: {100..1}、100から1秒までスリープを実行します。
ピーター・コーデス

1

あまりにも多くのバックグラウンドジョブを開始するとどうなりますか?

システムは遅くなり、応答しなくなります。最悪の場合は応答しないため、電源ボタンを押してハードリブートを実行することをお勧めします。bashスクリプトが通常のユーザー権限で実行されている場合、最初に頭に浮かぶのは/etc/security/limits.conf/etc/systemd/system.confおよびその中のすべての変数が[理想的に言えば] ユーザーにシステムのオーバーロードを防ぐことです。

  • cpu = xeon E5649、つまり12 コアの CPU。したがって、12のプロセスの12のコアを同時に実行し、それぞれが12のコアの1つを100%使用します。24個のプロセスを開始すると、12個のコアのそれぞれで50%の使用率で実行されます。700プロセス= 1.7%ですが、すべてが正常な時間内に正常に完了する限り、それは成功です。効率的であることは、常に関連するとは限りません。

    1. 700のインスタンスすべてをおそらく同時に実行できますか? 確かに、700は大きな数字ではありません。/etc/security/limits.confのmaxprocデフォルトは、たとえば4,135,275です

    2. サーバーが制限に達するまで、どこまで到達できますか? 700をはるかに超えると確信しています。

    3. 制限 ...スクリプトがユーザーアカウントで開始された場合 [そして、一般的にルートlimits.confはすべてのユーザーにほぼ適用されます]、foo &700回実行しようとするとスクリプトが終了します。それぞれ異なるpidを持つ700個のfooプロセスが表示されますが、456(乱数の選択)のみが表示され、他の244はセキュリティまたはsystemdの制限によりブロックされたため開始されません。

百万ドルの質問:いくつ同時に実行する必要がありますか?

ネットワークに関与していて、それぞれがtelnet接続を行うと言いましたが、CPUとRAMの制限を行う前に、ネットワークの制限とオーバーヘッドに遭遇するでしょう。しかし、あなたが具体的に何をしているのかわかりません、おそらく何が起こるかは、一度に700個すべてを開始することができますが、前のプロセスとネットワーク接続が終了し、さまざまなシステム制限または最初の500はキックオフしますが、残りの200はシステムまたはカーネルの制限により禁止されます。しかし、多くの人が一度に走ったとしても、甘いものがあるでしょうできる限り速く物事を成し遂げるスポット...オーバーヘッドを最小限に抑え、効率を向上させます。12コア(2 CPUの場合は24)であるため、一度に12(または24)から始め、実行時間の改善が見られなくなるまで、その同時バッチ数を12または24増やします。

ヒント: Googleの最大telnet接続を調べて、これがシステムにどのように適用されるかを確認してください。また、ファイアウォールについても忘れないでください。また、プロセスごとに必要なメモリの迅速な計算x 700; <使用可能なRAM(あなたの場合は約50GB)を確認してください。そうしないと、システムはSWAPの使用を開始し、基本的に応答しなくなります。そのため、12、24、Nのプロセスを一度に起動し、RAMを無料で監視します。その後、Nを増やして、何が起きているかをある程度知っています。

デフォルトでは、RHELは単一ホストからのTelnet接続の数を10の同時セッションに制限します。これはセキュリティ機能です... 10に設定、/ etc / xinetd.conf、「per_source」値を変更します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.