文字列: Redis は C 言語の従来の文字列表現を直接使用しませんが、単純な動的文字列と呼ばれる独自の SDS 抽象型を実装します。 。 C 言語の文字列は独自の長さ情報を記録しませんが、SDS は長さ情報を保存するため、文字列の長さを O(N) から O(1) に取得する時間が短縮され、バッファ オーバーフローを回避し、変更の必要性が減ります。文字列の長さに必要なメモリの再割り当ての数。
リンク リスト linkedlist: Redis リンク リストは双方向の非循環リンク リスト構造です。多くのパブリッシュとサブスクライブ、スロー クエリ、監視機能はリンク リストを使用して実装されます。各リンク リストノードは listNode 構造で表され、各ノードは前ノードと後続ノードへのポインタを持ち、同時にヘッダノードの前ノードと後続ノードは NULL を指します。
辞書ハッシュテーブル: キーと値のペアを保存するために使用される抽象データ構造。 Redis は基盤となる実装としてハッシュ テーブルを使用します。各ディクショナリには日常使用と再ハッシュ用に 2 つのハッシュ テーブルがあります。ハッシュ テーブルはチェーン アドレス メソッドを使用してキーの競合を解決し、同じインデックス位置にある複数のキーと値のペアに割り当てられます。ハッシュ テーブルが拡張または縮小される場合、サービスの可用性を考慮して、再ハッシュ プロセスは一度に完了せず、徐々に完了します。
スキップ リスト Skiplist: スキップ リストは、順序付きセットの基礎となる実装の 1 つです。スキップ テーブルは、順序付きセットのキーとクラスター ノードの内部構造を実装するために Redis で使用されます。 Redis スキップ テーブルは zskiplist と zskiplistNode で構成されます。zskiplist はスキップ テーブル情報 (ヘッダー、末尾ノード、長さなど) を保存するために使用されます。zskiplistNode はテーブル スキップ ノードを表すために使用されます。各スキップ テーブルのレイヤーの高さは 1 からランダムです。番号。同じジャンプ テーブル内で、複数のノードに同じスコアを含めることができますが、各ノードのメンバー オブジェクトは一意である必要があります。ノードはスコアのサイズに従って並べ替えられます。スコアが同じ場合、それらはメンバー オブジェクトのサイズに従って並べ替えられます。
整数セット intset: 整数値を保存するために使用されるコレクション抽象データ構造。重複する要素はありません。基礎となる実装は配列です。
圧縮リスト ziplist: 圧縮リストは、メモリを節約するために開発されたシーケンシャル データ構造です。複数のノードを含めることができ、各ノードはバイト配列または整数値を保存できます。
これらの基本的なデータ構造に基づいて、redis は、文字列オブジェクト string、リスト オブジェクト リスト、ハッシュ オブジェクト ハッシュ、コレクション オブジェクト セット、および順序付けされたコレクション オブジェクト zset などの独自のオブジェクト システムをカプセル化します。 object は少なくとも 1 つの基本データ構造を使用します。
redis は、柔軟性と効率を向上させるために、エンコーディング属性を通じてオブジェクトのエンコーディング形式を設定します。Redis は、さまざまなシナリオに基づいて自動的に最適化を行います。さまざまなオブジェクトのエンコードは次のとおりです。
String オブジェクト文字列: int 整数、embstr エンコードされた単純な動的文字列、生の単純な動的文字列
を使用します。
キャッシュ ブレークダウンの概念は、単一キーの同時アクセスが多すぎるということです。有効期限が切れると、すべてのリクエストがデータベースに直接送信されます。これはホット キーの問題に似ていますが、重要なのは、有効期限が切れるとすべてのリクエストが DB にヒットするということです。
解決策:
ロックして更新します。たとえば、A のクエリをリクエストして、それがキャッシュにないことが判明した場合、キー A をロックし、同時にキー A をロックします。次に、データベースにアクセスしてデータをクエリして書き込み、キャッシュしてからユーザーに返し、後続のリクエストでキャッシュからデータを取得できるようにします。
この現象を防ぐには、有効期限の組み合わせを値に書き込み、非同期で有効期限を継続的に更新してください。
キャッシュ ペネトレーションとは、キャッシュに存在しないデータをクエリすることを意味し、各リクエストはキャッシュが存在しないかのように DB にヒットします。
この問題に対処するには、ブルーム フィルターのレイヤーを追加します。ブルーム フィルターの操作手順は、ハッシュ関数を通じてデータをビット配列内の K 点にマッピングし、データを保存するためにこれらの点を 1 に設定することです。
このように、ユーザーが A を再度クエリし、A のブルーム フィルター値が 0 である場合、それが直接返され、ブレークダウン リクエストは生成されず、DB にヒットすることはありません。
ブルームフィルターを使用した後に問題となるのは、当然のことですが、配列そのものであるため、同じ位置に複数の値が入る可能性があります。配列の長さが長ければ誤判定の可能性は低くなりますが、このような問題は実情に応じて対応する必要があります。
ある瞬間に大規模なキャッシュ障害が発生すると、キャッシュサービスがダウンするなど、大量のリクエストが流入してDBを直撃します。システム全体の崩壊につながる可能性のあるものを雪崩と呼びます。ブレークダウンやホット キーの問題とは異なり、アバランシェ問題は、大規模なキャッシュが同時に期限切れになることを指します。
雪崩に対するいくつかの解決策:
同時有効期限切れを避けるために、異なるキーに異なる有効期限時間を設定します
ストリーム (Redis の場合)がダウンしている場合は、ストリームを制限して、同時に多数のリクエストによる DB のクラッシュを避けることができます。
2 次レベル キャッシュ、同じホット キー ソリューション。
redis には主に 2 つの期限切れ削除戦略があります。
遅延削除とは、キーがクエリされた場合にのみ検出され、有効期限が切れた場合にのみキーが検出されることを意味します。それは削除です。これらの期限切れのキーにアクセスしていない場合、明らかな欠点は、キーが常にメモリを占有し、削除できないことです。
Redis における定期的な削除とは、指定されたときにデータベース内のキーと値のペアを確認し、期限切れになったキーと値のペアを削除することです。 Redis は削除操作時にすべてのキーに対してポーリングを実行できないため、チェックと削除のためにいくつかのキーがランダムに選択されます。
Redis がキーを定期的にランダムにクエリするたびにキーを削除せず、これらのキーがクエリされないと仮定すると、これらのキーは Redis に保存され、削除できなくなります。 redis のメモリ削除機構に消えます。
volatile-lru: 有効期限が設定されたキーから、最も最近使用されていないキーを削除して削除します。
volatile-ttl: From From From From有効期限が設定されたキー、有効期限が近づいているキーを削除します
サーバーで各イベント ループが終了する前に、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 ファイルの最後の同期以降の書き込みコマンド データはすべて失われます。
高可用性を実現するには、1 台のマシンだけでは決して十分ではありません。高可用性を確保するために、redis には 2 つのオプションがあります。
マスター/スレーブ モードは、高可用性を実現するための最も単純なソリューションであり、中核となるのはマスター/スレーブの同期です。マスターとスレーブの同期の原理は次のとおりです。
スレーブはマスターに同期コマンドを送信します。
マスターが同期を受信した後、 bgsave が実行され、完全な RDB ファイルが生成されます。
マスターはスレーブの書き込みコマンドをキャッシュに記録します
bgsave が実行された後、マスターはスレーブの書き込みコマンドをキャッシュに記録します。 RDB ファイルをスレーブに送信し、スレーブはそれを実行します
マスターはキャッシュ内の書き込みコマンドをスレーブに送信し、スレーブはそれを実行します
#ノード B が会議メッセージを受信し、pong を返します
#A は、B が会議メッセージを受信したことを認識し、ping メッセージを返し、ハンドシェイクが成功します
最後に、ノード A はゴシップ プロトコルを通じてノード B の情報をクラスタ内の他のノードに広め、他のノードも B
slot
と握手をします。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 は、MULTI、EXEC、WATCH などのコマンドを通じてトランザクション メカニズムを実装します。トランザクション実行プロセスは、複数のコマンドを順番に一度に実行し、実行中にトランザクションは中断されません。すべてのコマンドが実行されるまで、クライアントからの他のリクエストは実行されません。トランザクションの実行プロセスは次のとおりです。
サーバーはクライアントのリクエストを受信し、クライアントが MULTI
の場合、トランザクションは開始されます。トランザクション状態にある場合、トランザクションはキューに入れられ、クライアントの QUEUED に返されます。それ以外の場合、このコマンドは直接実行されます。
クライアント EXEC コマンドを受信すると、 WATCH コマンドは、トランザクション全体のキーが存在するかどうかを監視します。変更されている場合は、失敗を示す空の応答がクライアントに返されます。それ以外の場合、redis はトランザクション キュー全体を走査し、キューに保存されているすべてのコマンドを実行します。最終的に結果をクライアントに返します
WATCH このメカニズム自体は CAS メカニズムです。監視されているキーはリンクされたリストに保存されます。キーが変更されると、REDIS_DIRTY_CAS フラグが設定されます。オンにすると、サーバーはトランザクションの実行を拒否します。
以上がRedis の面接の質問と回答は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。