ホームページ  >  記事  >  データベース  >  2023 年の Redis の高頻度面接の質問の共有 (回答分析付き)

2023 年の Redis の高頻度面接の質問の共有 (回答分析付き)

青灯夜游
青灯夜游転載
2021-10-18 10:27:284808ブラウズ

この記事では、Redis で頻繁に聞かれる面接の質問をまとめて共有します。これは、一定の参考価値があります。困っている友人は参考にしてください。皆さんのお役に立てれば幸いです。

2023 年の Redis の高頻度面接の質問の共有 (回答分析付き)

面接官の心理分析

面接官の観点から見ると、この質問の目的は、キャッシュに関するあなたの知識レベルをテストすることであり、キャッシュ機能と組み合わせることで、ビジネスを処理し、アーキテクチャを改善します。この質問は明らかにあなたが自由に自分の意見を表現することができ、面接官をあなたが最もよく知っている知識ポイントに導く機会を与えるものであるため、この機会を可能な限り捉えて面接官に良い印象を与える必要があります。この質問はうまく話せれば数時間は深くコミュニケーションできますが、1回のセッションであれば基本的には簡単に解決できます。 [関連する推奨事項: Redis ビデオ チュートリアル ]

ただし、死ぬほどチャットを始めないでください。チャットは浅すぎるため、 その後は基本的に戻って通知を待ちます。 ……


たとえば、次のような答えです。

2023 年の Redis の高頻度面接の質問の共有 (回答分析付き)

多くの人が、この答えが正しいと言うでしょう。そうです、その通りですが、与えられた機会が無駄であるという感覚が常にあります。

現時点で、面接官は次のようなことを考えています:

  • これは比較的基本的なものであり、Redis について深く理解している必要はありません
  • 問題は表面に残っていると思います。私は通常の仕事の仕方を知っていると思いますが、問題について考えたことはありません
  • あなたに表現する機会を与えます自分で自由に操作してください。理解できない場合は、まだ自分でやる必要があるようです。まず、分散と永続化についていくつか質問して、あなたのレベルがどの程度であるかを確認します。うまくいかない場合は、あなたの後ろにはたくさんの人がいます、そして彼らは後で仕事を終えるでしょう。

面接官の「十八龍討伐掌」に抵抗したくないなら、自ら率先して面接官の興味をそそり、自らのパターン(横の広さと深さ)を率先して改善すべきです。そして、あなたが知っていることについてできるだけ話してください。

たとえば、次のような回答方法:

2023 年の Redis の高頻度面接の質問の共有 (回答分析付き)

Redis の面接の質問の概要

2023 年の Redis の高頻度面接の質問の共有 (回答分析付き)

私の理解は、このインタビュアーとほぼ同じです! !

高性能: 高性能の大きな基準は、応答時間が速いことです。 Redis はメモリ ストレージをベースにしており、CPU アクセス速度が速いことに加え、データ構造、内部スレッド モデル、ネットワーク I/O モデルの設計が極端に最適化されているため、Redis は高性能のストレージ データベースです。唯一の欠点は、メモリが比較的高価であり、リソースが通常は限られていることです。したがって、非常に大きなデータのキャッシュ アーキテクチャは合理的に設計する必要があります。通常、過度に大きなデータを Redis に保存することはありません。これは、Redis のパフォーマンスが低下するためです。

高い同時実行性: 高い同時実行性の一般的な指標には、応答時間 (Response Time)、スループット (Throughput)、1 秒あたりのクエリ レート QPS (Query Per Second)、および同時ユーザー数が含まれます。 -スレッド モデルですが、Redis は同時実行性の高いビジネス シナリオでは確かに強力なツールです。現在、Redis の QPS は 100,000、さらには 100 万レベルに達する可能性があります。これは完全に同時実行性が高いです。

高可用性: Redis の高可用性は主にマスター/スレーブ レプリケーション、センチネル (センチネル モード)、およびクラスター (クラスター モード) に反映されます

2023 年の Redis の高頻度面接の質問の共有 (回答分析付き)

私の理解は大体このインタビュアーと同じです! !

Redis のシングル スレッドとは、Redis6 のリリース以降、コマンド操作を実行するために単一のスレッドを使用することを指します。

  • I/O 多重化ノンブロッキング モデルは、クライアント ソケット接続の処理に使用され、Redis サーバーの応答速度と効率を大幅に最適化できます。マルチチャネル I/O 多重化テクノロジにより、単一スレッドが可能になります。複数の接続リクエストを効率的に処理して、ネットワーク IO 時間の消費を最小限に抑えます。
  • メモリ ストレージに基づいて、ディスク IO を削減し、読み取り速度を高速化します
  • Redis は内部データ構造を究極的に最適化し、Redis データ構造を非常に効率的にしました。また、データ量や保存内容に応じて異なるエンコード方式が採用されており、これにはRedisのエンコード変換が含まれます。たとえば、list、hash、zset の 3 つのキーは、ziplist 圧縮リスト エンコーディングを使用します。ziplist はコンパクトなデータ構造です。特定のキー値に含まれる要素が少ない場合、最初に ziplist に格納されます。数値が特定の値を超えると、ziplist は標準のストレージ構造に変換されます。もちろん、この値は redis.conf でカスタマイズできます。さらに、SDS のメモリ事前割り当て、ハッシュ結果 Rehash でのプログレッシブ ハッシュ、SkipList ストレージに基づく ZSet シーケンスはすべてデータ構造を最適化し、高速化します。
  • Redis は、同時ロックの設計やマルチスレッドによる CPU コンテキスト切り替えの消費を考慮せずに、シングル スレッドを使用してコマンド操作を実行するため、コマンドの実行が高速になります

2023 年の Redis の高頻度面接の質問の共有 (回答分析付き)

私の理解は、このインタビュアーとほぼ同じです。 !

Redis には、String、List、Hash、Set、ZSet の 5 つの基本データ型があり、さらに、Bitmaps、Geospatial、および HyperLogLog という 3 つの特別なデータ型があります。

データ型 簡単な説明 使用シナリオ
文字列 String (文字列) は、Redis の最も単純で最も広く使用されているデータ構造であり、その内部は文字配列です。 String (文字列) は、変更を許可する動的文字列です。その構造的な実装は、Java の ArrayList に似ています (サイズ 10 の初期配列がデフォルトで構築されます)。これは、メモリの冗長割り当てのアイデアであり、プレとしても知られています。 - 割り当て。このアイデアにより、拡張によるパフォーマンスの消費を削減できます。文字列 (string) のサイズが拡張しきい値に達すると、文字列 (string) が拡張されます。文字列 (string) の拡張には主に 3 つの状況があります: 1. 長さが 1MB 未満で、拡張は 2 倍になります。元のサイズ; length = length * 2 2. 長さは 1MB より大きく、拡張後は 1MB ずつ増加します; length = length 1MB 3. 文字列の最大長は 512MBです キャッシュ、カウンター、分散ロック、など。
List Redis のリストは Java 言語の LinkedList に相当し、二重にリンクされたリストのデータ構造です (ただし、この構造設計はより賢明です。後で紹介します)。順次トラバーサルをサポートします。リンクされたリスト構造の挿入および削除操作は、時間計算量が O(1) で高速ですが、クエリは時間計算量が O(n) で遅くなります。 Redisのリスト(リスト)は単純なものではありません。 LinkedList ですが、クイックリスト - 「クイック リスト」、クイックリストは複数のジップリスト (圧縮リスト) で構成される双方向リストです; リンク リスト、非同期キュー、Weibo フォロワー タイムライン リスト...
Hash Redis のハッシュ (辞書) は、Java 言語の HashMap に相当します。ハッシュ値に従って分散される順序付けされていない辞書です。内部要素はキーと値のペアに基づいています。保管する。ハッシュ(ディクショナリ)の実装もJavaのHashMap(JDK1.7)の構造と一致しており、そのデータ構造も配列のリンクリストから構成される2次元構造となっており、ノード要素は配列上でハッシュ化されています。ハッシュの衝突が発生した場合は、リンク リストが使用され、配列ノードで連結されます。 Redisのハッシュ(辞書)に格納される値は文字列値のみであり、またJavaのHashMapとは展開が異なります。 Java の HashMap は容量拡張時に一度で完了しますが、Redis はコアアクセスがシングルスレッドのパフォーマンス問題であることを考慮し、高いパフォーマンスを追求するためにプログレッシブリハッシュ戦略を採用しています。プログレッシブリハッシュとは、一度ではなく複数回実行することを意味するため、古いハッシュ構造を保持する必要があるため、Redis のハッシュ (辞書) は新旧 2 つのハッシュ構造を持つことになります。すべての値が新しいハッシュに移動された後にのみ、新しいハッシュは機能内の以前のハッシュを完全に置き換えます。 ユーザー情報、ハッシュテーブル...
Set Redisの集合(セット)は、Java言語のHashSetに相当し、とその内部キー 値のペアは順序付けされておらず、一意です。すべての値が null である特殊な辞書を内部的に実装します。コレクション内の最後の要素が削除された後、データ構造は自動的に削除され、メモリが再利用されます。 重複削除機能、好き嫌い、共通の友人...
ZSet zset (順序セット) は、 Redisのデータ構造。 Java 言語の SortedSet と HashMap の組み合わせに似ており、set を使用して内部値の一意性を保証する一方で、値のスコア (重み) でソートします。この並べ替え機能は、スキップ リストによって実装されます。 zset (順序付きセット) の最後の要素値が削除された後、データ構造は自動的に削除され、メモリがリサイクルされます。 ファン リスト、生徒のパフォーマンスの並べ替え、トラフィック ランキング、クリック ランキング...
ビットマップ ビットマップはビットマップと呼ばれますが、厳密にはビットマップではありません。データ・タイプ。ビットマップの最下層は文字列 (キーと値) のバイト配列です。通常の get/set を使用してビットマップの内容を直接取得および設定することも、Redis が提供するビットマップ操作 getbit/setbit を通じてバイト配列を「ビット配列」として扱うこともできます。ビットマップの「ビット配列」の各セルは、0 と 1 のみを格納できます。配列の添え字は、ビットマップではオフセットと呼ばれます。ビットマップを設定するとき、キーが存在しない場合は新しい文字列が自動的に生成されます。設定されたオフセットが既存のコンテンツの範囲を超える場合、ビット配列は自動的にゼロ拡張されます。 従業員パンチイン...
Geospatial Geospatial は、バージョン 3.2 以降に Redis によって追加された地理的位置 GEO モジュールです。 近くの人と WeChat をして、「近くのレストラン」をオンラインで注文します"... …
HyperLogLog HyperLogLog は、カーディナリティ統計を行うために使用されるアルゴリズムです。不正確な重複排除とカウント スキームを提供します (この不正確さはそれほど不正確ではありません) , 標準誤差は 0.81% で、これは UV 統計の許容誤差範囲です。 HyperLogLog の利点は、入力要素の数または量が非常に大きい場合でも、カーディナリティ計算のための記憶領域が固定されることです。 Redis では、各 HyperLogLog キーに必要なメモリは 12KB のみで、ほぼ 2^64 の異なる基数を計算できます。ただし、HyperLogLog がカウントできるのはカーディナリティのサイズ (つまり、データ セットのサイズとセットの数) だけであり、要素自体を保存することはできず、要素自体をセット コレクションのように保存することもできません。要素を返します。 UV などの基本統計量

2023 年の Redis の高頻度面接の質問の共有 (回答分析付き)

#私の理解は、おおよそこのインタビュアーと同じです! !

Redis のデータ構造では、EXPIRE キーの秒数を通じてキーの有効期限 (TTL) を設定できます。また、私たちは Redis キーが期限切れになると自動的に削除されると考えがちですが、この考えが正しくないことは明らかです。 Redis の設計では、パフォーマンスやメモリなどの包括的な要素が考慮され、一連の有効期限戦略が設計されます。

    アクティブな削除 (遅延削除)
  • パッシブな削除 (定期的戦略)
アクティブな削除 (遅延削除) は、キーがアクセスされた時間を指します。 , まずキーの有効期限が切れているかどうかを確認し、期限切れの場合は積極的に削除します。

受動的削除 (定期的戦略) とは、Redis サーバーがキーの有効期限を定期的かつランダムにテストすることを指します。有効期限が切れた場合は、受動的に削除されます。有効期限が切れて永久にアクセスされなくなるキーがいくつかあるため、パッシブ削除の存在は不可欠ですが、アクティブな削除に依存すると、永久にメモリを占有することになります。

##高パフォーマンスのサービスを保証するために、Redis は期限切れのキーを受動的に削除し、貪欲な戦略/確率的アルゴリズムを採用しています。デフォルトでは、10 秒ごとにスキャンします。具体的な戦略は次のとおりです:

    #1. 有効期限辞書 (有効期限が設定されたキーのコレクション) からランダムに 20 個のキーを選択し、期限切れかどうかを確認します
  • ##2. 期限切れのキーを削除しますキー
  • 3. 削除された期限切れキーの数が 25% を超えている場合は、手順 1

  • #さらに、Redis キャッシュ アーキテクチャを設計する場合、開発者は料金を支払う必要があります。できるだけ避けるように注意してください (禁止) 多数のキーを同じ有効期限に設定すると、受動的削除と組み合わせると、Redis が期限切れのキーを受動的に削除すると、サービスが一時的に使用できなくなることがわかります。同時に期限切れになるキーが多数ある場合、キーの受動的な削除の 3 つのステップが発生し、複数回ループすると Redis サービスがフリーズしますが、これは大規模なトラフィックのプロジェクトでは受け入れられません。
したがって、この状況を回避するには、許容有効期限がそれほど正確である必要がない一部のキーは、よりランダムな有効期限に設定して、遅延時間を短縮する必要があります。

2023 年の Redis の高頻度面接の質問の共有 (回答分析付き)#私の理解は、おおよそこのインタビュアーと同じです! !

分散シナリオでは、一般的な分散ロック ソリューションには次のものが含まれます (方法を知っている場合は、ここで他の 2 つのタイプを使用できますが、知らない場合でも失敗しないでください) ! ):

データベース ロック メカニズムに基づいて実装された分散ロック
  • Zookeeper に基づいて実装された分散ロック## Redis 実装に基づく分散ロック
  • Redis が分散ロックを実装するためのソリューションは次のとおりです。

  • Redis がスタンドアロン環境にある場合、
  • Redis が提供するアトミック命令を通じて分散ロックを実装できます。

set key value [EX 秒] [PX ミリ秒] ] [NX | ロック解除は許可されていますが、Redis にはそのような機能はありません。Lua スクリプトは複数の命令をアトミックに実行できるため、Lua スクリプトを介してのみ処理できます。最後に、ロック タイムアウトの問題を考慮する必要があります。クライアントがロックを解放しないと、間違いなく機能しません。したがって、ロックは、指定されたタイムアウト時間の範囲内に他のクライアントによってロックが解除されないことを保証することしかできません。タイムアウト後に自動的に解放される このような状況は難しいですが、次のように最適化できます:

Redis 分散ロック内で長いタスクを実行しないようにして、コードを実行します単一の JVM ロックと同じように、できるだけロック間隔内でロック範囲を最適化することを検討できます。

実環境のストレス テストとオンライン シミュレーション テストをさらに実行します。適切なロック タイムアウト時間を見積もるためのシナリオ

  • Redis 分散ロック タイムアウト タスクが完了しない問題が発生した後のデータ回復方法を準備してください

  • そうである場合分散環境では、

    が増加します。 Sentinel の 1 マスターと複数のスレーブ環境などの新たな問題は、クライアントがマスター ノードのロックを申請するものの、同期が完了せず、マスター ノードがロックされてしまう可能性があります。現時点では、新しく選択されたマスター ノードのロックは無効です。

  • この状況への対応はこのように考えるべきですが、まず第一に、Redis のマスターとスレーブの直接同期では、いかなる場合でもデータ損失の問題を解決できません。そこで、ロック アプリケーションを 1 つの Redis から複数のスタンドアロン Redis ロック アプリケーションに変更することを検討します。ほとんどのアプリケーションのみが成功します。このアイデアがレッドロックです。
  • RedLock は複数の Redis インスタンスを使用します。各インスタンス間にマスター/スレーブ関係はなく、相互に独立しています。ロックする場合、クライアントはすべてのノードにロック指示を送信します。ノードの半分以上が停止している場合、クライアントはロック命令をすべてのノードに送信します。正常に設定され、正常にロックされました。ロックを解除する場合は、全ノードにdel命令を送信してロックを解除する必要があります。

レッドロックはマスターとスレーブの同期の問題を解決しますが、新たな複雑な問題を引き起こします:

  • 最初の問題はクロック ドリフトです。
  • 2 つ目の問題は、クライアントが異なる Redis サーバーから異なる時間にロックを正常に適用することです。

したがって、RedLock では、要求されたロックの最小有効期間を計算する必要があります。クライアントがロックの申請に成功し、最初のキーが正常に設定された時刻が TF、最後のキーが正常に設定された時刻が TL、ロックのタイムアウトが TTL、異なるプロセス間のクロックの差が CLOCK_DIFF であると仮定します。ロックの最小有効期間は次のとおりです:

TIME = TTL - (TF- TL) - CLOCK_DIFF

Redis を使用して分散ロックを実装すると、分離できなくなります。サーバーのダウンタイムやその他の可用性の問題から、RedLock についても同様です。複数のサーバーがロックを申請した場合でも、サーバーがダウンした後の処理も考慮する必要があります。公式は AOF 永続化処理を使用することを推奨しています。

ただし、AOF 永続性は、通常の SHUTDOWN 命令でのみ再起動および復元できます。ただし、停電が発生した場合、最後の永続性から停電までのロック データが失われる可能性があります。サーバーが再起動すると、分散ロックのセマンティック エラーが発生する可能性があります。したがって、この状況を回避するために、Redis サービスの再起動後、最大クライアント TTL 以内に Redis サービスを利用できなくなる (ロック アプリケーション サービスは提供されない) ことが公式に推奨されています。これにより問題は確かに解決できますが、これが Redis サーバーのパフォーマンスに確実に影響を与えることは明らかであり、これがほとんどのノードで発生すると、システムは全体的に使用できなくなります。

2023 年の Redis の高頻度面接の質問の共有 (回答分析付き)

#私の理解は、おおよそこのインタビュアーと同じです! !

Redis は非常に高速です。その主な理由は、Redis データがメモリに保存されることです。データはメモリ内にあるため、サーバーがダウンするか電源がオフになると、データはすべてが失われるため、Redis には障害によってすべての Redis データが失われないようにするための 2 つのメカニズムが用意されており、このメカニズムは Redis の永続化メカニズムと呼ばれます。

Redis には 2 つの永続化メカニズムがあります:

  • RDB (Redis Database) メモリ スナップショット
  • AOF (Append Only File) 増分ログ

#RDB(Redis DataBase) は、指定された時間間隔内にメモリ内のデータ セットのスナップショットをディスクに書き込むことを指します。RDB はメモリ スナップショット (メモリ データのバイナリ シーケンス) です。永続化の形式)、Redis からスナップショットが生成されるたびに、データを完全にバックアップします。

#利点:

#コンパクトなストレージ、メモリ領域の節約

    回復速度が非常に速い
  • 完全バックアップおよび完全レプリケーションのシナリオに適しており、災害復旧 (データの整合性と一貫性の要件が比較的低い場合) によく使用されます。
  • #欠点:

データは失われやすく、2 つのスナップショットの間に Redis サーバーで変更されたデータも失われやすくなります。

RDB はフォーク サブプロセスを使用してメモリ スナップショットを完全にバックアップします。これは重量のある操作であり、頻繁に実行するとコストがかかります。
  • 子プロセスをフォークすると、メモリは共有されますが、バックアップ中にメモリが変更されると、最大 2 倍のサイズに拡張される可能性があります。
    RDB トリガー ルールは、手動トリガーと自動トリガーの 2 つのカテゴリに分類されます。
  • 自動トリガー:

設定トリガー ルール

  • シャットダウン トリガー

  • フラッシュ トリガー

  • 手動トリガー:

保存

  • bgsave

  • AOF(Append Only File)
  • は、メモリを変更するすべての命令 (書き込み操作) を保存します。データは独立したログ ファイルに記録され、再起動時に AOF ファイル内の Redis コマンドを実行することでデータが復元されます。 AOF はデータ永続化のリアルタイム問題を解決でき、現在の Redis 永続化メカニズムにおける主流の永続化ソリューションです (4.0 以降のハイブリッド永続化については後ほど説明します)。

#利点:

データのバックアップがより完全になり、データ損失の可能性が低くなり、高いデータ整合性が必要なシナリオに適していますログ ファイルは読み取り可能であり、AOF は操作性が高く、ログ ファイルを操作することで修復できます

  • 欠点:

AOF ログ長期間運用すると徐々にサイズが大きくなり、リストアに非常に時間がかかります。AOF ログは定期的にスリム化する必要があります (詳細は後述)リストア バックアップ速度が比較的遅い

  • 同期書き込み頻繁な操作によりパフォーマンスが圧迫される
AOF ログはファイルの形式で存在します。プログラムが AOF ログ ファイルに書き込むとき、実際の内容はカーネルによって割り当てられたファイル記述子に書き込まれ、メモリ バッファでは、カーネルはバッファ内のデータを非同期的にディスクにフラッシュします。バッファ内のデータがディスクにフラッシュされる前にサーバーがクラッシュすると、データは失われます。
  • したがって、Redis は、Linux オペレーティング システムの glibc によって提供される fsync(int fid) を呼び出して、指定されたファイルの内容をカーネル バッファからディスクに強制的に戻し、バッファ内のデータが消去されないようにします。失った。ただし、これは IO 操作であり、Redis のパフォーマンスに比べて非常に遅いため、頻繁に実行することはできません。
Redis 構成ファイルにはバッファーを更新するための 3 つの構成があります:

appendfsync always

すべての Redis 書き込み操作は AOF ログに書き込まれます。Redis の同時実行数が、たとえ Redis が比較的少ない場合でも、Linux オペレーティング システムが提供する最大更新頻度をはるかに超えているため、理論上、Linux オペレーティング システムはこの構成を処理できません。この場合、この構成には IO 操作が含まれるため、パフォーマンスが非常に重視されるため、この構成は基本的に 1 秒に 1 回更新されません。バッファ内のデータは AOF ファイルに転送されます。この構成のデフォルトの戦略は、 Redis 構成ファイルは、パフォーマンスとデータの整合性の間の妥協と互換性があります。この構成では、理論的には、データは約 1 秒で失われます。

appendfsync no

Redis プロセスは、バッファー内のデータを AOF ファイルに積極的に更新せず、オペレーティング システムの判断に直接任せます。この操作はお勧めできません。データが失われる可能性が非常に高くなります。

以前に AOF の欠点について述べたとき、AOF は Redis 書き込み命令を保存するためのログ追加形式であると述べましたが、これにより、多数の冗長な命令ストレージが発生し、AOF ログ ファイルが非常に大きくなりますこの場合、メモリを占有するだけでなく、回復が非常に遅くなる原因となるため、Redis はこの問題を解決するための書き換えメカニズムを提供します。 Redis の AOF 永続化メカニズムが再書き込みを実行した後、データを復元するための最小限の命令セットのみが保存されます。手動でトリガーしたい場合は、次の手順を使用できます。

bgrewriteaof
Redis 4.0 以降の再書き込みでは、RDB スナップショットが使用され、 AOF 命令の結合方法により、AOF ファイルの先頭は RDB スナップショットのデータのバイナリ形式であり、末尾はスナップショットの生成後に発生した書き込み操作の命令です。

AOF ファイルの書き換えは Redis のパフォーマンスに一定の影響を与えるため、気軽に自動書き換えを行うことはできません。Redis には自動 AOF 書き換え用の 2 つの構成インジケーターが用意されています。これら 2 つのインジケーターが満たされた場合にのみ書き換えが行われます。同時に:

#auto-aof-rewrite-percentage 100: ファイルのメモリが元のメモリの 2 倍に達したときを指します

auto-aof- rewrite-min-size 64mb: ファイル再書き込みの最小メモリ サイズを指します

さらに、Redis 4.0 以降のほとんどの使用シナリオでは、永続化メカニズムとして RDB または AOF を単独で使用しませんが、次のことを考慮に入れてください。両方の利点を活かして組み合わせて使用​​してください。

最後に、この2つをまとめると、どちらが優れているのでしょうか?

両方を有効にすることをお勧めします。

データに敏感でない場合は、RDB のみを使用することもできます。

    AOF を単独で使用することは推奨されません。バグが発生する可能性があるためです。
  • 純粋なメモリ キャッシュを行うだけの場合は、行う必要はありません。
  • 私の理解は大体このインタビュアーのような感じです! !

Redis は、メモリ ストレージに基づいたキーと値のデータベースです。メモリは高速ですが、スペースが小さいことがわかっています。物理メモリが上限に達すると、システムの実行が非常に遅くなります。 , そこで、Redis の最大メモリを設定します。Redis メモリが設定されたしきい値に達すると、メモリのリサイクルがトリガーされます。Redis は多くのメモリ削除戦略を提供します: 2023 年の Redis の高頻度面接の質問の共有 (回答分析付き)

noeviction: メモリ制限に達したため、クライアントが試行します。 より多くのメモリが使用される可能性があるコマンドを実行すると、エラーが返されます。簡単に言えば、読み取り操作は引き続き許可されますが、新しいデータの書き込みは許可されません。

del (delete ) リクエストは

できます。

  • allkeys-lru: すべてのキーから、lru (最も最近使用されていない - 最も最近使用されていない) アルゴリズムを通じてそれらを削除します
  • allkeys-random: すべてのキーからすべてのキーをランダムに削除します
volatile-lru:
    有効期限が設定されているすべてのキーから、lru (最も最近使用されていない使用法 - 最も最近使用されていない使用法) を使用します。削除のためのアルゴリズム。有効期限がなく、永続化する必要があるデータが削除対象として選択されないようにします。
  • volatile-random: が設定されます。 from 有効期限が設定されているすべてのキーの中から、キーの残り有効期限 TTL の値を比較することにより、有効期限が設定されているすべてのキーからランダムに削除されます
volatile-ttl:
    、TTL が小さいほど、早く削除されます
  • volatile-lfu: 有効期限のあるキーには LFU 削除アルゴリズムを使用します
allkeys-lfu:
    すべてのキーに対して LFU 削除アルゴリズムを使用する
  • これらの戦略のうち、重要なアルゴリズムが 2 つあり、1 つは LRU で、最も最近使用されていないキーを削除します。ただし、Redis は近似 LRU アルゴリズムを使用します。これは、最近使用頻度が最も低いキーを削除する点で完全に正確ではありませんが、全体的な精度は保証できます。
  • 近似 LRU アルゴリズムは非常に単純です。Redis キー オブジェクトには、最新のアクセスのシステム タイムスタンプを保存するために 24 ビットが追加されます。クライアントがキー書き込み関連のリクエストを Redis サーバーに送信すると、メモリが見つかりました。maxmemory に達すると、遅延削除がトリガーされます。Redis サービスは、ランダム サンプリングを通じて条件を満たす 5 つのキーを選択します (このランダム サンプリング allkeys-lru はすべてのキーからランダムにサンプリングされることに注意してください。 ##volatile-lru
  • は、有効期限が設定されたすべてのキーからランダムにサンプリングされ、キー オブジェクトに記録されている最新のアクセス タイムスタンプと比較され、メモリに空きがある場合、5 つのキーのうち最も古いキーが削除されます。まだ十分ではない場合は、続行 この手順を繰り返します。

Redis 3.0 で maxmemory_samples が 10 に設定されている場合、Redis の近似 LRU アルゴリズムは実際の LRU アルゴリズムに非常に近くなりますが、明らかに maxmemory_samples を 10 に設定すると、各サンプルがサンプルとして使用されるため、maxmemory_samples を 5 に設定するよりも多くの CPU 計算時間が消費されます。データが増加すると、計算時間も増加します。

Redis3.0 では maxmemory_samples と同じサイズのエリミネーション プールが追加されるため、Redis3.0 の LRU アルゴリズムは Redis2.8 の LRU アルゴリズムよりも正確です。最初に削除プールで削除を待っているキーと比較され、最後に最も古いキーが削除されます。実際には、削除対象に選択されたキーをまとめて比較し、最も古いキーが削除されます。

LRU には明らかな欠点があります。キーの人気を正確に表すことができません。キーがアクセスされたことがない場合、メモリの削除が発生する直前にユーザーによってアクセスされただけです。LRU アルゴリズムでは、これはホットキーとみなされます。 LFU (Least Frequently Used) は、Redis 4.0 で導入された除外アルゴリズムで、キーのアクセス頻度を比較してキーを除外します。

LRU と LFU の違い:

  • LRU -> 最近使用、最新のアクセス時間に基づいて比較
  • LFU -> ; 頻繁に使用される、キー アクセス頻度の比較に基づく

LFU モードでは、Redis オブジェクト ヘッダーの 24 ビット lru フィールドが 2 つのセグメントに分割され、上位 16 ビットが格納されます。 - ldt (最終減分時間) と下位 8 ビットの logc (ロジスティック カウンター) を保存するビット。上位 16 ビットは、カウンタが最後に減少した時刻を記録するために使用されます。8 ビットしかないため、 は Unix の分のタイムスタンプを 2^16 で割って格納します。16 ビットで表現できる最大値は 65535 (65535) /24/60≒45.5)、約45.5日で戻ります(戻るとはモジュロ値が再び0から始まることを意味します)。

下位 8 ビットは、アクセス頻度の記録に使用されます。8 ビットが表すことができる最大値は 255 です。Logc は、実際の Rediskey アクセス数を記録することはできません。実際、名前からわかるように、アクセス数の対数を格納します。新しく追加された各キーの logc の初期値は 5 (LFU_INITI_VAL) であり、新しく追加された値が最初に選択されて削除されることはなく、logc が更新されます。キーにアクセスするたびに、さらに logc は時間の経過とともに減衰します。

ロジスティック カウンターは増加するだけでなく、減衰することもあります。増加と減衰のルールは、redis.conf を通じて構成することもできます。

  • lfu-log-factor は、ロジスティック カウンターの成長速度を調整するために使用され、lfu-log-factor の値が大きいほど、ロジスティック カウンターの成長速度が遅くなります。
  • lfu-decay-time は、ロジスティック カウンターの減衰速度を調整するために使用されます。分単位の値です。デフォルト値は 1 です。lfu-decay-time 値が大きいほど、減衰が遅くなります。

2023 年の Redis の高頻度面接の質問の共有 (回答分析付き)

#私の理解は、おおよそこのインタビュアーと同じです! !

キャッシュの内訳:

これは、非常に頻繁にアクセスされるホットスポット キーが集中型の同時アクセス状況にあることを意味します。このキーが無効な場合瞬間、多数のリクエストがキャッシュに侵入し、データベースを直接リクエストし、Redis を直接通過しました。

解決策:

    キャッシュされたデータが比較的固定されている場合は、ホットスポット データを期限切れにしないように設定してみてください。
  • キャッシュされたデータが頻繁に更新されず、キャッシュ更新プロセス全体にかかる時間が短い場合は、Redis や Zookeeper などの分散ミドルウェアに基づく分散ミューテックス ロック、またはローカル相互排他ロックを使用できます。少数のリクエストのみがデータベースをリクエストしてキャッシュを再構築できるようにし、残りのスレッドはロックが解放された後に新しいキャッシュにアクセスできるようにします。
    キャッシュされたデータが頻繁に更新される場合、またはキャッシュの更新プロセスに時間がかかる場合は、タイミング スレッドを使用してキャッシュをアクティブに再構築するか、キャッシュの有効期限が切れる前にキャッシュを遅らせることができます。すべてのリクエストが対応するキャッシュに常にアクセスできるようにするための時間。

キャッシュ侵入:

は、要求されているキャッシュまたはデータベースに存在しないデータを指します。この状況は通常、ハッカーによって引き起こされます。適切に防御しないと、リクエストによってデータベースが簡単に強制終了される可能性があります。たとえば、ハッカーが負の ID を使用してテーブルの 1 つをクエリした場合、通常、ID は負の数値に設定されません。

解決策:

    データベースがクエリされない場合は、キャッシュに null 値を設定します。
  • この方法では、異なる値を使用する問題は解決できません。ネガティブな ID 要求された状況。
  • ブルーム フィルタを使用して、データベース内のすべてのデータをブルーム フィルタにマッピングします。リクエストを行う前に、ブルーム フィルタを使用して、ブルーム フィルタが存在するかどうかを確認します。存在しない場合は、それを返します。直接。

キャッシュなだれ:

キャッシュなだれは、多数のキャッシュが同時に失敗すると発生し、データベースが即座にクラッシュします。 (同時実行性が高いシナリオ) この場合、キャッシュが復元されないと、データベースは役に立たず、クラッシュし続けます。 #########解決: ######
  • キャッシュ アーキテクチャの設計: 高可用性 Redis、マスター/スレーブ センチネル、Redis クラスター クラスターを設計します
  • プロジェクト サーバー: ローカル キャッシュとサービス低下処理を使用して、MySQL へのリクエストを最小限に抑えます
  • 運用とメンテナンスの方法: Redis クラスターを定期的に監視し、永続的なバックアップ メカニズムを作成し、雪崩が発生した場合にはキャッシュされたデータをタイムリーに復元します。

12023 年の Redis の高頻度面接の質問の共有 (回答分析付き)

この時点で、面接官の顔には長い間忘れていた笑顔が浮かんでいましたが、このコツさえつかめば、この面接は成功するはずです。

もちろん、この知識ポイントは数文で明確に説明することはできません。そのため、この記事を読んで簡単に理解できるようにすることをお勧めします。

Redis Distributed—— Completeマスター/スレーブ レプリケーション、Sentinel、およびクラスタリング>>

この記事は、https://juejin.cn/post/7019088999792934926

から転載されました。著者: Li Ziba

プログラミング関連の知識については、プログラミング入門をご覧ください。 !

以上が2023 年の Redis の高頻度面接の質問の共有 (回答分析付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.cnで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。