3

1000 のトピックに関するリアルタイム データを受信するプログラムがあります。平均して 1 秒あたり 5000 件のメッセージを受信します。各メッセージは、トピックとメッセージ値の 2 つの文字列で構成されます。これらの文字列を、メッセージの到着時刻を示すタイムスタンプと共に保存したいと思います。

「Core 2」ハードウェアで 32 ビット Windows XP を使用し、C# でプログラミングしています。

このデータを 1000 ファイル (トピックごとに 1 つ) に保存したいと思います。多くの人がデータをデータベースに保存するように言いたがることは知っていますが、私はその道をたどりたくありません。

私はいくつかのアプローチを検討しました:

1) 1000 個のファイルを開き、データが到着したらそれぞれに書き込みます。これには2つの懸念があります。1000 個のファイルを同時に開くことができるかどうかはわかりません。また、これがディスクの断片化にどのような影響を与えるかもわかりません。

2) 1 つのファイルに書き込み、後でそれを処理して 1000 個のファイルを生成します。

3) 一日の終わりまですべてを RAM に保持してから、一度に 1 つのファイルに書き込みます。2 GB の制限を超えるには 64 ビットに移行する必要があるかもしれませんが、十分な RAM があればこれでうまくいくと思います。

この問題にどのように取り組みますか?

4

11 に答える 11

10

このためにデータベースを使用したくない理由は想像できません。これは彼らが構築されたものです。彼らはそれがかなり得意です。

そのルートに行きたくない場合は、RAMに保存し、1時間ごとにディスクにローテーションすることもできますが、電源ケーブルにつまずくと、多くのデータが失われることに注意してください。

真剣に。それをデータベース化します。

編集:ハードウェアの準備ができていれば、堅牢で複製された完全なデータベースバックアップソリューションを入手するのに1日もかからないことを付け加えておきます。

他の環境でこのレベルのトランザクション保護を実行すると、セットアップとテストに数週間長くかかります。

于 2009-05-29T13:34:00.413 に答える
4

n8wrlのように、私もDBをお勧めします。しかし、あなたが本当にこの機能を嫌うなら...

別の解決策を見つけましょう;-)

最小限のステップで、私は2つのスレッドを取ります。1つ目はワーカーで、すべてのデータを受け取り、各オブジェクト(タイムスタンプ、2つの文字列)をキューに入れます。

別のスレッドがこのキューをチェックします(イベントごとの情報またはCountプロパティのチェックによって)。このスレッドは、各オブジェクトをデキューし、特定のファイルを開き、それを書き留め、ファイルを閉じて、次のイベントに進みます。

この最初のアプローチでは、パフォーマンスを開始して確認します。それがうまくいかない場合は、問題がある場所でいくつかの計測を行い、それを達成しようとします(開いているファイルを辞書(名前、streamWriter)などに入れます)。

しかし、反対側では、DBはこの問題に非常に適しています... 1つのテーブル、4つの列(ID、タイムスタンプ、トピック、メッセージ)、トピックに関する1つの追加インデックス、準備ができています。

于 2009-05-29T13:43:14.997 に答える
2

最初に帯域幅を計算します!5000メッセージ/秒各2kb=10mb/秒。毎分-600mb。さて、あなたはそれをRAMに落とすことができます。その後、1時間ごとに洗い流します。

編集:間違いを修正しました。すみません、悪いです。

于 2009-05-29T13:30:22.073 に答える
2

私はカイルに同意し、PIのようなパッケージ製品を選びます。PIは非常に高価であることに注意してください。

カスタムソリューションをお探しの場合は、いくつかの変更を加えたStephen'sを使用します。1台のサーバーにメッセージを受信させ、それらをキューにドロップします。ただし、ファイルを使用してメッセージを他のプロセスに渡すことはできません。これは、ロックの問題が常に発生するためです。おそらくMSMQ(MSメッセージキュー)のようなものを使用しますが、その速度はわかりません。

また、データベースを使用してデータを保存することをお勧めします。ただし、SQLが1秒間に5000トランザクションを実行できるようにするには、かなりのハードウェアが必要になると思うので、データベースにデータを一括挿入する必要があります。キューに蓄積される10000メッセージごとに一括挿入を行う方がよいでしょう。

データサイズ:

平均メッセージ〜50バイト->小さい日時= 4バイト+トピック(〜10文字非ユニコード)=10バイト+メッセージ->31文字(非ユニコード)=31バイト。

50 * 5000 =244kb/秒->14mb/分->858mb/時間

于 2009-05-29T13:42:14.437 に答える
2

おそらく、DB インストールのオーバーヘッドが必要ではないでしょうか?

その場合、sqlite のようなファイルシステムベースのデータベースを試すことができます:

SQLite は、自己完結型、サーバーレス、ゼロ構成、トランザクション SQL データベース エンジンを実装するソフトウェア ライブラリです。SQLite は、世界で最も広く展開されている SQL データベース エンジンです。SQLite のソース コードはパブリック ドメインにあります。

于 2009-05-29T15:42:05.210 に答える
2

DB を使用したくない理由をもう少し詳しく調べたいと思います。DB はこのようなことに優れています。しかし、あなたのオプションに...

  1. 1000 個の開いているファイル ハンドルは、よく聞こえません。ディスクの断片化は忘れてください - O/S リソースは最悪です。
  2. これは db-ish-ness に近いです! また、価値があるよりも多くのトラブルのように聞こえます。
  3. RAM = 揮発性。一日中データの蓄積に費やし、午後 5 時に停電が発生しました。

これにどのようにアプローチしますか?デブ!その後、インデックスのクエリ、分析などを行うことができるためです。

:)

于 2009-05-29T13:24:03.957 に答える
2

私は Oliver に同意しますが、変更を提案します。トピック/ファイルごとに 1 つずつ、1000 のキューを用意します。1 つのスレッドがメッセージを受信し、タイムスタンプを付けてから、適切なキューに入れます。もう 1 つは、データがあるかどうかを確認しながら、キューを単純に循環します。その場合、メッセージを読み取り、対応するファイルを開き、メッセージを書き込みます。ファイルを閉じた後、次のキューに移動します。これの利点の 1 つは、トラフィックに対応できない場合にファイル書き込みスレッドを追加できることです。ただし、書き込みをバッチ処理するために、最初に書き込みしきい値を設定してみてください (N 個のメッセージを取得するまでキューの処理を延期します)。そうすれば、ファイルを開いたり閉じたりして、1 つまたは 2 つのメッセージを書き込むだけで行き詰まることはありません。

于 2009-05-29T14:29:03.733 に答える
1

リアルタイムのデータ履歴パッケージの購入を検討します。PIシステムやWonderwareDataHistorianのようなもの。私は以前にファイルやMSSQLデータベースでこのようなことを試みましたが、うまくいきませんでした(これは顧客の要件であり、提案しませんでした)。これらの製品にはAPIがあり、SQLのようにデータにクエリを実行できるパッケージもあります。

ハイパーリンクを投稿することはできませんので、これら2つの製品をグーグルで検索すると、それらに関する情報が見つかります。

編集

ほとんどの人が示唆しているようにデータベースを使用する場合は、履歴データのトピックごとにテーブルを推奨し、テーブルのパーティション分割、インデックス、およびデータの保存期間を検討します。

たとえば、1日分の価値と、トピックごとに1つのテーブルを保存する場合、1秒あたり5回の更新x1分あたり60秒x1時間あたり60分x24時間=1日あたり432000レコードを見ています。データをエクスポートした後、翌日のデータをクリアする必要があると思います。これによりロックが発生するため、データベースへの書き込みをキューに入れる必要があります。次に、インデックスを再構築して、スキーマ変更ロックとオンラインインデックス再構築用のMS SQLEnterpriseEditionを引き起こすクエリを実行できるようにする場合。毎日データをクリアしない場合は、データを投入するための十分なディスク容量があることを確認する必要があります。

基本的に、私が言っていることは、信頼できる製品を購入するコストと、独自の製品を構築するコストを比較検討します。

于 2009-05-29T13:31:31.307 に答える
1

着信メッセージのバッファを保持し、定期的に1000個のファイルを別のスレッドに順番に書き込みます。

于 2009-05-29T13:32:13.253 に答える
1

2 つの別個のプログラムを作成します。1 つは着信要求を受け取り、それらをフォーマットして 1 つのファイルに書き出し、もう 1 つはそのファイルから読み取り、要求を書き出します。このようにすることで、開いているファイル ハンドルの数を最小限に抑えながら、着信要求をリアルタイムで処理できます。最初のプログラム形式を作成すると、それが正しく出力され、個々のファイルへの処理が簡単になります。

于 2009-05-29T13:24:24.813 に答える
0

データベースを使用したくない場合 (私は使用しますが、使用しないと仮定します)、レコードを 1 つのファイルに書き込み、追加操作は可能な限り高速で、別のプロセス/サービスを使用します。ファイルを 1000 個のファイルに分割します。X 分ごとにファイルをロールオーバーすることもできます。たとえば、15 分ごとに新しいファイルを開始すると、他のプロセスがそれらを 1000 個の個別のファイルに分割し始めます。

これはすべて、なぜDBではないのか、なぜ1000個の異なるファイルが必要なのかという疑問を投げかけます-あなたには非常に正当な理由があるかもしれません-しかし、おそらく、戦略を再考し、それが適切な理由付けであることを確認する必要がありますこの道をずっと下ってください。

于 2009-05-29T15:36:26.037 に答える