2013-02-04 8 views
7

現在、私の会社で稼働しているWindowsサービスをスケールアウトする方法についていくつかの情報を探しています。私たちは、.NET 4.0を使用して(と将来のある時点で4.5にアップグレードされます可能)およびWindows Server 2012Windowsサービスのスケールアウト

サービスの仕事は、新しい行を照会することです
サービスについて上でこれを実行していますロギング・テーブル(Oracleデータベースを使用しています)、情報の処理、5つのテーブルの行の作成と更新(トラッキング・テーブルと呼ぶ)、ロギング・テーブルの更新と繰り返しを行います。

ロギングテーブルには、他の5つのトラッキングテーブルで選択して保存する必要がある大量のXMLがあります(行ごとに最大20 MBになる可能性があります)。新しい行は、1時間に最大50万行の割合で常に追加されます。
トラッキングテーブルのトラフィッキングは、最小のもので90,000の新しい行から、最大のテーブルの潜在的に何百万までの行まで、非常に高くなります。これらのテーブルに対してもUpdate操作があることは言うまでもありません。
を処理されているデータについて

私はこのビットは、これらのオブジェクトがグループ化されて処理される方法に基づいて解決策を見つけるために重要であると感じています。データ構造は次のようになります。

public class Report 
{ 
    public long Id { get; set; } 
    public DateTime CreateTime { get; set; } 
    public Guid MessageId { get; set; } 
    public string XmlData { get; set; } 
} 

public class Message 
{ 
    public Guid Id { get; set; } 
} 
  • 報告書は、平均5つのレポートにあるすべてのメッセージのログ、私が選択するために必要なデータやプロセス
  • です。これは、場合によっては1から数百までの間で変化し得る。
  • メッセージには他のコレクションやその他の関係がありますが、質問とは関係ありません。

今日はやっと16コアサーバーの負荷を管理し、我々が持っているWindowsサービスは、(私は完全な仕様を覚えていないが、それはこのマシンは獣であると言うことは安全です)。私はスケールアウトし、このすべてのデータを処理し、他のインスタンスを妨害しないようなマシンを追加する方法を見つけることが任されています。

現在、各メッセージは独自のスレッドを取得し、関連するレポートを処理します。我々は、データを処理する際にDBクエリーの数を最小限に減らすために、MessageIdによってグループ化されたバッチでレポートを処理します。この段階で

制限

  • 私は私が合う任意のアーキテクチャを使用して、最初から書き直すこのサービスさせて頂いております。
  • インスタンスがクラッシュした場合、他のインスタンスはクラッシュしたものがどこに残っているかを確認する必要があります。データが失われることはありません。
  • この処理は、レポートがデータベースに挿入されてからできるだけリアルタイムで実行する必要があります。

私は、このようなプロジェクトをビルドする方法上の任意の入力やアドバイスを探しています。私はサービスがステートレスである必要があると思うか、あるいは何とかすべてのインスタンスのためにキャッシュを同期させる方法がありますか?すべてのインスタンスをどのように調整し、同じデータを処理していないことを確認する必要がありますか?どのように負荷を均等に分配できますか?もちろん、インスタンスをクラッシュさせ、その作業を完了させないようにするにはどうすればいいですか?あなたの作業項目に関しては無関係な情報

+0

これはETLプロセスのように聞こえます。 SQL Server Integration Services(SSIS)のようなものを見て、このプロセスを定期的に実行するようスケジュールを設定できるパッケージを作成することを検討しましたか? –

+0

私たちはOracleを使用していますが、上位のユーザーは残念ながらSQL Serverに関する言葉を聞きたくありません。 – Artless

+0

私はSSISの部分だけを考えていましたが、データベースエンジンではありません:)代替案はPentaho Data Integration(http://www.pentaho.com/explore/pentaho-data-integration/)やTalend etl analytics http://www.talend.com/solutions/etl-analytics) –

答えて

0

私は自分自身ですべてのこの拡張性と冗長性のものをコーディングすることによって、これを解決しました。誰かがこれを必要とするなら、私が何をしたか、どうやってそれをやったのかを説明します。

私は、各インスタンスでいくつかのプロセスを作成して、他のプロセスを追跡し、特定のインスタンスが処理できるレコードを把握しました。起動時に、インスタンスはInstancesというテーブルにデータベースに登録されます(まだ存在しない場合)。

Id     Number 
MachineName  Varchar2 
LastActive   Timestamp 
IsMaster   Number(1) 

登録すると、インスタンスのMachineNameが見つからなかった場合は、このテーブルの行を作成した後、インスタンスはそのLastActive列を更新し、別のスレッドで毎秒このテーブルにpingを開始します。このテーブルには、次の列があります。次に、このテーブルからすべての行を選択し、(それ以降はそれ以上)がまだ生きていることを確認します。つまり、LastActiveの時間は過去10秒間です。マスター・インスタンスが応答を停止した場合、マスター・インスタンスは制御を引き継いでマスターとして設定されます。次の反復では、マスターが1つだけ存在することを確認します(別のインスタンスが同時に制御を引き継ぐことを決定した場合)。そうでない場合は、最も小さいインスタンスのインスタンスがIdになります。

マスターインスタンスとは何ですか?
サービスの仕事は、ロギングテーブルをスキャンしてそのデータを処理して、人々が簡単にフィルタリングして読むことができるようにすることです。私は私の質問でこれを述べなかったが、ここでは関連性があるかもしれない。リクエストごとに複数のレコードをロギングテーブルに書き込むESBサーバーがたくさんあります。私のサービスの仕事は、それらをほぼリアルタイムで追跡することです。彼らはログを非同期的に書き込んでいるので、ログにstarted processing request Aのエントリの前に潜在的にfinished processing request Aを得ることができます。だから、私はそれらのレコードを並べ替えるいくつかのコードを持って、私のサービスが正しい順序でデータを処理することを確認します。このサービスをスケールアウトする必要があったため、不要なDBクエリや非常に厄介なバグを避けるために、このロジックを実行できるインスタンスは1つだけです。
ここにMaster Instanceが入っています。このソートロジックを実行し、ログレコードIDをReportAssignmentという別のテーブルに一時的に保存します。このテーブルの仕事は、処理されたレコードと誰によって処理されたレコードかを追跡することです。処理が完了すると、レコードは削除されます。テーブルは次のようになります。

RecordId  Number 
InstanceId  Number Nullable 

マスターインスタンスはログエントリをソートし、そのIDをここに挿入します。すべてのサービスインスタンスは、誰にも処理されていない、または非アクティブインスタンスによって処理されている新しいレコードと、(Ping処理中に取得された)[record's Id] % [number of isnstances] == [index of current instance in a sorted array of all the active instances]という新しいレコードに対して、このテーブルを1秒間隔でチェックします。クエリは次のようになります。

SELECT * FROM ReportAssignment 
WHERE (InstanceId IS NULL OR InstanceId NOT IN (1, 2, 3)) // 1,2,3 are the active instances 
AND RecordId % 3 == 0 // 0 is the index of the current instance in the list of active instances 

なぜこれを行う必要がありますか?

  • 他の2つのインスタンスはRecordId % 3 == 1RecordId % 3 == 2を照会します。
  • RecordId % [instanceCount] == [indexOfCurrentInstance]レコードがすべてのインスタンス間で均等に分散されるようにします。
  • InstanceId NOT IN (1,2,3)は、インスタンスがクラッシュしたインスタンスによって処理されていたレコードを引き継ぎ、新しいインスタンスが追加されたときにすでにアクティブなインスタンスのレコードを処理しないようにします。

インスタンスがこれらのレコードを照会すると、InstanceIdを独自に設定し、これらのIDを持つレコードのログテーブルを照会する更新コマンドを実行します。処理が完了すると、レコードはReportAssignmentから削除されます。

全体的に私はこれに非常に満足しています。それはうまくスケーリングされ、インスタンスがダウンしてもデータが失われないようにし、既存のコードにはほとんど変更がありません。

6

削除

EDIT
、Windowsワークフローは、おそらくあなたのサービスをリファクタリングするあなたの最速手段です。

Windows Workflow Foundation @ MSDN

あなたはWFから抜け出すだろう最も有用なものは何でも、それがあった時に最後の点からワークフローに起こるべき適切に設計されたワークフローは、持続時点から再開されるワークフローの永続性であり、保存されました。

Workflow Persistence @ MSDN

ワークフローを処理しつつ、別のプロセスから回収されるワークフローの能力べき他のプロセスがクラッシュを含みます。共有ワークフローストアを使用する場合、再開プロセスは同じマシン上にある必要はありません。すべての回復可能なワークフローでは、ワークフローストアを使用する必要があります。

作業の配布には、いくつかのオプションがあります。

  1. WorkflowServiceクラスを介してWCFエンドポイントを使用して、ワークフローの呼び出しを介してバランシングホスト・ベースのロードと組み合わせてメッセージを生成するサービス。手動でReceiveと対応するSendReplyハンドラ(これらはWCFメソッドにマップされます)を手動で設定するのではなく、ここでデザインモードエディタを使用してエントリメソッドを構築したいとします。あなたはおそらくすべてのメッセージのためにサービスを呼び出すだろうし、おそらくまたすべてのレポートのためにサービスを呼び出すだろう。ここではCanCreateInstanceプロパティが重要です。それに関連付けられたすべての呼び出しは、独立して実行される実行中のインスタンスを作成します。

    WorkflowService Class (System.ServiceModel.Activities) @ MSDN
    Receive Class (System.ServiceModel.Activities) @ MSDN
    Receive.CanCreateInstance Property (System.ServiceModel.Activities) @ MSDN
    SendReply Class (System.ServiceModel.Activities) @ MSDN

  2. キューをサポートしているサービス・バスを使用してください。最低でも、任意の数のクライアントからの入力を潜在的に受け入れ、その出力が一意に識別され、一度だけ処理される可能性のあるものが必要です。頭に浮かぶのはNServiceBus、MSMQ、RabbitMQ、ZeroMQです。ここに記載されている項目のうち、NServiceBusは排他的に.NETですぐに使用できます。クラウド環境では、Azure Service BusやAmazon SQSなどのプラットフォーム固有のサービスもオプションとして用意されています。サービス・バスは、メッセージを開始しますプロデューサーおよび任意の上に存在することができ、消費者の間だけで接着剤であることを

    NServiceBus
    MSMQ @ MSDN
    RabbitMQ
    ZeroMQ
    Azure Service Bus @ MSDN
    Amazon SQS @ Amazon AWS

    注意キューから読み取るマシンの数。同様に、このインダイレクションをレポート生成に使用できます。コンシューマーはワークフローインスタンスを作成し、ワークフローインスタンスを作成してワークフローの永続性を使用することができます

  3. Windows AppFabricを使用してワークフローをホストすることができ、IIS負荷分散に適用される多くの手法を使用して作業を分散できます。私は個人的にそれを経験しているわけではないので、すぐに使えるモニタリングのサポートが他にありません。

    How to: Host a Workflow Service with Windows App Fabric @ MSDN
+0

ありがとう!私はいくつかの読書とテストをしなければならず、私の会社が何をしたいのかを見なければならない。 – Artless

+1

あなたの質問に対するレポート解説コメントにあなたのコメントが与えられたら、WFに同梱されている永続ストアはMS SQL Serverに依存していることを警告する必要があります。 MSSQLインスタンスをセットアップする必要がないように、永続ストアとして動作するMSDEを入手できるかどうかを確認することは価値があります。 – meklarian