2

NoSQL エンジンである Raik の使い方を学んでいます。投稿のあるユーザーの「タイムライン」があり、その投稿が数百万から数十億に及ぶ場合、raik バケットから最後の N 件の投稿を取得するにはどうすればよいでしょうか? つまり、最後に作成されたものです。

セカンダリ インデックスを使用すると、Raik はキー順に投稿を返すことを読みました。そのため、投稿キーに UUID1 を使用し、投稿作成者のセカンダリ インデックスを使用して、そのキーを使用してその作成者からすべての投稿を取得できるようにすることにしました。

ただし、投稿は昇順でソートされます。また、max_results パラメータを SQL LIMIT として使用したいと考えています。

ただし、このクエリは、そのユーザーの最後の投稿ではなく、最初の N 件の投稿を返します。StackOverflow の投稿をいくつか見たことがあることと、提案されたソリューションである MapReduce が大きなバケットに対して効率的でないことを考えると、どのようにデータをモデル化するか、クエリを作成しますか?

ありがとう

4

2 に答える 2

3

SQL 環境から来る場合、バケットをテーブルとして扱い、小さな個々のレコードをそこに保存するのは簡単です。多くの場合、セカンダリ インデックスに依存してデータを取得します。Riak はコンシステント ハッシュを使用するキーと値のストアであるため、これは多くの場合、最も効率的またはスケーラブルなアプローチではありません。

Riak のキーに基づくルックアップにより、データを保持しているパーティションを直接識別でき、調整ノードはこれらのパーティションに直接クエリを実行できます。セカンダリ インデックスをクエリするとき、Riak はインデックスに一致する可能性のあるデータがどのパーティションに存在するかを知りません。したがって、一致するすべてのオブジェクトが確実に見つかるようにするには、クエリを多数のパーティションに送信する必要があります。これは「カバレッジ クエリ」と呼ばれ、バケットに 3 の n_val が使用されると仮定すると、すべてのパーティションの少なくとも 1/3 をクエリする必要があることを意味します。これは通常、クラスターの負荷が高くなり、直接的なキー ルックアップと同様にスケーリングされません。レイテンシも高くなる傾向があります。

したがって、Riak を使用する場合は、データを構造化して、非正規化などにより直接キー検索を可能な限り使用できるようにすることをお勧めします。

メッセージ/投稿をユーザーや会話など、何らかの方法でグループ化できる場合は、個別のオブジェクトとしてではなく、このグループ化を表す単一のオブジェクトにそれらを保存することが理にかなっている場合があります。

投稿がテキストまたは画像で構成され、会話スレッドにリンクされていると仮定すると、会話スレッドを表すオブジェクトを作成できます。これには、会話に関する情報と投稿のリストが含まれます。この投稿のリストには、投稿者の ID、タイムスタンプ、投稿を含むレコードのキーなどを含めることができます。投稿が適度に短いテキスト メッセージである場合は、投稿全体が含まれている場合もあり、取得する必要があるレコードの数が減ります。

この会話に投稿が入ると、レコードが更新され、投稿のリストが長くなります。兄弟を有効にするために true に設定するのが賢明な場合がありますallow_mult。これにより、同時書き込みを処理できるようになります。このアプローチにより、1 回のダイレクト キー ルックアップで常に会話と最新の投稿を取得できます。

Riak は、オブジェクトのサイズが数 MB 未満に保たれている場合に最適に機能します。したがって、サイズを抑えるために、ある時点で最も古い投稿を別のオブジェクトに移動する必要があります。これらの関連オブジェクトのリストをメインの会話オブジェクトに保持し、それらがカバーする時間間隔に関する情報を一緒に保持している場合、古い投稿をスクロールして戻る必要がある場合に、キーを直接検索することでこれらに簡単にアクセスできます。

通常、最も一般的なクエリは最新のエントリに対するものであるため、これは常にメインの会話オブジェクトを通じて実行できます。

また、この種の問題が非常に頻繁に議論されている非常に活発なメーリング リストがあることも指摘したいと思います。

于 2013-10-10T07:59:10.293 に答える
0

おそらく手遅れだと思いますが、同じことを疑問に思ってこの投稿を見つけました。私が思いつき、効果的に使用している回避策は、2 つのセカンダリ インデックスを作成することです。1 つは実際のタイムスタンプで、もう 1 つは (MAX_DATE - タイムスタンプ) です。最初のクエリでルックアップを実行すると昇順の結果が得られ、2 番目のクエリでルックアップを実行すると降順の結果が得られます (計算を実行して実際の日付に戻すと)。8640000000000000 であるMDNで報告されているように、Javascript 仕様で最大日付値を見つけることができます。本当に重い負荷の下でどのようにパフォーマンスが高いかについては言えませんが、私の目的のためには非常に優れていると言えます。速くてとても満足しています。私はそれを行うためのよりハックしない方法を見つけたいと思ってここに来ました。

于 2014-12-12T16:05:08.900 に答える