私のシナリオに最適なデータストアはどれですか?


10

データベースで非常に高い更新/選択クエリの実行を伴うアプリケーションに取り組んでいます。

ベーステーブル(A)があり、1日のエンティティに対して約500のレコードがあります。そして、システム内のすべてのユーザーについて、このエンティティのバリエーションがユーザーの設定の一部に基づいて作成され、それらは別のテーブル(B)に格納されます。これは、毎日午前0時に実行されるcronジョブによって実行されます。

したがって、テーブルAに10,000人のユーザーと500個のレコードがある場合、その日のテーブルBには500万のレコードがあります。私は常にこれらのテーブルに1日分のデータを保存し、真夜中に履歴データをHBaseにアーカイブします。この設定は正常に機能しており、今のところパフォーマンスの問題はありません。

最近、ビジネス要件にいくつかの変更があり、現在、ベーステーブルAの一部の属性(15〜20レコード)が20秒ごとに変更され、それに基づいて、テーブルBのすべてのバリエーションレコードのいくつかの値を再計算する必要があります。すべてのユーザー。変更するのは20のマスターレコードだけですが、20秒以上かかる200,000のユーザーレコードを再計算して更新する必要があるため、次の更新が行われると、最終的にすべてのSelectクエリがキューに入れられます。オンラインユーザーから約3 getリクエスト/ 5秒で6-9 Selectクエリが発生します。APIリクエストに応答するために、常にテーブルBのフィールドを使用します。

より多くの処理能力を購入してこの状況を解決できますが、100万人のユーザーでも処理できる適切にスケーリングされたシステムに興味があります。

ここの誰かがより良い代替案を提案できますか?nosql +リレーショナルデータベースはここで役立ちますか?ロックせずにデータを頻繁に更新でき、同時にエンティティのさまざまなフィールドで選択クエリを実行できる柔軟性を提供するプラットフォーム/データストアはありますか?


本当にすべてのデータを保存する必要がありますか?これは、要求に応じて計算した方がよいかのように聞こえます。20秒より少し長い時間で200kレコードを計算できる場合、それらの20レコード* 3ユーザー= 60時間のレコードをすぐに計算できるはずです。おそらく、どのユーザーがいつオンラインであるかを調べて、さらに最適化できますか?誰も使用したことのない大量のデータを生成しているように見えます(少なくともデータがまだ有効な間は)
thorstenmüllerNov

ログインしたユーザーに対してのみ生成することは、非常に良いオプションです。私もそのことを考えましたが、それでもスケーラブルなアプローチとは言えません。私のプラットフォームは日中のみ使用されるため、その間、ほとんどのユーザーがアクティブになります。他の提案は合致しますか?
水差し

@水差し-それでも、その場で計算できるかどうかという問題が残っています。あなたは、ください持っているレコードを更新するために、またはあなたのアプリケーションはただそこにデータを必要とするのか?
ボブソン2015年

エントリテーブルBがユーザー(5つ星から1つ星)にランク付けされているため、その場で計算することはできません。これらの計算が完了したら、ユーザーに対して再度ランク付けを行います。ユーザーのプロセス全体は500ミリ秒かかり、オンザフライで実行すると、API応答時間に影響します
Jugs

RDBMSの外部のスコアとランキングをnosql dbに格納して、selectステートメントが問題なく実行できるようにするのが理にかなっているかどうか考えていましたが、スコアとランクについてもクエリを実行する必要がある場合があります。ですから、私は今のところ少し迷っています。そのため、皆さんのような専門家からのアドバイスを探しています
Jugs

回答:


1

テーブルBはある種のキャッシュのようです。しかし、生産性を低下させるそのようなキャッシュ。

1秒あたり25のクエリがある場合でも、テーブルの使用を拒否し、B各リクエストの回答を計算できます。

とにかく、20レコードの更新に30秒の遅延がある場合-ソフトウェアアーキテクチャの失敗です(DBがすべてのレコードのPIの最初の10 ^ 100符号を計算する場合、私は間違っています)。

私が知っているように、醜いSQLクエリがなく、インデックスがあり、1 000 000レコード未満のリレーショナルDBは、ほとんどすべてのクエリで完全に機能します。

テーブルの使用を拒否し、B適切なインデックスをテーブルに追加してくださいA(最新のデータベースのほとんどにはヘルパーツールがあります)。次に:データ(テーブルA)とクエリ(クエリアナライザーを使用するか、SQLエキスパートを使用)の構造を最適化して、計算を高速化します。20レコードだけを更新する場合-インデックスの存在は更新プロセスの生産性を損なうことはありませんが、選択速度を大幅に向上させます


1

問題は、Bに挿入するレコードとBデータのサイズを計算するシステムです。

すべてのデータベース(MSSQLなど)は、オブジェクトが巨大でないことを前提として、問題のない挿入のボリュームを問題なく処理できる必要があります。

更新はより困難な問題による可能性がありますが、適切なインデックス作成とロックを使用すれば、大きな問題にはなりません。

このような問題が発生する時間の99%は、Bレコードがストアドプロシージャによって計算されるためです。これにより、dbサーバーにすべての負荷がかかります

これが事実である場合、解決策はこのコードをオフラインシステムに移動することです。このサービスは、キューシステムを介して呼び出すことができます。

したがって、更新Aメッセージは、ユーザーをループして各ユーザーの更新Bメッセージを作成するワーカープロセスをトリガーします

2番目のワーカープロセスBは、データAイベントを使用して更新ユーザーXをピックアップし、Bレコードを作成してDBを更新します。

キューワーカーを含むボックスをさらに追加することでこれをスケーリングできるため、計算の背後にますます多くの処理能力があり、データベースを更新と選択に集中できるようにします。

選択と更新/挿入を分離することで、さらに最適化できます。レプリケーションスレーブとしてすべての選択要求を取得する新しいDBと、すべての更新を取得する古いDBがあります。


0

Amazonで実行している場合は、DynamoDBを検討します。フラッシュメモリベースです。これへのリンクは次のとおりです:https : //aws.amazon.com/dynamodb/

どの種類のRDBMSを使用していますか?UDFまたはビューの計算フィールドを使用すると、パフォーマンスを向上できる場合があります。単一の更新クエリを介してデータベースで計算を実行していますか、またはデータベースからデータを選択し、別のプロセスで計算を実行してから、それらに再度ロードしていますか?

Oracleはデフォルトでスナップショットモードの実行を使用するように構成されています。つまり、更新中に行がロックされず、同時選択によって元の値が取得されます。SQL Serverはデフォルトで悲観的な同時実行性が設定されているため、更新が完了するまで同時選択はブロックされます。SQL Serverの一部のバージョンはスナップショットモードにすることができますが、一時テーブルへのストレスが大幅に増加します。

どのような環境で実行していますか?AmazonのEC2インスタンス上のRDBMSの場合は、ローカルのフラッシュディスクにDBデータファイルを配置してみてください。EBSからローカルディスクにファイルを移動する際に、1桁以上の違いがあることを確認しました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.