2

Windows Azure Web ロールを実行していますが、ほとんどの日はトラフィックが非常に少ないのですが、実行する必要がある大量のバックグラウンド作業につながる可能性のある (予見可能な) イベントがいくつかあります。バックグラウンド作業は、多くのデータベース呼び出し (Azure SQL) と外部 Web サービスへの HTTP 呼び出しで構成されているため、実際には CPU を集中的に使用するわけではありませんが、データベースまたは Web サービスが応答するのを待機するスレッドが多数必要になります。バックグラウンド作業は、Web ロールへの通常の HTTP 要求によってトリガーされます。

これを調整するには 2 つのオプションがあると思いますが、どちらが優れているかはわかりません。

  • オプション 1、スレッド:バックグラウンド作業の要求が届くと、Web ロールは必要な数のスレッドを開始します (または、個々の作業項目をスレッド プールのキューに入れます)。このオプションでは、これらのスレッドが大量のメモリを必要とする可能性があるため、ワークロードが重い場合はより大きなインスタンスを構成します。
  • オプション 2、自己呼び出し:バックグラウンド作業の要求が来ると、それを受信する Web ロールは、バックグラウンド作業のすべての項目に対して自身への HTTP 要求を生成します。このオプションでは、複数の Web ロール インスタンスを構成できます。これは、Windows Azure のロード バランサーがインスタンス間で HTTP 要求のバランスを取るためです。

オプション 1 はやや単純ですが、1 つのインスタンスしかバックグラウンド作業を処理できないという欠点があります。複数の Azure インスタンスをバックグラウンド作業に参加させたい場合、ロード バランサーが作業の一部を他のインスタンスに委任できるように、役割からそれ自体に HTTP 要求を送信する以外に選択肢はありません。

多分他のオプションがありますか?

編集:オプション 2 に関するその他の考え: バックグラウンド作業の要求が来ると、それを受け取ったインスタンスは、何らかの種類のキュー (Windows Azure キューまたはタスクとして機能する SQL テーブル) で実行される作業を保存します。列)。次に、ロード バランサーがすべてのロール インスタンスを「アクティブ化」するように、それ自体に対して大量の HTTP 要求を生成します。次に、各インスタンスはキューからタスクをデキューしてタスクを実行し、すべてのタスクが完了するまで次のタスクをフェッチします。Web ロールを worker ロールとして時々使用するようなものです。

このアプローチには臭い (Web ロールをワーカー ロールとして悪用し、同じ Web ロールへの HTTP 要求) があることは承知していますが、本当の欠点はわかりません。

EDIT 2:アプリの正確な状況についてもう少し詳しく説明する必要があることがわかりました。

アプリは常にいくつかの小さなタスクを実行する必要があります。これらのタスクは通常、1 ~ 10 秒以上かかることはなく、多くの CPU 作業を必要としません。通常の日には 50 ~ 100 のタスクしかありませんが、「特別な日」 (正月はその 1 つです) には、1 ~ 2 の範囲内で実行する必要がある数 10,000 のタスクに入る可能性があります。時間ウィンドウ。タスクは Web ロールで実行され、毎分タスクを開始するCron ジョブがあります。そのため、Web ロールは新しいタスクを処理するためのリクエストを毎分受信するため、どのタスクを処理する必要があるかを確認し、それらをある種のキューに追加します (現在、これは OUTPUT INSERTED を使用した UPDATE を含む SQL テーブルですが、切り替える予定です)いつか Azure Queues に)。現在、同じインスタンスがタスクを処理しますそれらをキューに入れた直後ですが、数万のタスクの連続処理には時間がかかりすぎるため、これはスケーリングしません。これが、 「タスクが利用可能です」というイベントを最初のインスタンスから他のインスタンスにブロードキャストするメカニズムを探している理由です。

4

4 に答える 4

3

作業の分散にキューを使用することを検討しましたか?処理が必要な「タスク」をキューに入れて、多くのワーカープロセスに作業を分散させることができます。

アプローチ1で見られる問題は、これを「スケールアウト」パターンではなく「スケールアップ」パターンとして見ていることです。1つの大きなインスタンスの代わりに多くの小さなVMインスタンスをデプロイすることで、スケーラビリティと可用性が向上します。さらに、あなたの仕事はCPUを集中的に使用しないとおっしゃいました。X-Smallインスタンスを検討する場合、1つのSmallインスタンス($ 0.12 /時間)のコストで6つのX-Smallインスタンス($ 0.02 /時間)をデプロイでき、同様に1つのLargeインスタンス($ 0.48)のコストで24をデプロイできます。 X-小さなインスタンス。

さらに、「スケールアウト」パターンの場合は、インスタンスを追加または削除するだけで簡単にスケールアウトできます。VMサイズを変更しているため、「スケールアップ」(または「スケールダウン」)パターンの場合、パッケージを再デプロイすることになります。

申し訳ありませんが、少し接線方向に行った場合:)これがお役に立てば幸いです。

于 2012-10-15T08:42:26.033 に答える
2

Azure Queue のオプションの 1 つを検討することについて、Gaurav や他の人たちに同意します。これは、問題をきれいに分離しながら、負荷をスムーズにするのに非常に便利なパターンです。

この基本的な Queue-Centric Workflow (QCW) パターンでは、Web ロールの HTTP 要求 (明らかに wget を呼び出す cron ジョブを介して実行される、作業をトリガーするメカニズム) の処理において、作業要求がキューに置かれます。次に、Web ロールの IIS Web サーバーは、HTTP 要求の処理という最も得意とすることを続けます。ロード バランサーからのサポートは必要ありません。

Web ロールは、リクエストが来るとすぐに受け入れる必要がありますが (それぞれのメッセージをキューに入れます)、デキュー部分はプルであるため、使用可能な容量 (または負荷に合わせて調整された容量) に合わせて負荷を簡単に調整できます! これがクラウドです!)。これらを一度に 1 つずつ処理するか、一度に 2 つずつ処理するか、または一度に N 個ずつ処理するかを選択できます。テスト (サイズ設定の演習) でわかることは、展開する VM のサイズに適しています。

お気づきかもしれませんが、Web ロールの RoleEntryPoint::Run メソッドを実装して、継続的に作業を行うこともできます。Web ロールの既定の実装は基本的に永久にスリープしますが、無限ループを実装してキューにクエリを実行し、作業を削除して処理することができます (キューからメッセージが利用できない場合は必ずスリープすることを忘れないでください! そうしないと失敗します)お金の漏れを引き起こし、あなたが絞られるかもしれません)。Gaurav が言及しているように、この QCW パターンを堅牢に実装するには、他にもいくつかの考慮事項があります (ノードに障害が発生した場合、または悪い (「毒」) メッセージ、コードにバグがある場合など)。ただし、ユースケースはそうではありません。 cron ジョブからの次のキックが原因であると思われるため (まれに、

アイテムをキューに配置することと、キューからアイテムを処理することを分離することは、実際には論理的な設計ポイントです。つまり、いつでもこれを変更して、本質的な設計の一部を壊すことなく、処理側 (キューからプルするコード) を別のアプリケーション層 (サービス層) にかなり簡単に移動できるということです。これにより、多くの柔軟性が得られます。ほとんどの場合 (2 層)、1 つの Web ロール ノード (SLA が必要な場合は 2 つ - コメントの一部に基づいて行うかどうかはわかりません) ですべてを実行し、必要に応じて追加することで 3 層にすることもできます。新年などの一連の処理 VM。

処理ノードの数は、環境からの信号に基づいて動的に調整することもできます。たとえば、キュ​​ーの長さが増加している場合、またはしきい値を超えている場合は、処理ノードを追加します。これがクラウドであり、この機械は完全に自動化できます。

私はあなたのアプリについてあまり知らないので、今はもっと推測しています...

前述の Run メソッドを使用することで、cron ジョブも排除し、無限ループでその作業を実行できる場合があります。もちろん、これはcronスケジューリングの複雑さに依存します。または、cron ジョブで作業要求アイテムをキューに直接配置することで (おそらくSDK の 1 つを使用して)、Web 層全体 (Web ロール) を排除することもできます。要求を処理するためのコードはまだ必要です。もちろん、これは Web ロールでもかまいませんが、その時点で Worker ロールを簡単に使用できます。

于 2012-10-16T01:28:38.873 に答える
2

[SOがチャットモードに切り替えるように言わないように別の回答として追加+コメントの長さの制限をバイパス]&大声で考えます:)

あなたの言ってる事がわかります。基本的に HTTP リクエストを介して、処理する新しいタスクの可用性を他のインスタンスにブロードキャストするようなものです。

したがって、私が正しく理解していれば、インスタンスが処理するタスクの要求を受け取ると、その要求をある種のキューにプッシュします (あなたが言及したように、Windows Azure キュー [個人的には実際にそれを好む] または SQL Azure データベースのいずれかである可能性があります)。 [独自のメッセージ ロック アルゴリズムを実装する必要があるため、これは好ましくありません]) そして、いくつかの作業を行う必要があるすべてのインスタンスにメッセージをブロードキャストします。残りのインスタンス (またはそれをブロードキャストしているインスタンス) は、そのタスクを自由に処理できるかどうかを確認できます。可用性に応じて、1 つのインスタンスがキューからタスクをフェッチし、そのタスクの処理を開始できます。

Windows Azure キューを使用したと仮定すると、インスタンスがメッセージをフェッチすると、しばらくの間 (Azure キューの可視性タイムアウト期間) すぐに他のインスタンスがメッセージを使用できなくなり、タスクの重複処理が回避されます。タスクが正常に処理された場合、そのタスクで作業しているインスタンスはメッセージを削除できます。

何らかの理由でタスクが処理されない場合、表示タイムアウト期間が経過すると、タスクは自動的にキューに再表示されます。ただし、これは別の問題につながります。インスタンスはポーリングではなくトリガー (HTTP リクエストの生成) に基づいてタスクを探すため、すべてのタスクが確実に完了するようにするにはどうすればよいでしょうか? 1 つのタスクと 1 つのタスクのみを処理することができ、2 番目のタスクを処理する要求を受け取っていないために失敗したと仮定すると、1 番目のタスクは二度と処理されません。明らかに、実際の状況では発生しませんが、考えたいことがあります。

これは理にかなっていますか?

于 2012-10-15T10:21:48.040 に答える
1

私は間違いなく、スケールアウト ソリューションを選びます。複雑さが軽減され、管理しやすく、価格も手頃です。さらに、展開が失敗した場合のダウンタイムのリスクが少なくなります (もちろん、障害ドメインとアップグレード ドメインのメカニズムがそれをカバーする必要がありますが)。その点で、私はこれについてGauravを完全に支持します!

于 2012-10-15T10:38:57.190 に答える