web-dev-qa-db-ja.com

リアルタイムデータをデータベースに保存する方法

これが私の状況です:

  • データをリアルタイムで提供するWebSocket接続があります
  • データを取得してキューに挿入する非同期コールバック関数があります
  • キューから読み取り、Postgresデータベースに一度に1行ずつ格納する別のスレッドがあります(Pythonのpsycopg2ライブラリを使用)

問題は、リアルタイムデータがデータベースに挿入するのにかかる時間よりも速く到着し、数時間でサーバーのメモリが不足することです。 (psycopg2ライブラリが遅いためですか?)

簡単な解決策は、データベースに挿入するスレッドをさらに作成することです。ただし、これによりデータの順序が乱れます。データを分類するデータベースはありますか?他の提案をいただければ幸いです。

1
MoneyBall

一般的に、リレーショナルデータベースでは、1000行の挿入は1000行の単一の挿入よりも遅くなります。メモリ内のデータをバッチ処理し、データベースにロードする方が速い場合があります。

メモリにデータを受信すると、キューを構築します。次に、キューから最上位のアイテムをポップして、データベースに挿入します。代わりに、上位のNアイテムをポップし、それらすべてを1つのINSERTステートメントに挿入します。 Nの理想的な値は普遍的ではないため、実験する必要があります。 1000、10000から始めて、スループット結果に基づいてそこから始めてみてください。

また、大量のデータがファイルにストリーミングされ、非同期でDBにロードされるアーキテクチャも確認(およびサポート)しました。これにより、受信サービスでメモリが不足したりクラッシュしたりすることなく(したがって、メモリ内のデータが失われることはありません)、ある程度の複雑さが増し、常にデータが読み込まれるよりも速くロードされるとは限りません。むしろ、それを解決する別の問題に分けるだけです。この構成では、受信サービスは、N MB /行のサイズになるまでファイルにデータを書き込みます。次に、次のファイルにロールオーバーします。 (個人的には、ファイルの順序を維持するためにファイル名に日時スタンプを付けるのが好きです。)非同期で、別のサービスが最新ではないファイルを取得し、データベースにロードします(COPYまたは何か= Pythonあなたが見つけたライブラリ)。

4
AMtwo

この質問はスタックオーバーフローに適しています。あなたはあなたのアーキテクチャでほとんどそこにいると思います。 Webソケットをできるだけ高速にして、データをいくつかの非永続ストレージに保存する必要があります。サーバーのクラッシュでデータが失われることを心配しない場合は、メモリで十分です。次に、そのキューからPostgresにデータを保存するプロセスが必要になることがよくあります。データベースへの1回の往復で多くの行を一括挿入するようにしてください。準備済みステートメントを使用して、挿入する必要のあるデータの配列のみを渡します。 – Colin 't Hart

0
user201835

データを取得してキューに挿入する非同期コールバック関数があります

キューとは何ですか?トランザクション対応でクラッシュしないか?

問題は、リアルタイムデータがデータベースに挿入するのにかかる時間よりも速く到着し、数時間でサーバーのメモリが不足することです。 (psycopg2ライブラリが遅いためですか?)

これは経験的な質問です。 topを見ると、おそらくそれに答えることができます。私の経験では、psycopg2は他の何よりも著しく遅くはありません。また、一部のボトルネックを解消できるCOPYプロトコルもサポートしています。挿入するテーブルにインデックスが付けられている場合、インデックスのメンテナンスがボトルネックになっている可能性があります。

簡単な解決策は、データベースに挿入するスレッドをさらに作成することです。ただし、これによりデータの順序が乱れます

コールバックまたはキューに割り当てられたタイムスタンプで挿入できます。

0
jjanes