redis知識ポイントまとめ
6116 ワード
Redisの紹介
Redisは高性能なkey-valueデータベースです.1秒あたり10万+QPS
Redisの特徴はデータの持続化をサポートし、メモリのデータをディスクに保存し、再起動時に を再ロードすることができる.はKVタイプのデータをサポートし、その他の豊富なデータ構造ストレージ もサポートする.は、データバックアップ、すなわちmaster-slaveモードのデータバックアップ をサポートする.
Redisがサポートするデータ構造 STRING:文字列、整数または浮動小数点数 LIST:同じ文字列を複数格納可能なリスト SET:集合、異なる要素を格納、無秩序に 配列 HASH:ハッシュリスト、キー値ペア間のマッピングを格納、無秩序配列 . ZSET:整列集合、キー値ペア、整列配列 RedisとMemcacheの違い
ひかくこうもく
Redis
Memcache
データ構造
豊富なデータ型
単純KVデータ型のみサポート
データ整合性
取引
cas
持続性
スナップショット/OF
サポートされていません
ネットワークIO
シングルラインIO多重
マルチスレッド、非ブロックIO多重化
メモリ管理メカニズム
オンサイト申請メモリ
メモリの事前割り当て
サブスクリプションの発行
パブリッシュサブスクリプション(pub/sub)は、送信者(pub)がメッセージを送信し、サブスクライバ(sub)がメッセージを受信するメッセージ通信モードである.
永続化ポリシー
スナップショットの永続化
ある時点のすべてのデータをハードディスク(HDD)に書き込みます.
AOF持続化
ファイルのみを追加し、書き込みコマンドを実行すると、実行された書き込みコマンドをハードディスクにコピーします.AOFポリシーを使用すると、ハードディスクに大量の書き込みが必要になります.Redisの処理速度はハードディスクのパフォーマンスに制限されます.
Redisトランザクション
Redisトランザクションでコマンドの実行に失敗した場合、その後のコマンドは続行されます.
DISCARDを使用すると、トランザクションをキャンセルし、トランザクションブロック内のすべてのコマンドを実行できなくなります.
分散ロックの実装方法
方式一
欠陥:C 1の実行時間が長すぎてロックが自発的に解放されず、C 2はC 1のロックがタイムアウトした後にロックを取得し、C 1とC 2が同時に実行され、データの不一致などの未知の状況をもたらす可能性がある.C 1が先に実行されると、C 2のロックが解放され、他のC 3がロックを取得する可能性がある
方式2
欠陥:極めて高い同時シーン(お年玉を奪うシーンなど)では、UnixTimestampの重複問題がある可能性があります.分散環境での物理クロックの一貫性は保証されず、UnixTimestampの重複問題も発生する可能性があります.
方程式3
実行
現在、最適な分散ロックスキームが存在するが、クラスタの下で依然として問題がある場合.Redisクラスタのデータ同期は非同期であるため、Masterノードがロックを取得した後にデータ同期が完了しない場合、Masterノードcrashは、新しいMasterノードでもロックを取得できると仮定し、複数のClientが同時にロックを取得する
Redis期限切れポリシーおよびメモリ淘汰メカニズム
期限切れポリシー
Redisの期限切れポリシーとは、RedisでキャッシュされたKeyが期限切れになった場合に、Redisがどのように処理するかを意味します.タイミングの有効期限:有効期限を設定したKeyごとにタイマを作成し、有効期限になるとすぐにクリアします.メモリは友好的で、CPUは友好的ではありません 不活性期限切れ:Keyにアクセスしたときに期限切れかどうかを判断し、期限切れすればクリアする.CPUは友好的で、メモリは友好的ではありません 定期期限切れ:一定時間おきにexpires辞書で一定数のKeyをスキャンし、期限切れのKeyをクリアします.メモリとCPUリソースが最適なバランス効果を達成する メモリ淘汰メカニズム noeviction:新しい書き込み操作は とエラーが発生します. allkeys-lru:最近最も使用されていないkey を削除 allkeys-random:いくつかのkey をランダムに除去 volatile-lru:有効期限が設定されているキーから、最近最も少ないkey を削除します. volatile-random:有効期限が設定されているキーから、いくつかのkey をランダムに削除します. volatile-ttl:有効期限が設定されているキーに、より早い有効期限があるkey優先削除 なぜRedisは単一スレッドなのか
Redisはメモリベースの操作であり、CPUはRedisのボトルネックではなく、Redisのボトルネックはメモリまたはネットワークである可能性が高い.また,単一スレッドで実現しやすく,不要なコンテキスト切替や競合条件を回避し,マルチスレッド切替消費CPUが存在しない.
CPUマルチコアの利用方法
モノリシックシングルインスタンスでは、操作がO(N)、O(log(N))の複雑さであれば、CPUに対する消費はそれほど高くない.CPUを最大限に活用するために、シングルマシンで複数のインスタンスを導入できます.
集合コマンドの実装方法
コマンド#コマンド#
intset符号化の実現方法
hashtable符号化の実現方法
SADD
intsetAdd関数を呼び出し、すべての新しい要素を整数セットに追加します.
dictAddを呼び出し、新しい要素をキー、NULLを値とし、キー値のペアを辞書に追加します.
SCARD
intsetLen関数を呼び出し、集合オブジェクトに含まれる要素の数である整数集合に含まれる要素の数を返します.
dictSize関数を呼び出し、辞書に含まれるキー値ペアの数を返します.この数は、集合オブジェクトに含まれる要素の数です.
SISMEMBER
intsetFind関数を呼び出し、整数セットで指定した要素を検索します.要素がセットに存在する場合、見つからない場合は、要素がセットに存在しないことを示します.
dictFind関数を呼び出し、辞書のキーで指定した要素を検索します.説明要素がセットに存在する場合、見つからない場合は、説明要素はセットに存在しません.
SMEMBERS
整数セット全体を巡回し、inisetGet関数を呼び出して集合要素を返します.
辞書全体を巡り、dictGetKey関数を使用して辞書のキーを集合要素として返します.
SRANDMEMBER
intsetRandom関数を呼び出し、整数セットから要素をランダムに返します.
dictGetRandomKey関数を呼び出し、辞書から辞書キーをランダムに返します.
SPOP
intsetRandom関数を呼び出し、整数セットからランダムに要素を取り出し、このランダム要素をクライアントに返した後、intsetRemove関数を呼び出し、ランダム要素を整数セットから削除します.
dictGetRandomKey関数を呼び出し、辞書から辞書キーをランダムに取り出し、このランダム辞書キーの値をクライアントに返した後、dictDelete関数を呼び出し、辞書からランダム辞書キーに対応するキー値ペアを削除します.
SREM
intsetRemove関数を呼び出し、整数セットから指定されたすべての要素を削除します.
dictDelete関数を呼び出し、辞書からすべてのキーが指定された要素のキー値ペアであることを削除します.
秩序化集合コマンドの実装方法
コマンド#コマンド#
ziplist符号化の実現方法
zset符号化の実現方法
ZADD
ziplistInsert関数を呼び出し、メンバーとスコアを圧縮リストに2つのノードとして挿入します.
zslInsert関数を呼び出し、新しい要素をジャンプテーブルに追加し、dictAdd関数を呼び出し、新しい要素を辞書に関連付けます.
ZCARD
ziplistLen関数を呼び出し、圧縮リストに含まれるノードの数を求めます.この数を2で割って集合要素の数を求めます.
ジャンプテーブルのデータ構造にアクセスするlengthプロパティ、コレクション要素に直接アクセスする数
ZCOUND
圧縮リストを巡回し、指定した範囲内のノードの数を統計します.
ジャンプテーブルを巡回し、指定した範囲内のノードの数を統計します.
ZRANGE
圧縮リストをヘッダーから末尾に巡回し、指定したインデックス範囲内のすべての要素を返します.
テーブルの先頭からテーブルの末尾にジャンプテーブルを巡回し、指定したインデックス範囲内のすべての要素を返します.
ZREVRANGE
表の末尾は圧縮リストをヘッダーに巡り、指定したインデックス範囲内のすべての要素を返します.
テーブルの末尾からテーブルヘッダにジャンプテーブルを巡回し、指定したインデックス範囲のすべての要素を返します.
ZRANK
圧縮されたリストをヘッダーから末尾に巡回し、指定されたメンバーを検索し、ノードを通過する数を沿道に記録します.指定されたメンバーが見つかった後、沿道ノードの数はそのメンバーに対応する要素のランキングです.
テーブルの先頭からテーブルの末尾にジャンプテーブルを巡回し、指定されたメンバーを検索し、ノードを通過する数を沿道に記録します.指定されたメンバーが見つかった後、沿道ノードの数はそのメンバーに対応する要素のランキングです.
ZREVRANK
圧縮リストを表の末尾から表の先頭に移動し、指定されたメンバーを検索し、ノードを通過する数を沿道で記録します.指定されたメンバーが見つかった後、沿道ノードの数はそのメンバーに対応する要素のランキングです.
表の末尾から表の先頭に向かってジャンプ表を巡回し、指定されたメンバーを検索し、ノードを通過する数を沿道で記録します.指定されたメンバーが見つかった後、沿道ノードの数はそのメンバーに対応する要素のランキングです.
ZREM
圧縮リストを巡回し、指定したメンバーを含むすべてのノードと、削除されたメンバーノードの横にあるスコアノードを削除します.
ジャンプテーブルを巡回し、指定したメンバーを含むすべてのジャンプテーブルノードを削除します.削除された要素のメンバーとスコアの関連付けを辞書で解除します.
ZSCORE
圧縮リストを巡り、指定したメンバーが含まれているノードを検索し、メンバーノードの横にあるスコアノードに保存されている要素スコアを取り出します.
指定したメンバーのスコアを辞書から直接取り出す
Redisは高性能なkey-valueデータベースです.1秒あたり10万+QPS
Redisの特徴
Redisがサポートするデータ構造
ひかくこうもく
Redis
Memcache
データ構造
豊富なデータ型
単純KVデータ型のみサポート
データ整合性
取引
cas
持続性
スナップショット/OF
サポートされていません
ネットワークIO
シングルラインIO多重
マルチスレッド、非ブロックIO多重化
メモリ管理メカニズム
オンサイト申請メモリ
メモリの事前割り当て
サブスクリプションの発行
パブリッシュサブスクリプション(pub/sub)は、送信者(pub)がメッセージを送信し、サブスクライバ(sub)がメッセージを受信するメッセージ通信モードである.
永続化ポリシー
スナップショットの永続化
ある時点のすべてのデータをハードディスク(HDD)に書き込みます.
BGSAVE
コマンドを使用すると、メモリ使用量が増加するにつれて、BGSAVEを実行すると、システムが長時間停止する可能性があります.AOF持続化
ファイルのみを追加し、書き込みコマンドを実行すると、実行された書き込みコマンドをハードディスクにコピーします.AOFポリシーを使用すると、ハードディスクに大量の書き込みが必要になります.Redisの処理速度はハードディスクのパフォーマンスに制限されます.
Redisトランザクション
redis> MULTI #
OK
redis> INCR user_id #
QUEUED
redis> INCR user_id
QUEUED
redis> INCR user_id
QUEUED
redis> PING
QUEUED
redis> EXEC #
1) (integer) 1
2) (integer) 2
3) (integer) 3
4) PONG
Redisトランザクションでコマンドの実行に失敗した場合、その後のコマンドは続行されます.
DISCARDを使用すると、トランザクションをキャンセルし、トランザクションブロック内のすべてのコマンドを実行できなくなります.
分散ロックの実装方法
方式一
tryLock() {
SETNX Key 1 Seconds}
release() {
DELETE Key}
欠陥:C 1の実行時間が長すぎてロックが自発的に解放されず、C 2はC 1のロックがタイムアウトした後にロックを取得し、C 1とC 2が同時に実行され、データの不一致などの未知の状況をもたらす可能性がある.C 1が先に実行されると、C 2のロックが解放され、他のC 3がロックを取得する可能性がある
方式2
tryLock() {
SETNX Key UnixTimestamp Seconds}
release() {
EVAL ( //LuaScript if redis.call("get", KEYS[1] == ARGV[1]) then return redis.call("del", KEYS[1]) else return 0 end )}
欠陥:極めて高い同時シーン(お年玉を奪うシーンなど)では、UnixTimestampの重複問題がある可能性があります.分散環境での物理クロックの一貫性は保証されず、UnixTimestampの重複問題も発生する可能性があります.
方程式3
tryLock() {
SET Key UniqId Seconds}
release() {
EVAL ( //LuaScript if redis.call("get", KEYS[1]) == ARGV[1] then return redis.call("del", KEYS[1]) else return 0 end )}
実行
SET key value NX
の効果は実行に等しいSETNX key value
現在、最適な分散ロックスキームが存在するが、クラスタの下で依然として問題がある場合.Redisクラスタのデータ同期は非同期であるため、Masterノードがロックを取得した後にデータ同期が完了しない場合、Masterノードcrashは、新しいMasterノードでもロックを取得できると仮定し、複数のClientが同時にロックを取得する
Redis期限切れポリシーおよびメモリ淘汰メカニズム
期限切れポリシー
Redisの期限切れポリシーとは、RedisでキャッシュされたKeyが期限切れになった場合に、Redisがどのように処理するかを意味します.
[root]# redis-cli config get maxmemory-policy
1) "maxmemory-policy"
2) "noeviction"
Redisはメモリベースの操作であり、CPUはRedisのボトルネックではなく、Redisのボトルネックはメモリまたはネットワークである可能性が高い.また,単一スレッドで実現しやすく,不要なコンテキスト切替や競合条件を回避し,マルチスレッド切替消費CPUが存在しない.
CPUマルチコアの利用方法
モノリシックシングルインスタンスでは、操作がO(N)、O(log(N))の複雑さであれば、CPUに対する消費はそれほど高くない.CPUを最大限に活用するために、シングルマシンで複数のインスタンスを導入できます.
集合コマンドの実装方法
コマンド#コマンド#
intset符号化の実現方法
hashtable符号化の実現方法
SADD
intsetAdd関数を呼び出し、すべての新しい要素を整数セットに追加します.
dictAddを呼び出し、新しい要素をキー、NULLを値とし、キー値のペアを辞書に追加します.
SCARD
intsetLen関数を呼び出し、集合オブジェクトに含まれる要素の数である整数集合に含まれる要素の数を返します.
dictSize関数を呼び出し、辞書に含まれるキー値ペアの数を返します.この数は、集合オブジェクトに含まれる要素の数です.
SISMEMBER
intsetFind関数を呼び出し、整数セットで指定した要素を検索します.要素がセットに存在する場合、見つからない場合は、要素がセットに存在しないことを示します.
dictFind関数を呼び出し、辞書のキーで指定した要素を検索します.説明要素がセットに存在する場合、見つからない場合は、説明要素はセットに存在しません.
SMEMBERS
整数セット全体を巡回し、inisetGet関数を呼び出して集合要素を返します.
辞書全体を巡り、dictGetKey関数を使用して辞書のキーを集合要素として返します.
SRANDMEMBER
intsetRandom関数を呼び出し、整数セットから要素をランダムに返します.
dictGetRandomKey関数を呼び出し、辞書から辞書キーをランダムに返します.
SPOP
intsetRandom関数を呼び出し、整数セットからランダムに要素を取り出し、このランダム要素をクライアントに返した後、intsetRemove関数を呼び出し、ランダム要素を整数セットから削除します.
dictGetRandomKey関数を呼び出し、辞書から辞書キーをランダムに取り出し、このランダム辞書キーの値をクライアントに返した後、dictDelete関数を呼び出し、辞書からランダム辞書キーに対応するキー値ペアを削除します.
SREM
intsetRemove関数を呼び出し、整数セットから指定されたすべての要素を削除します.
dictDelete関数を呼び出し、辞書からすべてのキーが指定された要素のキー値ペアであることを削除します.
秩序化集合コマンドの実装方法
コマンド#コマンド#
ziplist符号化の実現方法
zset符号化の実現方法
ZADD
ziplistInsert関数を呼び出し、メンバーとスコアを圧縮リストに2つのノードとして挿入します.
zslInsert関数を呼び出し、新しい要素をジャンプテーブルに追加し、dictAdd関数を呼び出し、新しい要素を辞書に関連付けます.
ZCARD
ziplistLen関数を呼び出し、圧縮リストに含まれるノードの数を求めます.この数を2で割って集合要素の数を求めます.
ジャンプテーブルのデータ構造にアクセスするlengthプロパティ、コレクション要素に直接アクセスする数
ZCOUND
圧縮リストを巡回し、指定した範囲内のノードの数を統計します.
ジャンプテーブルを巡回し、指定した範囲内のノードの数を統計します.
ZRANGE
圧縮リストをヘッダーから末尾に巡回し、指定したインデックス範囲内のすべての要素を返します.
テーブルの先頭からテーブルの末尾にジャンプテーブルを巡回し、指定したインデックス範囲内のすべての要素を返します.
ZREVRANGE
表の末尾は圧縮リストをヘッダーに巡り、指定したインデックス範囲内のすべての要素を返します.
テーブルの末尾からテーブルヘッダにジャンプテーブルを巡回し、指定したインデックス範囲のすべての要素を返します.
ZRANK
圧縮されたリストをヘッダーから末尾に巡回し、指定されたメンバーを検索し、ノードを通過する数を沿道に記録します.指定されたメンバーが見つかった後、沿道ノードの数はそのメンバーに対応する要素のランキングです.
テーブルの先頭からテーブルの末尾にジャンプテーブルを巡回し、指定されたメンバーを検索し、ノードを通過する数を沿道に記録します.指定されたメンバーが見つかった後、沿道ノードの数はそのメンバーに対応する要素のランキングです.
ZREVRANK
圧縮リストを表の末尾から表の先頭に移動し、指定されたメンバーを検索し、ノードを通過する数を沿道で記録します.指定されたメンバーが見つかった後、沿道ノードの数はそのメンバーに対応する要素のランキングです.
表の末尾から表の先頭に向かってジャンプ表を巡回し、指定されたメンバーを検索し、ノードを通過する数を沿道で記録します.指定されたメンバーが見つかった後、沿道ノードの数はそのメンバーに対応する要素のランキングです.
ZREM
圧縮リストを巡回し、指定したメンバーを含むすべてのノードと、削除されたメンバーノードの横にあるスコアノードを削除します.
ジャンプテーブルを巡回し、指定したメンバーを含むすべてのジャンプテーブルノードを削除します.削除された要素のメンバーとスコアの関連付けを辞書で解除します.
ZSCORE
圧縮リストを巡り、指定したメンバーが含まれているノードを検索し、メンバーノードの横にあるスコアノードに保存されている要素スコアを取り出します.
指定したメンバーのスコアを辞書から直接取り出す