定義
Redisは、C言語で開発されたオープンソースの高性能なKey-Valueペアインメモリデータベースです。NoSQLのインメモリデータベースです。
性格描写
- 優れたパフォーマンス、メモリ内のデータ、非常に高速な読み取り/書き込み速度、シングル・マシン・サポート同時10W QPS
- 単一プロセス、単一スレッド、スレッドセーフ、IO多重化機構を使用
- 豊富なデータ型、文字列、ハッシュ、リスト、集合、順序付き集合などをサポート。
- データの永続性をサポート。メモリ内のデータをディスクに保存し、再起動時にロード可能。
- マスター-スレーブ・レプリケーション、Sentry、高可用性
- 分散ロックとして使用可能
- メッセージング・ミドルウェアとして使用可能、パブリッシュ・サブスクライブをサポート
データタイプ
- redisObjectはタイプエンコーディング、データポインタ、仮想メモリなどを備えています!
- 文字列:基本型、文字列型はバイナリセーフ、文字列型は任意のデータを格納することができ、値は512Mまで格納することができます。
- redisハッシュは文字列のキーと値のマッピングテーブルで、ハッシュは特にオブジェクトの保存に適しています。一般的なコマンド: hget, hset, hgetall など。アプリケーションシナリオ: ユーザー属性の保存、読み込み、変更
- listリストは、挿入順でソートされた文字列の単純なリストです。一般的なコマンド: lpush, rpush, lpop, rpop, lrange。 アプリケーションシナリオ: フォローリスト、ファンリスト、最新ニュースキュー、メッセージキュー。
- setは文字列型の順序なし集合です。順序がなく、重複もありません。一般的なコマンド: sdd、spop、members、sunion。 アプリケーションのシナリオ: 共通の友人、サイトへのすべての Ip 訪問の統計。
- zset は set のような文字列型の要素の集まりで、順序付けされ重複を許しません。一般的なコマンド:zadd、zrange、zrem、zcard。内部では、HashMapとジャンプテーブルの使用は、データが格納され、順序を確保するために、HashMapは、マッピングのスコアにメンバーに配置され、ジャンプテーブルは、スコアのストレージ内のHashMapに基づいてソートのすべてのメンバーに格納されている間、ジャンプテーブル構造の使用は、比較的高い得ることができます。ジャンプテーブル構造の使用は、より高い検索効率を達成することができます。シナリオ: リーダーボード; 重みを持つメッセージキュー
データ構造
- int
- embstr
- raw
- LinkedList
- QuickList
- ZipList
- Intset
- Dict
- SkipList
使用方法
- RedisTemplate
キャッシュの問題
- キャッシュとデータベースのデータ整合性の問題
- 両者間の強い一貫性は保証できません
- キャッシュとデータベース間のデータ不整合の確率を減らすために、適切な戦略を採用するしかありません。
- データベースを更新した後にキャッシュを更新し、キャッシュが失敗したときにリトライするメカニズムを追加します。
- キャッシュ雪崩
- 説明: 複数のキャッシュ・キーが同時に無効化され、リクエストがすべてデータベースに落ちるため、 データベースがヒットしてハングします。 解決策: キーデータが同時に無効にならないように、各キーの有効期限にランダムな値を追加します。
- キャッシュ侵入
- 説明:ユーザがキャッシュとデータベースの両方に存在しないidでリクエストを開始し、キャッシュを通してデータベースを継続的に攻撃することで、データベースへの負荷が高くなり、データベースを深刻にクラッシュさせる可能性があります。
- 解決策
- ユーザー認証を実行し、不正なユーザーの要求は直接返されます。
- ブルームフィルタは、すぐにあなたのキーがデータベースに存在するかどうかを判断するために効率的なデータ構造とアルゴリズムの使用は、あなたが良いに戻り、そこにDBをチェックしに行く存在しないKVをリフレッシュしてから返されます。
- キャッシュの内訳
- 説明:非常にホットなキーは、常にキャッシュヒットの結果、データベースに直接、継続的な大規模な同時実行、有効期限の瞬間のキーは、要求の多数にさらされています。
- なぜRedisは、解決するために非常に高速です:ホットデータが期限切れになることはありません設定するか、相互排他ロックが修正されます追加します!
Redisが速い理由
- 提供される公式データは100000以上のQPSに達することができ、このデータはMemcachedより悪くありません!
- Redisは完全にメモリベースの操作であり、CPUがRedisのボトルネックになることはなく、マシンのメモリサイズやネットワーク帯域幅がボトルネックになる可能性が高いため、Redisは確かにシングルプロセス、シングルスレッド・モデルです。シングルスレッドは実装が簡単で、CPUがボトルネックにならないため、シングルスレッドのソリューションを使用するのが論理的です。
- 最初に:Redisは完全にメモリベースであり、リクエストの大部分は純粋なメモリ操作であり、非常に迅速に、データはメモリ上に存在し、HashMapに似て、HashMapの利点は、検索し、時間の複雑さがO(1)である操作することです。
- 2つ目:簡単なデータ構造とデータの簡単な操作。
- 第三に:シングルスレッドの使用は、不要なコンテキストスイッチングと競争条件を回避し、CPUの切り替えによって引き起こされるマルチスレッドがない、ロックの様々なことを考える必要はありません、ロックリリースロック操作は、パフォーマンスの消費によって引き起こされるデッドロックの問題はありません。
- 第四:ノンブロッキングIOで多重化IOモデルを使用。
RedisとMemcachedの違い
- ストレージ:memcacheは、メモリ上にすべてのデータを配置し、停電がハングアップし、データは、メモリのサイズを超えることはできません。
- データ型のサポート:memcacheのデータ型のサポートはシンプルで、単純なキーバリューしかサポートしていませんが、redisは5つのデータ型をサポートしています。
- redisは直接、独自のVMメカニズムを構築するため、一般的なシステムコールシステム関数は、それが移動し、要求するためにいくつかの時間を無駄になります。
- 値のサイズ:redisは1GBまで、memcacheは1MBまでです。
鍵の有効期限ポリシー
- 時限削除
- 不活性削除
フェーズアウト戦略
- volatile-lru:有効期限が設定されたKVセットから、最も最近使用されたデータを優先します。
- volitile-ttl:有効期限が設定されたKVの集合から、残り時間の短いデータを優先的に削除。
- volitile-random:有効期限を設定したKVセットから削除するデータを無作為に選択
- allkeys-lru:すべてのKVセットから最も最近使用されたデータに優先順位をつけます。
- allKeys-random: 全 KV セットから無作為にデータを選択し、消去します。
- noeviction: 最大メモリを超えた場合、エラーメッセージを返します。
客観化
- RDB: スナップショット形式は、メモリ上のデータを直接ダンプファイルに保存することです。
- bgsave
- bgsave
- fork()
- AOF:Redisのサーバーに変更を加えるすべてのコマンドを1つのファイルに保存するコマンド集。
- fsync
- always
- fsync
- always
- no
- Redisが再起動すると、AOFファイルに保存されたデータセットはRDBファイルに保存されたものよりも完全であることが多いため、AOFファイルを優先的に使用してデータセットを復元します。
事
- Rewrite
- マルチ
- キューに入れられた
- multi
- queued
- exec/discard
分散ロック
- setnxコマンドのアトミック性は、分散システムの1つのノードで1つのスレッドだけがロックを取得できることを保証するために使用されます。
- 有効期限の設定
- 更新
- 他人のロックの解除防止
- 一般的なレディソン・フレームワークの実装
マスタースレーブレプリケーション
- マスター・スレーブ構成とセンチネルモードを組み合わせることで、単一障害点の問題が解決され、redisの可用性が向上します。スレーブノードは読み取り操作のみを行い、マスターノードは書き込み操作を行います。読み込みが多く書き込みが少ない状況では、マスターノードに複数のスレーブノードを構成して応答効率を向上させることができます。
- マスター-スレーブ・レプリケーション・プロセス
- スレーブノードがslaveofを実行し、マスターノードに関する情報を保存します。
- スレーブノードのタイマータスクがマスターノードの情報を発見し、マスターノードとのソケット接続を確立します。
- スレーブノードがping信号を送信し、マスターノードがpongを返します。
- 接続が確立されると、マスターノードはすべてのデータをスレーブノードに送信します。
- マスターノードが現在のデータをスレーブノードに同期すると、レプリケーションプロセスが完了します。次に、マスターノードはスレーブノードに書き込みコマンドを継続的に送信し、マスタースレーブ間のデータの一貫性を確保します。
- データの同期処理
- edis2.8ではsync [runId] [ offset] syncコマンドを、redis2.8以降ではpsync [runId] [offset]コマンドを使用します。
- syncコマンドは完全なレプリケーション処理のみをサポートし、psyncは完全なレプリケーションと部分的なレプリケーションをサポートします。
- runId: redisノードの起動ごとに一意のuuidが生成され、redisが再起動するたびにrunIdが変更されます。
- offset: マスターノードとスレーブノードの両方が独自のマスタースレーブレプリケーションオフセットを保持します。
- マスターノードからスレーブノードにデータを送信する過程で、マスターノードもいくつかの書き込み操作を行い、この時のデータはレプリケーションバッファに保存されます。スレーブノードがマスタノードからのデータの同期を終了すると、マスタノードはバッファ内のデータをスレーブノードに送信して部分レプリケーションを継続します。
- マスターノードが書き込みコマンドに応答すると、スレーブノードにネーミングを送信するだけでなく、レプリケーションコマンドによって失われたデータの修復に使用されるレプリケーションバックログバッファにも書き込みます。
- スレーブ・ノードが psync [runId] [offset] コマンドを送信すると、マスター・ノードには 3 つの応答があります:
- FULLRESYNC:最初の接続、完全なレプリケーションが実行されます。
- CONTINUE: 部分的なレプリケーションが実行されます。
- ERR: psync コマンドはサポートされていません。
- edis2.8ではsync [runId] [ offset] syncコマンドを、redis2.8以降ではpsync [runId] [offset]コマンドを使用します。
- フルレプリケーションのプロセス
- スレーブノードがpsync ? -1 コマンドを送信します。
- マスターノードはスレーブノードが最初のレプリケーションであることを検出し、FULLRESYNC {runId} {offset}を返します。runIdはマスターノードのrunId、offsetはマスターノードの現在のオフセットです。
- スレーブ・ノードはマスタ・ノードの情報を受信して info に保存します。
- 4.マスターノードはFULLRESYNCを送信した後、bgsaveコマンドを起動してRDBファイルを生成します。
- 5、マスターノードがRDBファイルをスレーブノードに送信します。マスターノードからのライトコマンドは、スレーブノードがデータのロードを終了するまでの間、バッファに置かれます。
- 6.スレーブノードは自身のデータベースデータをクリーンアップします。
- 7、スレーブノードはRDBファイルをロードし、データを自身のデータベースに保存します。
- 8、スレーブノードがAOFをオンにしている場合、スレーブノードは非同期でAOFファイルを書き換えます。
- 部分レプリケーションのプロセス
- 部分レプリケーションは、フルレプリケーションの高いオーバーヘッドに対するRedisの最適化であり、psync[runId][offset]コマンドを使用して実装されます。スレーブノードがマスターノードをレプリケートしているとき、ネットワークフラッシュやコマンドロスなどの異常が発生すると、スレーブノードがマスターノードに失われたコマンドデータの送信を要求し、マスターノードのレプリケーションバックログバッファがデータのこの部分を直接スレーブノードに送信し、マスターノードとスレーブノードのレプリケーションの一貫性を維持することができます。一般的に、送り返されるデータのこの部分は、完全なデータ量よりもはるかに小さくなります。
- マスタ-スレーブ接続の中断中もマスタ・ノードはコマンドに応答しますが、レプリケーション接続の中断によりコマンドをスレーブ・ノードに送信することはできませんが、マスタ・ノードのレプリケーション・バックログ・バッファには直近の期間の書き込みコマンド・データを保存することができます。
- マスタ・スレーブ接続が回復すると、スレーブ・ノードは自身のレプリケートされたオフセットとマスタ・ノードのランタイムIDを保存するため、それらをpsyncパラメータとしてマスタ・ノードに送信し、部分レプリケーションを要求します。
- マスターノードはpsyncコマンドを受信した後、まずパラメータrunIdが自分自身と一致するかどうかをチェックし、一致する場合は、レプリケーションが現在のマスターノードであることを意味します。その後、パラメータオフセットに従って、レプリケーションバックログバッファを検索し、オフセット後のデータが存在する場合は、+COUTINUEコマンドをスレーブノードに送信し、レプリケーションの一部を実行できることを示します。バッファサイズは固定であるため、バッファオーバーフローが発生するとフルレプリケーションが実行されます。
- マスターノードはオフセットに従ってレプリケーションバックログバッファのデータをスレーブノードに送信し、マスタースレーブレプリケーションが正常な状態になるようにします。
歩哨
- マスタースレーブレプリケーションの問題点は何ですか?
- マスターノードがダウンすると、スレーブノードがマスターノードに昇格しますが、同時にアプリケーション側でマスターノードのアドレスを変更する必要があり、また、すべてのスレーブノードに新しいマスターノードをレプリケートするように命令する必要があり、すべてのプロセスに手作業が必要です。
- マスターノードの書き込み能力は1台のマシンで制限されます。
- マスターノードのストレージ容量は1台のマシンによって制限されます。
- 例えば、redisのレプリケーションが停止した後、スレーブノードはpsyncを開始します。この時、同期が失敗すると完全な同期が実行され、マスターリポジトリは同時に完全なバックアップを実行するため、ミリ秒から数秒のタイムラグが発生する可能性があります。
- センチネル機能 主な機能には、マスタ・ノードの生存検出、マスタ・スレーブ動作の検出、自動フェイルオーバー、マスタ・スレーブ切り替えなどがあります。
- 監視:マスターとスレーブが正常に稼働しているかを常時チェックします。
- 通知:監視対象のredisサーバに問題が発生した場合、APIスクリプトを通じて管理者や他のアプリケーションに通知を送信します。
- 自動フェイルオーバー: マスターノードが正常に機能しなくなると、Sentinelは自動フェイルオーバー操作を開始します。この操作は、障害が発生したマスターノードとマスタースレーブ関係にあるスレーブノードの1つをアップグレードして新しいマスターノードにし、他のスレーブノードを新しいマスターノードに指定します。
- コンフィギュレーション・プロバイダ:Redis Sentinelモードでは、クライアント・アプリケーションは初期化時にSentinelノードのコレクションに接続し、そこからマスター・ノードに関する情報を取得します。
- どのように動作するか
- 各Sentinelノードは、定期的に次のタスクを実行する必要があります。各Sentinelは、マスターサーバー、スレーブサーバー、および1秒に1回の頻度でそれに知られている他のSentinelインスタンスにPINGコマンドを送信します。
- インスタンスがPINGコマンドへの最後の有効な応答からdown-after-millisecondsで指定された値以上である場合、そのインスタンスはセンチネルによって主観的にダウンとしてマークされます。
- マスターサーバーが主観的ダウンとマークされた場合、このサーバーを監視しているすべてのセンチネルノードは、マスターサーバーが主観的ダウン状態になったことを1秒に1回の割合で確認します。
- マスターサーバーが主観的にオフラインとマークされ、指定された時間枠内に十分な数のSentinelがこの判断に同意した場合、このマスターサーバーは客観的にオフラインとマークされます。
- 通常、各センチネルは、10秒に1回の頻度で、それが知っているすべてのマスターサーバーとスレーブサーバーにINFOコマンドを送信します。 マスターサーバーが客観的にオフラインとマークされると、センチネルがオフラインのマスターサーバーのすべてのスレーブサーバーに送信するINFOコマンドの頻度は、10秒に1回から1秒に1回に変更されます。
- Sentinelは、客観的にダウンしているマスターノードのステータスについて他のSentinelとネゴシエートし、SDOWN状態であれば、新しいマスターノードに自動的に投票し、残りのスレーブノードを新しいマスターノードにポイントしてデータをレプリケートします。
- マスターサーバーをオフラインにすることに同意するSentinelsの数が十分でない場合、マスターサーバーの客観的なオフラインステータスは削除されます。マスターサーバーの主観的なオフラインステータスは、マスターサーバーが再びSentinelのPINGコマンドに有効な応答を返すと削除されます。