7

物理センサーがサーバーにデータを送信するプロジェクトがあります。データは不定期に送信されます - 何かがセンサーをアクティブにした後ですが、20 分ごとよりも頻繁に送信されます。サーバー上のデータは Posgresql データベースに保存されます。

データ構造は次のようになります。

Sensor Table
    sensor name - string
    sensor serial no - string
    sensor type - foreign key to types table

Sensor Data Table
    sensor - foreign key
    timestamp
    value 1 - boolean
    value 2 - boolean
    value 3 - integer
    value 4 - float
    ...

合計 100 リクエスト/秒を超えないことが予想されます。データベースのデータ レコードは 90 日間、場合によってはそれ以上保持する必要があります (以前に考えていた 2 週間だけではありません)。したがって、レコードの合計量は 120 960 000/14 日を超えません。これは「安全な」見積もりです。実際には、10 分の 1 になる可能性があります (10 リクエスト/秒、12 960 000 レコード)。

次のようなデータの分析を行う必要があります。

  1. 新しいレコードが来て、その「値 2」が true のときに何かをする
  2. センサー X の「値 2」が、宣言された時間 (50 分、1 時間、またはそれ以上の時間) より長く真である場合に何かを行います。
  3. センサー X の 24 時間での「値 2」の合計真時間が、宣言された時間よりも長い場合に何かを行う
  4. センサー X の「値 3」が宣言された時間よりも長く true であり、この期間に XYZ タイプの他のセンサーがアクティブでなかった場合に何かを行います ...

上記の「宣言された時間」は 1 秒以上です。

サーバー部分全体は Django (およびデータを収集するための django-rest-framework) で開発されています。

問題は、リアルタイムまたはほぼリアルタイム (1 秒) でデータを監視し、必要なアクションをトリガーする期間を監視する必要があると仮定して、そのようなデータ分析を効率的に行う方法です。

私の考え:

  1. 基準を満たすレコードを毎秒データベースに照会し、特定のアクションを呼び出すプロセスを実行します (おそらく 1 秒以上かかります)。

  2. 分析タイプごとにいくつかの個別のプロセス (イベントレット?) を実行し、1 秒ごとにデータベースにクエリを実行して、特定のアクションを起動します。

  3. サブスクライバーに継続的に報告する各センサーごとに 1 つのプロセスを実行します。私は「値 2」に対して x 秒以上 true などです。そのセンサーの新しいデータが到着すると、プロセスはリセットされます。ここで zeromq のようなパブリッシュ/サブスクライブ ソリューションを使用できますか?

  4. 他の/より高速なソリューションを使用する

    • Mongodb - 問題は、データが削除された後 (2 週間)、mongodb のファイルが圧縮されないことです。
    • Hadoop - このクラスの問題には大きすぎず、複雑すぎませんか?
    • Pandas といくつかの HDF5 ストレージ - 問題は、上で説明した分析と、おそらくファイルへの書き込みを実行できるかどうかです。しかし.. mongoでも動作する可能性があります。

ヒント?

アップデート。

現在、私にとってシンプルで効果的と思われる解決策は次のとおりです。

  1. データがセンサー A に到着した後、すべてのテストを実行し、
  2. 次のような方法で、テスト結果をいくつかの「テスト」テーブル (または redis) に保存します。
    • 今日の午後 1 時 15 分に実行アクション「センサーがより長く開いています」
    • 今日の午後 1 時 30 分に実行アクション「センサーが 24 時間より長く開いています」...
  3. 上記の「テスト」テーブルを継続的にスキャンし、今日の午後 1 時 15 分になったら、必要なアクションを実行します。
  4. センサーAに新しい信号が到着したら、すべてのテストを再度実行し、「テスト」テーブルのデータもリセットします。

これにより、特定のセンサーのリクエストが到着するたびにテストを起動する必要がありますが、反対側では、1 秒ごとに「テスト」テーブルのみをスキャンする必要があります。

更新 2

PyTables ( http://www.pytables.org/moin/PyTables ) を発見しました。これは、データ ストレージとしてのユース ケースに非常に適しているようです。

4

4 に答える 4

2

これでの私の最初の刺し傷は、「センサーデータテーブル」に複数列のインデックスを作成することです。

sensor->timestamp->value1 //Index 1
sensor->timestamp->value2 //Index 2
sensor->timestamp->value3 //Index 3
sensor->timestamp->value4 //Index 4

SQL クエリが十分に高速かどうかを確認します。イベントレットまたは cron を介してクエリを実行できます。パフォーマンスの観点からは、このクエリが十分に高速である限り、どちらを使用しても問題はなく、ボトルネックになる可能性が最も高くなります。

もう 1 つの提案は、MySQL メモリ テーブル、または同等の postgre ( PostgreSQL のインメモリ テーブル) を試すことです。

もう 1 つの提案は、Redis を試すことです。「センサー データ」は、並べ替えられたセットのコレクションとして保存できます。センサー ID と値フィールドごとに 1 つの並べ替えられたセット、およびタイムスタンプでデータを並べ替えます。

 ZADD sensor_id:value1 timestamp value
 ZADD sensor_id:value2 timestamp value

Redis は、データを蓄積するためにいくつかのアプリケーション ロジックを必要としますが、すべてが RAM に収まる場合は非常に高速になります。

Re:モンゴDBです。良いパフォーマンスを得ることができます。クエリ可能なデータとインデックスが RAM に収まり、書き込みロックが多すぎない限り。重複する機能を提供する 2 つの重いデータベースを実行するのは、管理 (およびコーディング) の負担ですが。それを考えると、圧縮は実際には問題ではありません。センサー データに TTL インデックスを作成すると、mongo は bg スレッドで古いデータを削除します。しばらくすると、ファイル サイズは一定のままになります。

お役に立てれば

于 2013-04-15T14:00:06.370 に答える