web-dev-qa-db-ja.com

無限スクロールページのRedisページネーション戦略

TL; DR:Redisでページ付けするのに最も効率的なオプションは次の3つのうちどれですか?

複数のユーザー生成投稿を含むWebサイトを実装しています。これらの投稿は、リレーショナルDBに保存され、site:{site_id}:post:{post_id}のようなキーを使用して Hashes の形式でRedisにコピーされます。

Pinterestスタイルのインターフェースで遅延読み込みページネーションを実装するために(つまり、ユーザーが下にスクロールすると、サーバーにAjaxリクエストを送信して次の投稿を要求する)、Redisに対して簡単なページネーションクエリを実行したいと思います。

次に、site:{site_id}:postsのようなキーを使用して、公開された投稿IDを追跡するために Set を作成しました。コレクションに重複したIDを入れたくないので、セットを選択しました。簡単な [〜#〜] sad [〜#〜] (チェックする必要はありません)ですばやく実行できます。 IDが存在する場合)すべてのDB更新で。

セットは注文されていないので、ページ付けする必要のあるオプションの長所と短所を比較検討しています。

1) [〜#〜] sscan [〜#〜] コマンドを使用して、すでに実装されているセットをページ付けします

この場合、返されたスキャンカーソルをユーザーのセッションに保持し、次のリクエストでサーバーに送り返すことができます(複数のユーザーがデータベースにアクセスして更新する場合、信頼性が低いようです。カーソルが無効になり、奇妙な結果を返します-私が見逃しているいくつかの警告がない限り)。

2)セットをリファクタリングして リスト または ソートされたセット 代わりに

次に、 [〜#〜] lrange [〜#〜] または [〜#〜] zrange [〜#〜] を使用してページ付けできます。リストは、私のユースケースにとって最もパフォーマンスが高く自然なオプションのようです。ページ付けや日付順の注文には最適ですが、すべてのリストをループせずに単一のアイテムの存在を確認することはできません。ソートされたセットは、セットとリストの両方の利点を結合しているように見えますが、より多くのサーバーリソースを消費します。

3)通常のセットを使い続け、ページ番号をキーの一部として保存します

site:{site_id}:{page_number}:postsのようになります。スキャンコマンドが実装される前は 推奨される方法 でした。

だから、問題は:どれが最も効率的/最も単純なアプローチですか?ここに記載されていない他の推奨オプションはありますか?

17
Rafael Beckel

「最高」は主観的に最もよく提供されます:)

2番目のアプローチを使用することをお勧めしますが、リストではなくソート済みセットを使用することをお勧めします。このタイプのジョブには意味があるだけでなく( ZRANGE を参照)、リストをLRANGE-するよりも複雑さの点で効率的です。 。

9
Itamar Haber