Redis の面接の質問と回答は何ですか?

WBOY
リリース: 2023-05-31 16:55:51
転載
938 人が閲覧しました

Redis の基本データ型について話しましょう

  1. 文字列: Redis は C 言語の従来の文字列表現を直接使用しませんが、単純な動的文字列と呼ばれる独自の SDS 抽象型を実装します。 。 C 言語の文字列は独自の長さ情報を記録しませんが、SDS は長さ情報を保存するため、文字列の長さを O(N) から O(1) に取得する時間が短縮され、バッファ オーバーフローを回避し、変更の必要性が減ります。文字列の長さに必要なメモリの再割り当ての数。

  2. リンク リスト linkedlist: Redis リンク リストは双方向の非循環リンク リスト構造です。多くのパブリッシュとサブスクライブ、スロー クエリ、監視機能はリンク リストを使用して実装されます。各リンク リストノードは listNode 構造で表され、各ノードは前ノードと後続ノードへのポインタを持ち、同時にヘッダノードの前ノードと後続ノードは NULL を指します。

  3. 辞書ハッシュテーブル: キーと値のペアを保存するために使用される抽象データ構造。 Redis は基盤となる実装としてハッシュ テーブルを使用します。各ディクショナリには日常使用と再ハッシュ用に 2 つのハッシュ テーブルがあります。ハッシュ テーブルはチェーン アドレス メソッドを使用してキーの競合を解決し、同じインデックス位置にある複数のキーと値のペアに割り当てられます。ハッシュ テーブルが拡張または縮小される場合、サービスの可用性を考慮して、再ハッシュ プロセスは一度に完了せず、徐々に完了します。

  4. スキップ リスト Skiplist: スキップ リストは、順序付きセットの基礎となる実装の 1 つです。スキップ テーブルは、順序付きセットのキーとクラスター ノードの内部構造を実装するために Redis で使用されます。 Redis スキップ テーブルは zskiplist と zskiplistNode で構成されます。zskiplist はスキップ テーブル情報 (ヘッダー、末尾ノード、長さなど) を保存するために使用されます。zskiplistNode はテーブル スキップ ノードを表すために使用されます。各スキップ テーブルのレイヤーの高さは 1 からランダムです。番号。同じジャンプ テーブル内で、複数のノードに同じスコアを含めることができますが、各ノードのメンバー オブジェクトは一意である必要があります。ノードはスコアのサイズに従って並べ替えられます。スコアが同じ場合、それらはメンバー オブジェクトのサイズに従って並べ替えられます。

  5. 整数セット intset: 整数値を保存するために使用されるコレクション抽象データ構造。重複する要素はありません。基礎となる実装は配列です。

  6. 圧縮リスト ziplist: 圧縮リストは、メモリを節約するために開発されたシーケンシャル データ構造です。複数のノードを含めることができ、各ノードはバイト配列または整数値を保存できます。

これらの基本的なデータ構造に基づいて、redis は、文字列オブジェクト string、リスト オブジェクト リスト、ハッシュ オブジェクト ハッシュ、コレクション オブジェクト セット、および順序付けされたコレクション オブジェクト zset などの独自のオブジェクト システムをカプセル化します。 object は少なくとも 1 つの基本データ構造を使用します。

redis は、柔軟性と効率を向上させるために、エンコーディング属性を通じてオブジェクトのエンコーディング形式を設定します。Redis は、さまざまなシナリオに基づいて自動的に最適化を行います。さまざまなオブジェクトのエンコードは次のとおりです。

  1. String オブジェクト文字列: int 整数、embstr エンコードされた単純な動的文字列、生の単純な動的文字列

  1. #リスト オブジェクト リスト: ziplist、linkedlist

  1. ハッシュ オブジェクト ハッシュ: ziplist、hashtable

  1. Set オブジェクト セット: intset、hashtable

  1. 順序付けされたコレクション オブジェクト zset: ziplist、skiplist

なぜ Redis は速いのですか?

redis は非常に高速です。1 つの redis で 1 秒あたり数万の同時実行をサポートできます。mysql と比較すると、パフォーマンスは mysql の数十倍です。速度が速い主な理由は次のとおりです。

  1. メモリ操作に完全に基づいている

  2. C 言語の実装、最適化されたデータ構造、いくつかの基本的なデータ構造、Redis は多くの最適化を行っており、パフォーマンスは非常に高くなります。

  3. 単一スレッドを使用し、コンテキスト切り替えコストは不要です。

  4. 非ブロック IO 多重化メカニズムに基づく

では、なぜ Redis は Redis6.0 以降マルチスレッドに切り替えたのですか?

redis のマルチスレッドの使用シングル スレッドを完全に放棄する必要がありますか? Redis は依然としてシングル スレッド モデルを使用してクライアント リクエストを処理します。データの読み書きとプロトコル解析を処理するためにのみマルチ スレッドを使用します。コマンドの実行には引き続きシングル スレッドを使用します。

この目的は、redis のパフォーマンスのボトルネックが CPU ではなくネットワーク IO にあるためです。マルチスレッドを使用すると、IO の読み取りと書き込みの効率が向上し、それによって Redis の全体的なパフォーマンスが向上します。

ホットキーとは何か知っていますか?ホットキーの問題を解決するにはどうすればよいですか?

いわゆるホットキー問題とは、redis 上の特定のキーにアクセスするリクエストが突然何十万件も発生し、トラフィックが集中しすぎて、制限の上限に達するというものです。物理ネットワーク カードが原因でサーバーの Redis がクラッシュし、雪崩が発生します。

ホット キーの解決策:

  1. プレッシャーを軽減するために、事前にホット キーを別のサーバーに分散します。

  2. 2次キャッシュを使用し、事前にホットキーデータをメモリにロードします。Redisがダウンしている場合は、メモリクエリ

    を使用します。

キャッシュ ブレークダウン、キャッシュ ペネトレーション、キャッシュ アバランシェとは何ですか?

キャッシュ ブレークダウン

キャッシュ ブレークダウンの概念は、単一キーの同時アクセスが多すぎるということです。有効期限が切れると、すべてのリクエストがデータベースに直接送信されます。これはホット キーの問題に似ていますが、重要なのは、有効期限が切れるとすべてのリクエストが DB にヒットするということです。

解決策:

  1. ロックして更新します。たとえば、A のクエリをリクエストして、それがキャッシュにないことが判明した場合、キー A をロックし、同時にキー A をロックします。次に、データベースにアクセスしてデータをクエリして書き込み、キャッシュしてからユーザーに返し、後続のリクエストでキャッシュからデータを取得できるようにします。

  2. この現象を防ぐには、有効期限の組み合わせを値に書き込み、非同期で有効期限を継続的に更新してください。

キャッシュ ペネトレーション

キャッシュ ペネトレーションとは、キャッシュに存在しないデータをクエリすることを意味し、各リクエストはキャッシュが存在しないかのように DB にヒットします。

この問題に対処するには、ブルーム フィルターのレイヤーを追加します。ブルーム フィルターの操作手順は、ハッシュ関数を通じてデータをビット配列内の K 点にマッピングし、データを保存するためにこれらの点を 1 に設定することです。

このように、ユーザーが A を再度クエリし、A のブルーム フィルター値が 0 である場合、それが直接返され、ブレークダウン リクエストは生成されず、DB にヒットすることはありません。

ブルームフィルターを使用した後に問題となるのは、当然のことですが、配列そのものであるため、同じ位置に複数の値が入る可能性があります。配列の長さが長ければ誤判定の可能性は低くなりますが、このような問題は実情に応じて対応する必要があります。

キャッシュ雪崩

ある瞬間に大規模なキャッシュ障害が発生すると、キャッシュサービスがダウンするなど、大量のリクエストが流入してDBを直撃します。システム全体の崩壊につながる可能性のあるものを雪崩と呼びます。ブレークダウンやホット キーの問題とは異なり、アバランシェ問題は、大規模なキャッシュが同時に期限切れになることを指します。

雪崩に対するいくつかの解決策:

  1. 同時有効期限切れを避けるために、異なるキーに異なる有効期限時間を設定します

  2. ストリーム (Redis の場合)がダウンしている場合は、ストリームを制限して、同時に多数のリクエストによる DB のクラッシュを避けることができます。

  3. 2 次レベル キャッシュ、同じホット キー ソリューション。

#Redis の有効期限戦略とは何ですか?

redis には主に 2 つの期限切れ削除戦略があります。

遅延削除

遅延削除とは、キーがクエリされた場合にのみ検出され、有効期限が切れた場合にのみキーが検出されることを意味します。それは削除です。これらの期限切れのキーにアクセスしていない場合、明らかな欠点は、キーが常にメモリを占有し、削除できないことです。

定期的な削除

Redis における定期的な削除とは、指定されたときにデータベース内のキーと値のペアを確認し、期限切れになったキーと値のペアを削除することです。 Redis は削除操作時にすべてのキーに対してポーリングを実行できないため、チェックと削除のためにいくつかのキーがランダムに選択されます。

期限切れのキーが定期的かつ遅延的に削除されない場合はどうすればよいですか?

Redis がキーを定期的にランダムにクエリするたびにキーを削除せず、これらのキーがクエリされないと仮定すると、これらのキーは Redis に保存され、削除できなくなります。 redis のメモリ削除機構に消えます。

  1. volatile-lru: 有効期限が設定されたキーから、最も最近使用されていないキーを削除して削除します。

  2. volatile-ttl: From From From From有効期限が設定されたキー、有効期限が近づいているキーを削除します

  3. #volatile-random: 有効期限が設定されたキーからランダムにキーを選択して削除します

  4. allkeys-lru: 削除対象のキーから最も最近使用されていないキーを選択します

  5. allkeys-random: 削除対象のキーからランダムにキーを選択します

  6. noeviction: メモリがしきい値に達すると、新しい書き込み操作に対してエラーが報告されます。

永続化メソッドとは何ですか?違いは何ですか?

Redis 永続化ソリューションは、RDB と AOF の 2 つのタイプに分類されます。

RDB

RDB 永続化は、設定に応じて手動または定期的に実行でき、ある時点のデータベースの状態を RDB ファイルに保存する機能です。圧縮 特定の時点でのデータベースの状態を復元できるバイナリ ファイル。 RDBファイルはハードディスク上に保存されるため、redisがクラッシュしたり終了したりしても、RDBファイルが存在していればデータベースの状態を復元することができます。

RDB ファイルは、SAVE または BGSAVE を通じて生成できます。

SAVE コマンドは、RDB ファイルが生成されるまで redis プロセスをブロックします。プロセスのブロック期間中、redis はコマンド リクエストを処理できません。これは明らかに不適切です。

BGSAVE は子プロセスをフォークアウトし、その子プロセスが RDB ファイルの生成を担当します。親プロセスはプロセスをブロックすることなくコマンド リクエストの処理を続行できます。

AOF

AOF は RDB とは異なり、redis サーバーによって実行された書き込みコマンドを保存することでデータベースの状態を記録します。

AOF は、追加、書き込み、同期の 3 つのステップを通じて永続化メカニズムを実装します。

  1. AOF 永続性がアクティブ化されると、サーバーが書き込みコマンドを実行した後、書き込みコマンドが aof_buf バッファーの末尾に追加されます。
  2. サーバーで各イベント ループが終了する前に、flushAppendOnlyFile 関数が呼び出され、aof_buf の内容を AOF ファイルに保存するかどうかが決定されます。これは、appendfsync を構成することで決定できます。

always ##aof_buf内容写入并同步到AOF文件
everysec ##将aof_buf中内容写入到AOF文件,如果上次同步AOF文件时间距离现在超过1秒,则再次对AOF文件进行同步
no ##将aof_buf内容写入AOF文件,但是并不对AOF文件进行同步,同步时间由操作系统决定
ログイン後にコピー

設定しない場合、デフォルトのオプションは毎秒になります。常には最も安全ですが (イベント ループ書き込みコマンドが 1 つだけ失われます)、パフォーマンスが低下し、毎秒になります。モードでは 1 秒間のデータしか失われませんが、いいえモードの効率は 1 秒ごとと同様ですが、AOF ファイルの最後の同期以降の書き込みコマンド データはすべて失われます。

Redis の高可用性を実現するにはどうすればよいですか?

高可用性を実現するには、1 台のマシンだけでは決して十分ではありません。高可用性を確保するために、redis には 2 つのオプションがあります。

マスター/スレーブ アーキテクチャ

マスター/スレーブ モードは、高可用性を実現するための最も単純なソリューションであり、中核となるのはマスター/スレーブの同期です。マスターとスレーブの同期の原理は次のとおりです。

  1. スレーブはマスターに同期コマンドを送信します。

  2. マスターが同期を受信した後、 bgsave が実行され、完全な RDB ファイルが生成されます。

  3. マスターはスレーブの書き込みコマンドをキャッシュに記録します

  4. bgsave が実行された後、マスターはスレーブの書き込みコマンドをキャッシュに記録します。 RDB ファイルをスレーブに送信し、スレーブはそれを実行します

  5. マスターはキャッシュ内の書き込みコマンドをスレーブに送信し、スレーブはそれを実行します

#ここで書いたコマンドは sync ですが、redis2.8 以降では sync の代わりに psync が使用されるようになりましたが、これは sync コマンドがシステムリソースを消費するため、psync の方が効率的であるためです。

Sentinel

マスター/スレーブ方式の欠点は依然として明らかです。マスターがダウンするとデータを書き込むことができなくなり、スレーブはその機能を失い、アーキテクチャ全体が機能しなくなります。手動で切り替えない限り、主な理由は自動フェイルオーバー メカニズムがないことです。 Sentinel の機能は、単純なマスター/スレーブ アーキテクチャよりもはるかに包括的であり、自動フェイルオーバー、クラスター監視、メッセージ通知などの機能を備えています。

Sentry は複数のマスター/スレーブ サーバーを同時に監視でき、監視対象のマスターがオフラインになると、自動的にスレーブをマスターに昇格させ、その後新しいマスターが引き続きコマンドを受信します。プロセス全体は次のとおりです。

  1. #センチネルを初期化し、通常の Redis コードをセンチネル固有のコードに置き換えます

  2. マスター ディクショナリとサーバー情報を初期化します。サーバー情報 主に ip:port を保存し、インスタンスのアドレスと ID を記録します。

  3. マスターとの 2 つの接続 (コマンド接続とサブスクリプション接続) を作成し、センチネルにサブスクライブします。 hello channel

  4. info コマンドを 10 秒ごとにマスターに送信して、マスターとその下のすべてのスレーブの現在の情報を取得します。

  5. いつマスターに新しいスレーブ、センチネルがあることがわかります。新しいスレーブも 2 つの接続を確立し、10 秒ごとに info コマンドを送信してマスター情報を更新します。

  6. センチネルは ping を送信します。コマンドをすべてのサーバーに 1 秒ごとに送信します。サーバーが設定された応答時間内に無効な応答を返し続ける場合、オフラインとしてマークされます。

  7. 主要な監視者を選出します。これには、複数の人の同意が必要です。センチネルの半分

  8. 先頭のセンチネルはオフライン マスターのスレーブの 1 つを選択し、それをマスターに変換します

  9. #すべてのスレーブにコピーを許可します新しいマスターからのデータ

  10. 元のマスターを新しいマスターのスレーブ サーバーとして設定します。元のマスターが接続を再開すると、新しいマスターのスレーブ サーバーになります

Sentinel は、すべてのインスタンス (マスター/スレーブ サーバーや他のセンチネルを含む) に 1 秒ごとに ping コマンドを送信し、その応答に基づいてオフラインかどうかを判断します。この方法は主観的オフラインと呼ばれます。主観的にオフラインであると判断された場合は、他の監視監視員に質問し、投票の半数以上がオフラインであると判断した場合、客観的にオフラインとしてマークされ、フェイルオーバーがトリガーされます。

Redis クラスターの原理について話してもらえますか?

センチネルを利用して Redis の高可用性を実現できる場合、および大量のデータに対応しながら高い同時実行性をサポートしたい場合は、Redis クラスターが必要です。 Redis クラスターは、redis が提供する分散データ ストレージ ソリューションであり、データ シャーディングを通じてデータを共有し、レプリケーションおよびフェイルオーバー機能を提供します。

ノード

Redis クラスターは複数のノードで構成されており、複数のノードはクラスターミートコマンドを介して接続されます。ノードのハンドシェイクプロセス:

  1. ノード A はクライアントからクラスターのミート コマンドを受信します

  2. #A は受信した IP アドレスとポート番号に基づいて B にミート メッセージを送信します
  3. #ノード B が会議メッセージを受信し、pong を返します
  4. #A は、B が会議メッセージを受信したことを認識し、ping メッセージを返し、ハンドシェイクが成功します

  5. 最後に、ノード A はゴシップ プロトコルを通じてノード B の情報をクラスタ内の他のノードに広め、他のノードも B

  6. slot

    と握手をします。
  7. redis はクラスター シャーディングの形式でデータを保存します。クラスター データベース全体は 16384 個のスロットに分割されます。クラスター内の各ノードは 0 ~ 16384 個のスロットを処理できます。データベース内の 16384 個のスロットすべてがノードによって処理されると、クラスターはそれ以外の場合は、1 つのスロットが処理されない限り、オフライン ステータスが処理されます。処理のために対応するノードにスロットを割り当てるには、clusteraddslots コマンドを使用します。

slot はビット配列で、配列の長さは 16384/8=2048 で、配列の各ビットはノードによって処理される 1 で表され、0 は処理されないことを表します。これは、ノード A が 0 ~ 7 スロットを処理することを意味します。

クライアントがノードにコマンドを送信するとき、スロットが現在のノードに属していることが判明した場合、ノードはコマンドを実行します。そうでない場合は、ガイドとして MOVED コマンドがクライアントに返されます。クライアントを正しいノードに接続します。 (MOVED プロセスは自動です)

ノードを追加または削除する場合、スロットの再割り当ても非常に便利です。Redis は、スロットの移行を実現するためのツールを提供します。プロセス全体は完全にオンラインであり、停止する必要はありませんサービス。 。

フェイルオーバー

ノード A がノード B に ping メッセージを送信し、ノード B が指定された時間内に pong に応答しない場合、ノード A はノード B を pfail の疑いのあるオフライン状態としてマークします。同時に B のステータスをメッセージの形式で他のノードに送信します。半分以上のノードが B を失敗ステータスとしてマークすると、B はオフライン失敗としてマークされます。このとき、フェイルオーバーが発生し、優先順位が高くなります。複数のスレーブ ノードからデータを複製することが与えられます マスター ノードとなる 1 つを選択し、オフライン ノードのスロットを引き継ぎます 全体のプロセスはセンチネルのプロセスと非常によく似ており、どちらも選択のための Raft プロトコルに基づいています。

Redis トランザクションのメカニズムを理解していますか?

redis は、MULTI、EXEC、WATCH などのコマンドを通じてトランザクション メカニズムを実装します。トランザクション実行プロセスは、複数のコマンドを順番に一度に実行し、実行中にトランザクションは中断されません。すべてのコマンドが実行されるまで、クライアントからの他のリクエストは実行されません。トランザクションの実行プロセスは次のとおりです。

  1. サーバーはクライアントのリクエストを受信し、クライアントが MULTI

  2. の場合、トランザクションは開始されます。トランザクション状態にある場合、トランザクションはキューに入れられ、クライアントの QUEUED に返されます。それ以外の場合、このコマンドは直接実行されます。

  3. クライアント EXEC コマンドを受信すると、 WATCH コマンドは、トランザクション全体のキーが存在するかどうかを監視します。変更されている場合は、失敗を示す空の応答がクライアントに返されます。それ以外の場合、redis はトランザクション キュー全体を走査し、キューに保存されているすべてのコマンドを実行します。最終的に結果をクライアントに返します

WATCH このメカニズム自体は CAS メカニズムです。監視されているキーはリンクされたリストに保存されます。キーが変更されると、REDIS_DIRTY_CAS フラグが設定されます。オンにすると、サーバーはトランザクションの実行を拒否します。

以上がRedis の面接の質問と回答は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:yisu.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!