web-dev-qa-db-ja.com

複数の解像度で時系列を効率的に保存

はじめに

エネルギーデータ(ガス/電力消費、電力供給)を保存するシステムをリファクタリングしています。データは、将来変更される可能性のあるスキーマで15分ごとに絶対データをポストするセンサーから取得されます(読み取り:ドキュメントストレージが必要です)。

現在の状況

生データはMongoDBデータベースに保存されます。バックグラウンドプロセスがこのデータを読み取り、MySQLデータベースにさまざまな解像度で格納されている構造化デルタデータに変換します。

MongoDBスキーマ:| device_id (uint) | timestamp (ISODate) | data (unspecified object) |

MySQLスキーマ:(複数のテーブル:hourdaymonthyear
| device_id (uint) | timestamp (datetime) | gas_consumption | electricity_consumption | ... |

MongoDB dataフィールドが定義を変更すると、バックグラウンドプロセスがデータのバージョンを検出し、それに応じて処理します。 MySQLデータベースは、MongoDBデータから再作成される場合があり、新しいスキーマが使用される場合があります(将来必要になる場合があります)。

想定される状況

新しい状況では、時系列データベースを使用したいと思います(これは多くの外部関係者から提案されているため)。アトミック(データベース)レベルで実装したい機能が2つあります。

  • 欠落データのギャップフィリング。四半期データでいくつかのポイントが欠落している可能性があります。絶対値がわかっているため、このデータは線形分布で入力する必要があります。
  • さまざまな解像度を保存します。データは複数の解像度(時間から年)でクエリされ、これらのクエリはすべて高速である必要があります。

要件:

  • 100万デバイス(データ入力)までスケールアップする必要があります。
  • 最大50kの同時ユーザー(データクエリ)まで拡張する必要があります。
  • 集約されたデータは、できるだけ早く利用できる必要があります。 (最大1時間は許容されます)
  • データが劣化しない場合があります。 (完全な履歴は最高の解像度で利用できる必要があります)
  • 古いデータが更新される可能性があります(最高の解像度で、その変更は低解像度で反映されます)。これは非常にまれですが、可能であるべきです。 (これが大きな問題であることが判明した場合、この要件は別の方法で処理される可能性がありますが、それは推奨されるソリューションではありません)。
  • 無料ビールのように無料。
  • すべてのコードはNodeJSで記述されているため、データはNodeJSからアクセスできる必要があります。
  • 最新のデータポイント(現在の年など)が終了する前に前の階層の合計で満たされることが望ましいです。そうでない場合は、四半期テーブルからこれを要求する必要があります。例:2017年7月1日の2017年のデータポイントには、その日付までの年の合計と、経過時間の表示が含まれます。 (これは持っているのは素晴らしいことです)。

典型的なクエリは次のようになります(疑似コード):SELECT <fields> BETWEEN <start-date> AND <end-date> WITH RESOLUTION <time-resolution>

現在の考慮事項

時系列をサポートするいくつかのデータベース(InfluxDB、MongoDB、Graphite、RRDtool、Redis、OpenTSDBなど)を見てきましたが、さまざまな解像度やギャップフィリングをネイティブでサポートするデータベースが見つかりません。

MongoDBはオプションである可能性がありますが、書き込みはファイアアンドフォーゲットです。つまり、欠落データは検出されない可能性があります。生データの場合、これが頻繁に発生しない限り、これは問題ではありません。処理されたデータの場合、これは大きな問題です。アプリケーションの残りの部分では、非常にまれなEdgeの場合でも、これらのテーブルのデータはシーケンシャルであると想定しています。

MySQLもオプションになります(たとえば、初期実装を変更しないなど)が、時系列データベースは理由によって時系列データベース用に最適化されているように感じます。

質問

現在の状況は良いアプローチですか?そうでない場合、何がより良いでしょうか?私のユースケースは時系列を保存する世界でそれほどユニークではないように感じますが、正しい方向にプッシュすることができるリソースをオンラインで見つけることができないようです。

6

カリフォルニアエネルギー委員会(UT3、または niversal Translator 3)の同様のアプリケーションに取り組みました。いくつかのポイント:

  • 「埋める」アルゴリズムは数学的に正しくない場合があります。問題のデータは通常、平均値です。時間内に平均値データをリサンプリングする正しい方法は、時間加重平均を使用することです。それは一種の統合です。
  • 一方、いくつかの瞬間的なタイプのデータがあり、異なるタイプの数値積分が必要な場合があります。もっと必要な数学的特性を研究することを勧めます。
  • 最高のパフォーマンスは、元のリサンプリングされていないデータのみをバイナリ形式で格納するカスタムデータベースを使用することから得られます。 「カスタムデータベース」は、それぞれがデータストリームを含む読み取り専用ファイルのセットで構成できます。時系列固有のデータベースはおそらく十分高速です。
  • リサンプリングアルゴリズムは、クライアントでリアルタイムに実行できるほど高速です。
  • エンドユーザーのサンプリング頻度が元のデータよりもはるかに低い場合は、もちろん、サーバーでリサンプリングされたストリームをキャッシュすることは理にかなっています。元のデータへのアクセスにより、クライアントベースのデザイン(Universal Translatorなど)が用途によってはより魅力的になります。
2
Frank Hileman