web-dev-qa-db-ja.com

高速(1秒未満)の読み取りクエリパフォーマンスを備えた大規模な(22兆を超えるアイテム)地理空間データセット

高速な読み取りクエリのパフォーマンスを必要とする大規模な地理空間データセット用の新しいシステムを設計しています。したがって、適切なDBMS、データ構造、または次の状況で必要なパフォーマンスを達成するための代替方法について、可能であるか、または経験/アドバイスがあると誰かが思っているかどうかを確認したいと思います。

データは、処理された衛星レーダーデータから継続的に生成され、グローバルにカバーされます。衛星の解像度と地球の土地被覆に基づいて、私は完全なデータセットを推定して、地球上の75億の個別の場所で値を生成します。単一の衛星の寿命にわたって、出力はこれらの場所のそれぞれで最大300の値を生成します(したがって、合計データセットは22兆を超えます)。これは1つの衛星用で、もう1つは軌道上にあり、別の2つが新しい数年で計画されています。だからたくさんのデータがあります!単一のデータ項目は非常に単純で、(経度、緯度、値)のみで構成されますが、項目の数が原因で、1つの衛星で最大100TBを生成すると推定しています。

書き込まれたデータは、新しい衛星の捕捉が処理されるまで成長しないため、更新する必要はありません。書き込みパフォーマンスは重要ではありませんが、読み取りパフォーマンスは重要です。このプロジェクトの目標は、Googleマップ上のレイヤーなどのシンプルなインターフェースを介してデータを視覚化できるようにすることです。この場合、各ポイントは、時間の経過に伴う平均、勾配、またはいくつかの関数に基づいて色付きの値を持ちます。 (投稿の最後のデモ)。

これらの要件から、データベースはスケーラブルである必要があり、クラウドソリューションに目を向ける可能性があります。システムは、「(lat、lon)の近くのポイント」や「(box)内のポイント」などの地理空間クエリを処理できる必要があり、単一のポイントを見つけるための読み取りパフォーマンスが1未満であり、 50,000ポイント(最大200,000ポイントが望ましいですが)。

これまでのところ、1億1100万の場所に約7億5000万のデータ項目のテストデータセットがあります。私はpostgres/postGISインスタンスを試してみましたが、問題なく動作しましたが、シャーディングの可能性がなければ、これはデータの増加に対応できます。mongoDBインスタンスも試してみましたが、再びOKのように見えますシャーディングでは、データボリュームに合わせてスケーリングすれば十分な場合があります。私は最近elasticsearchについて少し学んだので、これについてのコメントはそれが私にとって新しいので役に立ちます。

以下は、完全なデータセットで達成したいことの簡単なアニメーションです: Tileserver serving visualization of 750 million data items.

このgif(私のpostgresトライアルから)は、(6x3)の事前計算されたラスタータイルを提供しており、それぞれが〜200,000ポイントを含み、それぞれを生成するために〜17秒かかります。ポイントをクリックすると、グラフは1秒未満で最も近い場所にあるすべての履歴値を引き出して作成されます。

長い投稿をお詫びします。すべてのコメント/アドバイスを歓迎します。

19
Azwok

場所によってシャーディングできます。地球をグリッドに分割し、そのグリッド内の各正方形を1つのサーバーに配置します。クラウドについて説明したので、それはクラウドに適しています。もちろん、複数のサーバーからの結果を手動でマージする必要があります。

そうすれば、好きなデータベースソリューションを使用できます。それ自体でスケーラブルである必要はありません。

個々の正方形には、異なる量のデータがあります。それらには異なるサイズのマシンを使用できます(これはクラウドであるため)、または同じマシンに複数の小さな断片を配置します。

このクエリスキームは、実行するクエリの種類に最適です。各クエリは、ごく少数のシャードに触れるだけでよいためです。クエリごとにすべてのタイムシャードを操作する必要があるため、時間によるシャーディングはさらに悪くなります。ランダムシャーディングにも同じ問題があります。

全体として、クエリパターンがシャーディングスキームに非常によく適合しているため、これは簡単なシャーディングケースです。

実際、これにはデータベースが必要なのでしょうか。おそらく、グローブを1000x1000タイル以下に分割し、タイルごとにブロブストレージに1つのフラットファイルを作成できます。ブロブストレージは、100万のブロブをまったく気にしません。

このストレージスキームを使用すると、クエリの実行は概念的に非常に簡単です。複数のグリッド解像度でデータを重複して保存することもできます。

4
usr

読み取りクエリはどの程度更新する必要がありますか?

マップが最新の測定値を表示するだけでよい場合は、データベースを時間で分割できます。これにより、マップのクエリ負荷が軽減されます。

特定のポイントの履歴については、履歴を示すxとyによって2番目のストアを保持できます。履歴データは変更されないため、これは夜間の更新/更新で実行できます。

その後、さまざまなズームレベルでマップと統合するために、より粗い解像度で平均を事前に計算できます。これにより、大きなマップ領域(ズームアウト)で取得するポイントの数が減ります。より細かい解像度は、より小さな領域をクエリしていたマップをより拡大するために使用されます。本当にこれをスピードアップする必要がある場合は、タイルをブロブとして計算し、アプリケーションでそれらを解釈することができます。

これらには集約情報の再計算が含まれるため、クエリ結果に待ち時間が発生します。許容できるレイテンシに応じて、この種のアプローチを使用して読み取りを最適化できます。

OK、ポイントは時間の経過に伴う平均値を計算する必要があります。この計算では、ラスター値をクエリ用に事前に計算できるため、実際のクエリは22兆アイテムからかなり多くなると思います。

クエリには2つのクラスがあるようです。1つは現在のビューウィンドウ内にある場所を理解するためのもので、もう1つはそれらのポイントに必要な統計を提供するためのものです。私の提案は、それぞれに専用の専用ツールを使用することです。

すべての測定値が75Bnポイントの同じセットに関連していると想定しています。したがって、これらの緯度/経度は、一度確立されると静的です。これらは、一度のコストでグループ化、集約、およびインデックス化できます。したがって、領域とズームレベルでシャーディングすることをお勧めします。各シャードのサイズは、各GISインスタンスから達成できるパフォーマンスによって決まります。

GISは、時系列データベースに渡される一連のポイントを返します。これは測定値を保持し、集計を実行します。 [〜#〜] kdb [〜#〜] は私が知っているものです。それはあなたのシナリオよりも少ないキーを持っていますが、キーごとのより多くのデータポイントを持つ証券取引を対象としています。

キー値をGISサーバーから時系列DBに転送するにはコストがかかります。私の仮説は、このコストは、タスク固有の時系列DBでのより高速な処理によって返済されるというものです。質問の文言から、単一のインスタンスではすべてのデータを保持できないため、一部のクロスサーバートラフィックは避けられないようです。コンポーネントの 相対速度 を考えると、データがキャッシュされているリモートサーバーにキーセットを送信する方が、ローカルディスクからデータを読み取るよりも高速であるようです。

ポイントを見つける部分と値を計算する部分が互いに局所的である場合、もちろん、私は応答が速くなることを期待します。私の(限られた)理解は、与えられた点に最も近いN個の近傍を見つけることは簡単なことではないということです。これが、特定のソフトウェアを使用して実行することを提案した理由です。ポイントファインディングを

where latitude between x1 and x2
and logitude between y1 and y2

次に、その部分は、バリューストレージソフトウェアと、アーキテクチャから削除されたGISで処理できます。

私はそのようなシステムを実装していません。私は本当にここで大声で考えています。ペタバイト規模では、既成のソリューションはありません。ただし、衛星データプロバイダーは多数あるため、問題は扱いやすくなっています。幸運を。

3
Michael Green