JSON ペイロードを Redis に保存したいのですが、これを行うには 2 つの方法があります。
単純な文字列のキーと値を使用するもの。
キー: ユーザー、値: ペイロード (JSON BLOB 全体、100 ~ 200 KB になる場合があります)SET user:1 payload
ハッシュの使用
HSET user:1 username "someone"
HSET user:1 location "NY"
HSET user:1 bio "STRING WITH OVER 100 lines"
ハッシュを使用する場合、値の長さは予測できないことに注意してください。上記の bio の例のように、すべてが短いわけではありません。
どちらの方がメモリ効率が良いでしょうか? 文字列のキーと値を使用するのと、ハッシュを使用するのとではどちらが良いでしょうか?
ベストアンサー1
この記事には、多くの洞察が提供されています。http://redis.io/topics/メモリ最適化
Redis にオブジェクトの配列を保存する方法はたくさんあります (ネタバレ: ほとんどのユースケースではオプション 1 が適しています)。
オブジェクト全体を JSON エンコードされた文字列として単一のキーに保存し、セット (または適切な場合はリスト) を使用してすべてのオブジェクトを追跡します。例:
INCR id:users SET user:{id} '{"name":"Fred","age":25}' SADD users {id}
一般的に言えば、ほとんどの場合、これがおそらく最良の方法です。オブジェクトに多くのフィールドがあり、オブジェクトが他のオブジェクトとネストされておらず、一度にアクセスするフィールドのサブセットが小さい場合は、オプション 2 を使用する方がよい場合があります。
利点: 「良い方法」と見なされます。各オブジェクトは完全な Redis キーです。JSON 解析は高速で、特にこのオブジェクトの多くのフィールドに一度にアクセスする必要がある場合に便利です。欠点: 1 つのフィールドのみにアクセスする必要がある場合は遅くなります。
各オブジェクトのプロパティを Redis ハッシュに保存します。
INCR id:users HMSET user:{id} name "Fred" age 25 SADD users {id}
利点: 「良い方法」と見なされます。各オブジェクトは完全な Redis キーです。JSON 文字列を解析する必要はありません。欠点: オブジェクト内のすべてのフィールドまたはほとんどのフィールドにアクセスする必要がある場合、速度が低下する可能性があります。また、ネストされたオブジェクト (オブジェクト内のオブジェクト) は簡単に保存できません。
各オブジェクトを Redis ハッシュ内の JSON 文字列として保存します。
INCR id:users HMSET users {id} '{"name":"Fred","age":25}'
これにより、少し統合して、多数のキーの代わりに 2 つのキーのみを使用できます。明らかな欠点は、各ユーザー オブジェクトが Redis ハッシュ内の単なるフィールドであり、完全な Redis キーではないため、TTL (およびその他のもの) を各ユーザー オブジェクトに設定できないことです。
利点: JSON 解析は高速です。特に、このオブジェクトの多くのフィールドに一度にアクセスする必要がある場合は高速です。メイン キーの名前空間の「汚染」が少なくなります。欠点: オブジェクトが多数ある場合、メモリ使用量は #1 とほぼ同じです。1 つのフィールドのみにアクセスする必要がある場合は、#2 よりも低速です。おそらく「良い方法」とは見なされません。
各オブジェクトの各プロパティを専用のキーに保存します。
INCR id:users SET user:{id}:name "Fred" SET user:{id}:age 25 SADD users {id}
上記の記事によると、このオプションはほとんど好まれない(オブジェクトのプロパティに特定の10 ...か何か)。
利点: オブジェクト プロパティは完全な Redis キーであり、アプリにとって過剰ではない可能性があります。欠点: 速度が遅く、メモリを多く使用し、「ベスト プラクティス」とは見なされません。メイン キーの名前空間が大量に汚染されます。
全体概要
オプション 4 は、一般的には好まれません。オプション 1 と 2 は非常に似ており、どちらもかなり一般的です。私は (一般的に言えば) オプション 1 を好みます。これは、より複雑なオブジェクト (複数のネスト層など) を保存できるためです。オプション 3 は、メイン キーの名前空間を汚染しないことを本当に重視する場合に使用されます(つまり、データベースに多くのキーが存在することを望まず、TTL、キー シャーディングなどのことを気にしない)。
もし私が何か間違ったことを言っていたら、ぜひコメントを残して、私が回答を修正できるようにしてから、反対票を投じてください。ありがとうございます! :)