1. ホーム
  2. multithreading

[解決済み] スレッドは何本までならOK?

2022-03-15 18:56:15

質問

私はサーバーを書いていて、リクエストを受信したときに、それぞれのアクションを別のスレッドに送ります。これは、ほとんどすべてのリクエストがデータベースクエリを作成するためです。私はスレッドの構築/破壊を削減するためにスレッドプールライブラリを使用しています。

質問ですが、このようなI/Oスレッドの良い切り口は何でしょうか?大まかな見積もりになると思いますが、何百という数でしょうか?数千?

このカットオフ値を知るにはどうしたらいいでしょうか?


EDITです。

皆さん、回答ありがとうございます!自分の糸数の上限を知るには、テストするしかないようです。しかし、問題は、どのように私はその天井に当たったことを知ることができますか?具体的に何を測定すればいいのでしょうか?

解決方法は?

ある人はこう言うでしょう。 スレッドが多すぎるということですが、私はそうは思いません:-)

私からのアドバイスです。 測定し、推測しない。 一つの提案は、設定可能にして、最初は100に設定し、ソフトウェアを野に放ち、何が起こるかを監視することです。

スレッド使用量のピークが3であれば、100は多すぎです。一日中100のままなら、200に上げてどうなるか見てみましょう。

あなたは かもしれない 実際には、コード自体が使用状況を監視し、次回の起動時に設定を調整するようにしますが、それはおそらく過剰な作業です。


明確化・精緻化のために。

私は、独自のスレッドプーリングサブシステムを開発することを推奨しているわけではありません。しかし、スレッドの良いカットオフポイントについて質問されているので、スレッドプールの実装には、作成されるスレッドの最大数を制限する機能があると仮定します(これは良いことです)。

私はスレッドとデータベース接続プーリングのコードを書いたことがありますが、それらは次のような特徴を持っています(これらはパフォーマンスにとって不可欠なものだと思います)。

  • 最小限のアクティブなスレッド数。
  • スレッドの最大数。
  • しばらく使用されていないスレッドをシャットダウンする。

1つ目は、スレッドプールクライアントの観点から、最小限のパフォーマンスの基準値を設定します(この数のスレッドは常に使用可能です)。2つ目は、アクティブなスレッドによるリソースの使用制限を設定します。3番目は、リソースの使用を最小限に抑えるために、静かな時間帯にベースラインに戻します。

未使用のスレッドを持つことによるリソース使用量(A)と、作業に必要なスレッドが足りないことによるリソース使用量(B)のバランスを取る必要があります。

(A)は一般的にメモリ使用量(スタックなど)であり、何もしないスレッドはCPUをあまり使用しません。(B)は一般的に、スレッドが利用可能になるのを待つ必要があるため、到着したリクエストの処理に遅れが生じます。

だから計測するんですね。おっしゃるとおり、スレッドの大半はデータベースからの応答を待っているため、実行されることはないでしょう。スレッドの数に影響を与える要因は2つあります。

1つ目は、利用可能なDBコネクションの数です。この場合、DBMSは無制限に接続できると仮定します(ただし、理想的には接続数も測定する必要があります)。

それから、持つべきスレッドの数は、過去の使用状況によって異なります。最低限動作させるべきスレッド数は、過去に動作させた最小数+A%で、絶対最小数は(例えば、A同様に設定可能な)5となります。

スレッド数の最大値は、過去の最大値+B%とします。

また、動作の変化も監視する必要があります。何らかの理由で使用率が100%になる時間が長くなった場合(クライアントのパフォーマンスに影響するような場合)、再びB%高くなるまで最大許容値を引き上げる必要があります。


具体的に何を測ればいいのか、という質問に対して。

具体的に測定すべきは、負荷がかかった状態で同時使用(DB呼び出しからの戻り待ちなど)するスレッドの最大量です。そして、10%の安全係数を追加して (他の投稿者は私の例を固定的な推奨とみなしているようなので、強調しています)。

また、チューニングのため、本番環境で行う必要があります。事前に見積もりを取るのはいいのですが、本番が何を投げてくるかわかりません(だからこそ、これらのことはすべて実行時に設定可能であるべきなのです)。これは、予期せぬクライアントコールが2倍になって入ってくるような状況をキャッチするためです。