3

まず、私はコンピューター科学者ではなくエンジニアですので、優しくしてください。私は現在、MySQL++を使用するC++プログラムを持っています。このプログラムには、NIVisaランタイムも組み込まれています。割り込みハンドラの1つは、USBデバイスから1秒間に約200回データ(1バイト)を受信します。このデータをタイムスタンプ付きでリモートサーバーの各サンプルに保存したいと思います。これは実行可能ですか?誰かが良いアプローチをお勧めできますか?よろしく、マイケル

4

4 に答える 4

4

リモート サーバーに対して 1 秒あたり 200 トランザクションを実行することは、多くのことを要求していると思います。特に、これらのトランザクションが、ジョブを実行して迅速に完了しなければならない割り込みハンドラーのコンテキストで発生することを考えると。割り込みハンドラーをデータベースアクセスから切り離す方が良いと思います-おそらく、割り込みハンドラーに着信データとタイムスタンプを何らかのメモリ内データ構造(配列、循環リンクリストなど、適切な同期を使用して)に保存させます)データ構造でデータが利用可能になるまで待機し、それをデータベースにポンプする別のスレッドがあります。私はその割り込みハンドラーを可能な限りスリムで決定論的に保ちたいと思っています.ネットワークを介したリモートサーバーへのデータベースアクセスが遅すぎるか、さらに悪いことです.

もちろん、これにより、データ オーバーランの問題/問題が発生します。データがデータベースに送り込まれるよりも速く入力され、メモリ内のストレージ構造がいっぱいになります。これにより、データが失われる可能性があります。いくつかのサンプルを落とすと、どれほど悪いことですか?

于 2010-01-26T12:52:34.550 に答える
1

値ごとに1つの個別の挿入でその速度を維持できるとは思いませんが、それらを十分な大きさのバッチにバッチ処理すると、すべてを1つのクエリとして送信でき、問題ないはずです。

INSERT INTO records(timestamp, value)
  VALUES(1, 2), (3, 4), (5, 6), [...], (399, 400);

タイムスタンプと値をバッファにプッシュするだけで、バッファのサイズが200(またはその他の任意の数値)に達したら、SQLを生成し、ロット全体を送信します。sprintfを使用してこの文字列を作成するのは、遅すぎないようにする必要があります。割り込みルーチンが同時に書き込んでいる可能性のあるデータ構造からの読み取りに注意してください。

このSQL生成が何らかの理由で遅すぎて、API(ストアドプロシージャなど)を使用するより迅速な方法がない場合は、データ収集と同時にこれを実行することをお勧めします。最も簡単なのは、おそらくソケットまたはパイプを介して、SQL生成を実行する別のプロセスにデータをストリーミングすることです。マルチスレッドアプローチもありますが、より複雑でエラーが発生しやすくなります。

于 2010-01-26T13:57:09.527 に答える
0

私の意見では、次の 2 つのことを行う必要があります。1. データをバッファリングし、2. バッファごとに 1 つのタイム スタンプを作成します。USB プロトコルはバイトベースではなく、よりメッセージベースです。メッセージを追跡している場合は、メッセージにタイム スタンプを付けます。

また、データベースは一度に 1 バイトではなく、データのブロックまたはチャンクを受け取ります。各トランザクションでデータベースにオーバーヘッドがあります。効率を測定するには、オーバーヘッドをトランザクションのバイト数で割ります。大きなブロックは、多数の小さなトランザクションよりも効率的であることがわかります。

もう 1 つのオプションは、データをファイルに保存してから、MySQL LOADFILE 関数を使用してデータをデータベースにロードすることです。また、データをバッファに格納してから、MySQL C++ コネクタ ストリームを使用してデータをデータベースにロードします。

于 2010-01-26T17:39:53.390 に答える