一、redisデータ構造の使用シーン

以前redisbookという本を読んで、redisの基本機能はすでに熟知していましたが、先週からredisのソースコードを読み始めました。現在の目標はredisのデータ構造を完全に理解することです。ご存知の通り、redisには全部で5つのデータ構造がありますが、それぞれのデータ構造の使用シーンはどのようなものなのでしょうか。

  • String——文字列
  • Hash——字典
  • List——列表
  • Set——集合
  • Sorted Set——ソート済みセット

それでは、それぞれの使用シーンについて簡単に説明します:

1. String——文字列

Stringデータ構造はシンプルなkey-value型で、valueはStringだけでなく数値にもなります(数値型がLongで表現できる場合、encodingは整数型になり、それ以外はすべてsdshdrに文字列として格納されます)。Strings型を使用すると、現在のMemcachedの機能を完全に実装でき、しかも効率がさらに高くなります。また、Redisの定期永続化(RDBモードまたはAOFモードを選択可能)、操作ログ、Replicationなどの機能も利用できます。Memcachedと同じget、set、incr、decrなどの操作を提供するだけでなく、Redisは以下の操作も提供しています:

  • LEN niushuai:O(1)で文字列長を取得
  • APPEND niushuai redis文字列に内容をappendし、しかもインテリジェントなメモリ割り当て(毎回2倍)を採用します。
  • 文字列の特定の範囲の内容を設定および取得する
  • 文字列の特定のビット(bit)を設定・取得します。
  • 一連の文字列の内容を一括設定する
  • 原子计数器
  • GETSETコマンドの巧妙な使い方:古い値をクリアすると同時に新しい値を設定し、アトミックカウンターと併用します。

2. Hash——字典

Memcachedでは、構造化された情報をhashmapにまとめ、クライアント側でシリアライズした後に文字列の値(通常はJSON形式)として格納することがよくあります。例えば、ユーザーのニックネーム、年齢、性別、ポイントなどです。このとき、その中の特定の項目を変更する必要がある場合、通常は文字列(JSON)を取り出してデシリアライズし、特定の項目の値を変更してから、再び文字列(JSON)にシリアライズして保存し直す必要があります。単純な属性を1つ変更するだけでこれだけのことを行うのは、コストが大きくなり、並行操作が発生する可能性のある場面(例えば、2つの並行操作がどちらもポイントを変更する必要がある場合)にも適していません。一方、RedisのHash構造を使用すると、データベースで属性をUpdateするように、特定の属性値を1つだけ変更できます。

  • ユーザー属性の保存、読み取り、変更

3. List——列表

Listは要するにリンクリストです(redisは双方向リンクリストでListを実現しています)。データ構造の知識を学んだことがある人なら誰でもその構造を理解できるはずです。List構造を使用することで、最新メッセージランキングなどの機能(例えば新浪微博のTimeLine)を簡単に実装できます。Listのもう一つの応用はメッセージキューです。Listの*PUSH操作を利用してタスクをListに保存し、ワーカースレッドがPOP操作でタスクを取り出して実行します。Redisはまた、List内の特定の範囲の要素を操作するAPIを提供しており、List内の特定の範囲の要素を直接照会したり削除したりできます。

  • 微博 TimeLine
  • 消息队列

4. Set——集合

Setはつまり集合です。集合の概念とは、重複しない値の組み合わせのことです。Redisが提供するSetデータ構造を利用して、集合的なデータを保存できます。例えば、微博アプリでは、あるユーザーのすべてのフォロー先を一つの集合に保存し、そのすべてのファンを別の集合に保存できます。Redisは集合に対して積集合、和集合、差集合などの操作を非常に使いやすく提供しているため、共通のフォロー、共通の好み、友達の友達などの機能を非常に簡単に実現できます。上記のすべての集合操作について、異なるコマンドを使用して、結果をクライアントに返すか新しい集合に保存するかを選択できます。

  • 共通の友達、友達の友達
  • 一意性を利用して、ウェブサイトにアクセスするすべての独立したIPを統計できます。
  • 友達を推薦する際に、tagに基づいて積集合を求め、あるしきい値(threshold)より大きければ推薦できます。

5. Sorted Set——ソート済みセット

Setsと比較すると、Sorted SetsはSetの要素に重みパラメータであるscoreを追加したもので、集合内の要素がscoreに従って順序よく並ぶようにします。例えば、クラス全員の成績を格納するSorted Setsでは、その集合のvalueは生徒の学籍番号にでき、scoreは試験の点数にできます。これにより、データを集合に挿入する時点で、自然な並び替えがすでに行われています。また、Sorted Setsを重み付きキューとして使うこともできます。例えば、普通のメッセージのscoreを1、重要なメッセージのscoreを2にし、ワーカースレッドがscoreの降順で作業タスクを取得するように選択できます。重要なタスクを優先のに実行させることができます。

  • 重みを持つ要素、例えばゲームのユーザースコアランキング。
  • 比較的複雑なデータ構造であり、一般的に使用されるシーンはそれほど多くありません。

二、redisのその他の機能の使用シーン

1. パブリッシュ/サブスクライブシステム

Pub/Subは、文字通り理解すると公開(Publish)と購読(Subscribe)です。Redisでは、特定のkey値に対してメッセージの公開とメッセージの購読を設定できます。あるkey値に対してメッセージが公開されると、それを購読しているすべてのクライアントが対応するメッセージを受信します。この機能の最も明確な使い方は、リアルタイムメッセージシステムとしての利用です。例えば、通常のインスタントチャット、グループチャットなどの機能です。

2. 事务——Transactions

NoSQLがすべてトランザクションをサポートしないと誰が言ったのでしょうか。RedisのTransactionsは厳密なACIDトランザクションではありませんが(例えば、EXECで送信して実行される一連のコマンドの実行中にサーバーがダウンした場合、一部のコマンドは実行され、残りは実行されません)、このTransactionsはそれでも基本的なコマンドのパッケージ実行機能を提供します(サーバーに問題が発生しない場合、一連のコマンドが順番にまとめて実行されることを保証でき、その間に他のクライアントのコマンドが割り込んで実行されることはありません)。RedisはまたWatch機能を提供しており、あるkeyをWatchしてからTransactionsを実行できます。その過程で、このWatchされた値が変更された場合、このTransactionsはそれを検出して実行を拒否します。