2016-11-25 7 views
2

JavaScriptベースのWebアプリケーションをいくつか実行しています。各アプリケーションは、使用イベントログ(さまざまなクリックイベントの記録)を作成します。私はasp.netのWeb APIを使用してSQLデータベースにこれらのすべてのイベントを記録したい。データベースにイベントログを格納するためのキューを持つAsp.net Web API

  1. を各メッセージには、4-5のプロパティ(名前、eventTypeを、AppIDを、ペイロードは、ユーザーID)を持つことになります。ここでは

    は考慮すべき重要なポイントです。ペイロードはJSON形式のオブジェクトです。これにより、データベースにオブジェクトを文字列形式で格納することができます

  2. ピークロード時にユーザーが毎分1000-1500メッセージを送信することを期待しています。
  3. 私は一度エンドポイントがメッセージを受け取ったら、メッセージをキュー&に入れ、MSSQL DBにメッセージを保存します。ここで

は私の質問です:

  1. それは、クライアント側のメッセージをキューして、20件のメッセージまたはすべての3分後にバッチでイベントを送信することは理にかなってい。これにより、ネットワークとWeb APIに余分な負荷がかかりません。
  2. メッセージサイズを考慮すると、1分あたりのメッセージ数はありません。この場合、メモリキューで使用するのは理にかなっていますか?私は本当に高速のキューを望んでいます&サードパーティのキューソリューションへの依存を避けたいです。メッセージの順序を維持する必要はありません。
  3. Webサーバーを再起動すると、99%の稼働時間があると考えても問題ありません。
  4. 複数のコンシューマ(すべて同じことを行う、テーブルにデータを書き込む)、または単一のコンシューマのみが必要ですか。
  5. 各メッセージの閉じる接続を開くのではなく、SQL接続を開いたままにする方法はありますか。
+2

を挿入あなたは本当にSQL Serverの中で、これを保存したいですか?クエリはそれほど簡単ではないかもしれません。ペイロードはどのようにフォーマットされていますか?あなたはnosqlソリューションを考えましたか?どのプロセスがキューを処理しますか?私は別のプロセスでそれをやります。通常、私はこのようなもののためにAzure EventHubのようなものを使うことを提案します。 –

+0

@PeterBons彼のアプリはすべてJavascriptになっているので、私はGoogle Analyticsを代わりに(イベントベースの)代わりに考えると面白かったです。各イベントラベルのフォーマットは、「時間:ユーザストリング(サニタイズ)」とすることができる。しかし、問題があります。一部の広告ブロッカーはGoogleアナリティクスを完全にブロックします。 – CPHPython

+0

@CPHPython他のオプションは、アプリケーションの洞察、空白のサービスです。無料の階層もあります。とにかく、たくさんのオプション。第三者に制限がある場合は、あまりにも悪いです。 DIYの選択肢がホイールを再発明しているかもしれません。スケーラビリティが問題になっているとき....... –

答えて

1

プロデューサコンシューマパターンを使用して実装します。ブロッキングコレクションを使用したインターネット上の例がたくさんあります。プロデューサは、オブジェクトを共有ブロッキングコレクションに追加するWeb APIエンドポイントであり、コンシューマはブロッキングコレクションからのバックグラウンドスレッドです。重要なポイントは、SQL Serverがボトルネックになる可能性が高いため、できるだけ早くコンシューマをSQL Serverに挿入する必要があることです。 1つのトランザクションで1つの行を一度に挿入することは最悪の選択です。行をバッチで挿入し、バッチごとに1つのトランザクションを挿入するほうが速くなります。しかし、最も高速なオプションは、一括挿入インターフェイスを使用して行バッチを挿入することです.SqlBulkCopyクラスはそのインターフェイスを提供します。

SqlBulkCopyを効率的に使用するには、SqlBulkCopyOption.TableLockを選択する必要があります。したがって、複数のコンシューマーは意味をなさないものです。

接続の再利用を心配する必要はありません。そのために接続プールが存在します。 C#プログラムで接続を閉じると、接続は実際には閉じられず、プールに戻されます。新しい接続を作成して開くときに、実際には開いている接続がプールから取得されます。

+0

過去に似たようなことをしなければならなかったのですが、1分間に平均9000メッセージ、4キューに分散したmsmqロード、tlp、SQLサーバー、バッチあたり約20レコードのバッチ処理が必要でした。格納する前にいくつかの処理を行わなければならなかったので、私たちの場合はSQL Serverではなく、ボトルネックになっていました。 – user3086298

1
  1. キューがクライアント側にあります - 接続不良の場合に意味があります。モバイルのようなものです。また、いくつかのバンドルが失われてしまいます。

  2. メモリキューには問題ありません(メッセージの損失を許す限り)。私はMSMQを使用することをお勧めします。これはトランザクショナルなので、指定された要件に十分以上の秒あたり約2Kのメッセージを処理できます

  3. 上記の回答は潜在的な損失を解決し、キューから削除してSQLに追加する) SQL Serverはボトルネックであり、メモリ内処理ではありません。

  4. もちろんです。ループの終わりにそれを閉じないでください。 (あなたはそれを閉じるためにタイマーを使うことができます、または接続管理についての詳細を読むことができます)

    5.1。あなたは、SQLのBULKを使用してください https://efbulkinsert.codeplex.com/

+0

5.1について:個人的には、(小さな)パフォーマンス上のペナルティがあるため、個人的にこの特定の状況ではエンティティフレームワークを使用しません。 –

+0

私は、SQL BULK INSERTの使用を提案しています。必要に応じて、手動でスクリプトを記述することができます。あなたは、提案されたパッケージに大きなオーバーヘッドがあると言っていますか? (私はEFについては言及していませんが、この特定のパッケージについて) – Marty

+0

これはEF用のパッケージであったので、私は悪いです.SQLパッケージをSQLパッケージで使用する代わりに、 –

関連する問題