7

メディア オブジェクトを保存し、redis を介して特定の時間範囲で取得できるようにしようとしています。これを行うために、ソートされたセットのデータ型を選択しました。次のような要素を追加しています。

zAdd: key: media:552672 score: 1355264694
zAdd: key: media:552672 score: 1355248565
zAdd: key: media:552672 score: 1355209157
zAdd: key: media:552672 score: 1355208992
zAdd: key: media:552672 score: 1355208888
zAdd: key: media:552672 score: 1355208815

キーはメディアが撮影された場所 ID に固有であり、スコアはメディア オブジェクトの作成時間です。値はメディア オブジェクトの json_decode です。

を使用して取得しようとするzRevRangeByScoreと、エントリが重複することがあります。基本的に、外部 API へのバッファとして Redis を使用しています。ユーザーが同じ API 呼び出しを X 秒で 2 回行っている場合は、キャッシュから結果を取得します。それ以外の場合は、チェックせずにキャッシュに追加します重複を含まないセットの定義のために、それがすでに存在するかどうかを確認します。考えられる既知の問題: メディア オブジェクトの属性がキャッシュ間で変更されると、重複として表示されます。

redis クライアント側でチェックを行わずにこのタイプのデータを保存するより良い方法はありますか?

TLDR; タイムスタンプでオブジェクトの範囲を選択し、それらが一意であることを確認できるRedisでオブジェクトを保存および取得する最良の方法は何ですか?

4

1 に答える 1

25

同じことについて話していることを確認しましょう。Redisでソートされたセットの用語は次のとおりです。

ZADD key score member [score] [member]
summary: Add one or more members to a sorted set, or update its score if it already exists
  • key-ソートされたセットの「名前」
  • score-スコア(この場合はタイムスタンプ)
  • member-スコアが関連付けられている文字列
  • ソートされたセットには多くのメンバーがあり、それぞれにスコアがあります

オブジェクトのJSONエンコードされた文字列をメンバーとして使用しているようです。メンバーは、ソートされたセットで一意のものです。あなたが言うように、オブジェクトが変更された場合、それはソートされたセットに新しいメンバーとして追加されます。それはおそらくあなたが望むものではありません。

ソートされたセットは、タイムスタンプでデータを保存するRedisの方法ですが、セットに保存されるメンバーは通常、Redisの別のキーへの「ポインター」です。

あなたの説明から、私はあなたがこのデータ構造を望んでいると思います:

  • 作成されたタイムスタンプによってすべてのメディアを格納するソートされたセット
  • 一意のメディアごとの文字列またはハッシュ

メディアオブジェクトをハッシュに保存することをお勧めします。これにより、柔軟性が向上します。例:

# add some members to our sorted set
redis 127.0.0.1:6379> ZADD media 1000 media:1 1003 media:2 1001 media:3
(integer) 3
# create hashes for our members
redis 127.0.0.1:6379> HMSET media:1 id 1 name "media one" content "content string for one"
OK
redis 127.0.0.1:6379> HMSET media:2 id 2 name "media two" content "content string for two"
OK
redis 127.0.0.1:6379> HMSET media:3 id 3 name "media three" content "content string for three"
OK

この方法で保存されたデータを取得するには、2つの方法があります。特定のタイムスタンプ範囲(例:過去7日間)内のメンバーを取得する必要がある場合は、メンバーを取得するために使用する必要があります。次に、メンバーをループして、または類似のZREVRANGEBYSCORE各ハッシュを取得します。サーバーへの1回の呼び出しでループを実行する方法については、パイプライン処理HGETALLを参照してください。

redis 127.0.0.1:6379> ZREVRANGEBYSCORE media +inf -inf
1) "media:2"
2) "media:3"
3) "media:1"
redis 127.0.0.1:6379> HGETALL media:2
1) "id"
2) "2"
3) "name"
4) "media two"
5) "content"
6) "content string for two"

最後のn個のメンバー(または、たとえば、最新の10番目から最新の100番目)のみを取得する場合SORTは、アイテムを取得するために使用できます。構文と、さまざまなハッシュフィールドを取得する方法、結果を制限する方法、およびその他のオプションについては、並べ替えのドキュメントを参照してください。

redis 127.0.0.1:6379> SORT media BY nosort GET # GET *->name GET *->content1) DESC
1) "media:2"
2) "media two"
3) "content string for two"
4) "media:3"
5) "media three"
6) "content string for three"
7) "media:1"
8) "media one"
9) "content string for one"

注意:ソートされたハッシュをスコア(BY nosort)でソートすることは、Redis2.6でのみ機能します。

最終日、週、月などのメディアを取得する予定の場合は、それぞれに個別の並べ替えられたセットを使用ZREMRANGEBYSCOREし、古いメンバーを削除するために使用することをお勧めします。次にSORT、これらのソートされたセットで使用して、データを取得できます。

于 2012-12-13T16:06:08.720 に答える