Redis の高頻度面接の質問のまとめ (パート 1)

目次

1.Redisとは何ですか?

2. Redis はなぜ速いのか

3. 分散キャッシュの一般的なテクノロジー選択スキームは何ですか?

4. Redis と Memcached の違いを知っていますか?

5. Redis の使用シナリオは何ですか?

6. Redis で一般的に使用されるデータ構造は何ですか?

7. Redis データ型の基礎となるデータ構造は何ですか?

8. なぜ SDD を設計するのか?

9. zset (ジャンプテーブル) の基礎となる構造について話す

10. Redis が文字列型の値を保存できる最大容量はどれくらいですか?

11. Redis シングルスレッドモデルについて詳しく説明します

12. キャッシュされたデータに有効期限を設定する必要があるのはなぜですか?

13. Redis はデータの有効期限が切れているかどうかをどのように判断しますか?

14. Redis のメモリ削除メカニズムについて話す

15. Redis の永続化メカニズムは何ですか?

16. RDBトリガー方式? 

17. RDB実行の具体的なプロセス

18. AOF は書き込み前ログですか、それとも書き込み後ログですか?

19. AOFを実現するにはどうすればよいですか? 

20. AOF書き換えとは何ですか?

21. ログのプロセス全体を書き換える場合、メインスレッドはどこでブロックされますか?

22. AOF リライトが元の AOF ログを再利用しないのはなぜですか?



1.Redisとは何ですか?

Redis は、永続ストレージと、文字列、ハッシュ テーブル、リスト、セット、順序付きセットなどを含むさまざまなデータ構造をサポートするオープン ソース メモリ データベースです。Redis は、キャッシュ、メッセージ キュー、リアルタイム統計、リーダーボード、リアルタイム データ分析などのシナリオで広く使用されています。

Redis の機能は次のとおりです。

  1. 高いパフォーマンス: Redis はデータをメモリに保存し、読み取りと書き込みの速度が非常に高速です。

  2. 複数のデータ構造: Redis は、文字列、ハッシュ テーブル、リスト、セット、順序付きセットなどを含む複数のデータ構造をサポートします。

  3. 永続ストレージ: Redis は、プロセスの終了によってデータが失われないように、ディスクへのデータの永続ストレージをサポートしています。

  4. 分散サポート: Redis は分散アーキテクチャをサポートしており、複数の Redis インスタンスを通じてデータの分散ストレージと負荷分散を実現できます。

  5. 優れたスケーラビリティ: Redis はデータ レプリケーションとマスター/スレーブ同期をサポートしており、読み取りと書き込みの分離と高可用性を実現できます。

つまり、Redis は、さまざまなシナリオで広く使用されている、機能が豊富で高性能、使いやすいインメモリ データベースです。

2. Redis はなぜ速いのか

3 つの理由:

1. Redis は RAM ベースのデータ ストアです。RAM アクセスはランダム ディスク アクセスより少なくとも 1000 倍高速です。

2. Redis は、IO 多重化とシングルスレッド実行ループを使用して、実行効率を向上させます。

3. Redis は、いくつかの効率的な基礎データ構造を利用します。

3. 分散キャッシュの一般的なテクノロジー選択スキームは何ですか?

レディスを除いて。Memcached の方が一般的です

Memcached は、使いやすく、高いパフォーマンスを備え、大量の同時アクセスを処理できる軽量のキャッシュ システムです。Memcached は永続性をサポートしていません。データは通常メモリに保存されます。メモリが不足すると、データは一貫性のあるハッシュ アルゴリズムに従って他のノードに移行されます。Memcached はマルチスレッドをサポートしており、複数のリクエストを同時に処理できます。

4. Redis と Memcached の違いを知っていますか?

共通点:

  1. どちらも主記憶媒体としてメモリを使用するため、読み取りおよび書き込み要求に迅速に応答し、アクセス速度が向上します。
  2. どちらも分散キャッシュをサポートしており、データを複数のノードに分散して、キャッシュ システムの可用性とパフォーマンスを向上させることができます。
  3. どちらも文字列、リスト、ハッシュなどの単純なデータ構造をサポートしており、ほとんどのキャッシュ ニーズを満たすことができます。

ただし、Redis と Memcached にはいくつかの違いもあります。

  1. データ構造: Redis は、文字列、ハッシュ、リスト、セット、順序付きセットなどを含むさまざまなデータ構造をサポートします。各データ構造はさまざまな操作をサポートし、より複雑なキャッシュ要件を満たすことができます。Memcached はキーと値のペアの保存のみをサポートしており、操作は比較的単純です。
  2. 永続性: Redis はデータの永続性をサポートしており、データの損失を避けるためにデータをディスクに保存できます。ただし、Memcached は永続化をサポートしていません。通常、データはメモリに保存されます。メモリが不足した場合、データは一貫性のあるハッシュ アルゴリズムに従って他のノードに移行されます。
  3. パフォーマンス: Redis のパフォーマンスは、特に高い同時実行性、複雑なデータ構造、データの永続性の点で Memcached よりも高く、Redis の方がパフォーマンスが優れています。ただし、Redis のリソース消費量も高くなります。
  4. 分散ロック: Redis は分散ロックの実装をサポートしていますが、Memcached は分散ロックをネイティブにサポートしていないため、他の方法で実装する必要があります。

5. Redis の使用シナリオは何ですか?

一般的な使用シナリオをいくつか挙げます。

  1. キャッシュ: Redis の最も一般的な使用シナリオはキャッシュです。Redis はメモリを記憶媒体として使用するため、読み取りおよび書き込みリクエストに迅速に応答し、アクセス速度を向上させることができます。ホット データを Redis にキャッシュしてデータベースへの頻繁なアクセスを回避し、アプリケーションのパフォーマンスを向上させることができます。

  2. メッセージ キュー: Redis のパブリッシュ/サブスクライブ メカニズムを使用して、単純なメッセージ キュー システムを構築できます。Redis のチャネルにメッセージをパブリッシュし、そのチャネルにサブスクライブしているクライアントがメッセージを受信することで、メッセージのパブリッシュと消費を実現できます。

  3. 分散ロック: Redis を使用して分散ロックを実装できます。Redis はアトミック操作をサポートしているため、Redis を使用して分散ロックを実装し、複数のプロセスが共有リソースに同時にアクセスすることを防ぎ、それによってデータの一貫性とシステムのセキュリティを確保できます。

  4. カウンタ: Redis はアトミック操作をサポートしており、カウンタの実装に使用できます。カウンタをRedis上に格納し、複数のクライアントがカウンタ上で同時に動作することで分散カウンタの機能を実現します。

  5. 地理的位置アプリケーション: Redis は、地理的位置アプリケーションを実現するために、緯度や経度などの地理的位置情報を保存するために使用できる地理的位置データ型をサポートします。

  6. リアルタイム リーダーボード: Redis を使用すると、リアルタイム データを保存し、データに従って並べ替えることができ、リアルタイム リーダーボード機能を実現できます。

  7. セッション管理: Redis を使用して、ユーザー情報、ログインステータスなどのセッションデータを保存し、セッション管理の機能を実現できます。

6. Redis で一般的に使用されるデータ構造は何ですか?

Redis は、次の一般的に使用されるデータ構造を含む、さまざまなデータ構造をサポートしています。

  1. 文字列 (文字列): 文字列は Redis の最も基本的なデータ構造の 1 つであり、文字列、整数、浮動小数点数などのデータ型を格納できます。

  2. ハッシュ (ハッシュ): ハッシュは、小規模なリレーショナル データベースと同様に、複数のフィールドと値を格納できるキーと値のペアのコレクションです。

  3. リスト (リスト): リストは、リストの両端で挿入および削除できる順序付けされた文字列の集合であり、キューやスタックなどのさまざまなデータ構造をサポートします。

  4. セット (セット): セットは、順序付けされていない文字列のコレクションです。セットに対して追加、削除、交差、結合などの操作を実行でき、データの重複排除に使用できます。

  5. ソート セット (ソート セット): ソート セットは順序付けされた文字列セットであり、各要素にはスコアがあり、ランキングや間隔クエリなどの操作を実行でき、リーダーボードやスコアリング システムなどの機能を実装するためによく使用されます。

3 つの特別なデータ型は 、HyperLogLogs (カーディナリティ統計)、Bitmaps (ビットマップ)、および地理空間 (地理的位置) です。

7. Redis データ型の基礎となるデータ構造は何ですか?

Redis は次の 5 つの主要なデータ型をサポートしており、それぞれに異なる基礎となるデータ構造の実装があります。

  1. 文字列 (文字列): 基礎となる層は、バイナリ セキュリティ操作をサポートする Simple Dynamic String (SDS) で実装されます。

  2. ハッシュ (ハッシュ): 最下層はハッシュ テーブルによって実装され、高速な検索、挿入、削除の操作をサポートします。

  3. リスト (リスト): 最下層は二重リンクリストによって実装され、先頭と末尾での高速な挿入および削除操作をサポートします。

  4. セット (集合): 最下層はハッシュ テーブルまたはスキップ テーブルによって実装され、和集合、積集合、差分などの効率的な集合演算をサポートします。

  5. ソートセット (順序付きセット): 最下層はスキップテーブルとハッシュテーブルの組み合わせによって実装され、スコア別およびメンバー別のソート操作をサポートします。

8. なぜ SDD を設計するのか?

Redis は、主に C 言語の従来の文字配列 (char 配列) に存在する次のようないくつかの問題を解決するために、SDS (Simple Dynamic String) の単純な動的文字列を設計しました。

  1. スペースを動的に調整するのは簡単ではありません。C 言語の文字配列は定義時に長さを指定する必要があります。長さが十分でない場合は、より大きな配列を再定義してから、元の配列のデータをコピーする必要があります。新しい配列の場合、このような操作は非常に面倒でエラーが発生しやすくなります。

  2. バイナリ セキュリティはサポートされていません。C 言語の文字配列はターミネータとして「\0」を使用するため、バイナリ データまたは「\0」文字を含む文字列はサポートされません。

  3. パフォーマンスの問題: C 言語の文字配列は、長さを取得するときに配列全体を走査して長さを計算する必要があり、非効率的です。

SDS では、動的に割り当てられたメモリを指す buf ポインタを維持し、同時に文字列の長さ情報を記録することで、上記の問題を解決できます。

1. 動的拡張

SDS の内部構造は、長さ、使用可能なスペース、および文字配列で構成されます。空き領域とは、文字列配列内の未使用の領域を指します。C 言語のネイティブの文字列型と比較して、SDS は動的に拡張できます。つまり、文字列の長さが使用可能なスペースを超えると、使用可能なスペースが自動的に増加します。この設計により、SDS の操作がより効率的になり、メモリの再割り当てや文字列を何度もコピーするオーバーヘッドが回避されます。

2. バッファオーバーフローのリスクを軽減する

C言語のネイティブ文字列型では長さに制限がないため、文字列の長さが文字配列の長さを超えるとバッファオーバーフローの問題が発生します。SDS は、文字列の実際の内容を格納する buf 属性を設計しており、buf 配列の長さは文字列の実際の長さ内で制御されるため、バッファ オーバーフローのリスクが回避されます。

3. C言語ネイティブ文字列型と互換性あり

C 言語のネイティブ文字列型との互換性を保つために、SDS は内部構造にヌル文字 ('\0') を予約しています。これにより、SDS は他の C 言語関数と対話するときにネイティブ文字列のように動作できるようになります。

4. バイナリセキュリティ

C 言語のネイティブ文字列型では、文字列の末尾にヌル文字 ('\0') が使用されます。これは、テキスト データのみを保存できることを意味します。SDS はバイナリ セーフであり、あらゆるバイナリ データを保存できます。この設計により、SDS は Redis にキーと値を保存するのに非常に役立ちます。

5. 文字列操作の最適化

文字列の長さ情報は SDS の内部構造に格納されるため、文字列の長さを取得する操作は O(1) 時間になります。さらに、SDS は、文字列の追加、文字列のコピーなど、他の文字列操作関数も提供します。これらの関数は、C 言語のネイティブの文字列操作関数よりも効率的です。

Redis7.0のSDSのソースコードの一部は以下の通りです(https://github.com/redis/redis/blob/7.0/src/sds.h)。

/* Note: sdshdr5 is never used, we just access the flags byte directly.
 * However is here to document the layout of type 5 SDS strings. */
struct __attribute__ ((__packed__)) sdshdr5 {
    unsigned char flags; /* 3 lsb of type, and 5 msb of string length */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr8 {
    uint8_t len; /* used */
    uint8_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr16 {
    uint16_t len; /* used */
    uint16_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr32 {
    uint32_t len; /* used */
    uint32_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr64 {
    uint64_t len; /* used */
    uint64_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};

ソース コードから、SDS の実装メソッドは SDS_TYPE_5 (未使用)、SDS_TYPE_8、SDS_TYPE_16、SDS_TYPE_32、SDS_TYPE_64 の 5 つあり、実際に使用されるのは最後の 4 つだけであることがわかります。Redis は初期化の長さに基づいて使用するタイプを決定するため、メモリ使用量が削減されます。

タイプ バイト 少し
sdshdr5 < 1 <8
sdshdr8 1 8
sdshdr16 2 16
sdshdr32 4 32
sdshdr64 8 64

後の 4 つの実装には、次の 4 つの属性が含まれます。

  • len: 文字列の長さは、すでに使用されているバイト数です。
  • alloc: 利用可能な文字スペースの合計サイズ。alloc-len は SDS の残りのスペース サイズです。
  • buf[]: 実際に文字列を格納する配列
  • flags: 下位 3 ビットはタイプ フラグを保存します

9. zset (ジャンプテーブル) の基礎となる構造について話す

ジャンプ テーブルは、平均 O(logN)、最悪 O(N) の複雑さの検索、および zset (順序セット) の基礎となる実装をサポートします。

zset の機能:

  • 反復しないが順​​序付けられた文字列要素のコレクション。
  • 各要素は double 型のスコアに関連付けられており、Redis はスコアに従って小さいものから大きいものの順に並べ替えます。
  • スコアは繰り返すことができ、繰り返されたスコアは挿入順序に従って並べ替えられます。

zskiplistNodeこの構造体には、要素値、スコア値、バック ポインター、およびレベル ポインターの配列が含まれています。レベル ポインター配列の各要素には、対応するレベルの現在のノードの次のノードと、ランキングの計算とノードの削除に使用される現在のノードから次のノードまでのスパンが含まれます。

Redis では、ジャンプ リスト内の要素は順序付けられたコレクションを実装するために使用され、各要素には値とスコアが含まれており、スコアは要素の並べ替えに使用されます。したがって、zskiplistNode構造体のobjポインターはrobj、要素の値を含む Redis オブジェクト ( ) を指しscore、要素のスコアを表します。

要素の値とスコアに加えて、zskiplistNodeこの構造には、現在のノードの前のノードを指すバック ポインターも含まれています。バック ポインタの役割は、ジャンプ テーブルでの逆方向のトラバースを容易にすることです。

/* ZSETs use a specialized version of Skiplists */
typedef struct zskiplistNode {
	//数据
    sds ele;
    //节点分值
    double score;
    //节点的后退指针
    struct zskiplistNode *backward;
    struct zskiplistLevel {
        //节点的前进指针
        struct zskiplistNode *forward;
        //跨度
        unsigned long span;
    } level[];
} zskiplistNode;
typedef struct zskiplist {
	//跳跃表的头结点和尾节点
    struct zskiplistNode *header, *tail;
    //跳跃表的长度
    unsigned long length;
    //跳跃表的层数
    int level;
} zskiplist;

最後に、ジャンプ テーブル ノードのレイヤー ポインタ配列は、ジャンプ テーブルの実装の中核部分であり、高速な検索と削除を実現するために使用されます。各ノードのレベル配列には、各レベルの現在のノードの次のノードを指すいくつかのポインタが含まれています。レベル ポインタ配列の長さはランダム アルゴリズムに従って生成され、各ノードのレベル数は異なり、最大値は 32 です。階層ポインター配列の各要素には、現在のノードから次のノードまでのスパンを表すspan属性、ランキングの計算に使用されます。

10. Redis が文字列型の値を保存できる最大容量はどれくらいですか?

Redis 文字列型の値は、最大 512MB のデータを保存できます。より大きなデータを保存する必要がある場合は、データを 512MB 未満の複数のブロックに分割して複数の文字列タイプのキーに保存するか、Redis の他のデータ構造を使用してデータを保存できます。

11. Redis シングルスレッドモデルについて詳しく説明します

Redis は単一プロセスおよび単一スレッドのモデルであり、公式データでは 100,000+ QPS (1 秒あたりのクエリ数) に達することがあります。

なぜ効率が高いのか:

1. 純粋なメモリ操作

2. ノンブロッキング IO 多重化メカニズムに基づく

3. 複数のスレッドの頻繁なコンテキスト切り替えを避ける

Redis は、Reactor モデルに基づいて独自のネットワーク イベント プロセッサ ファイル イベント プロセッサを開発しました。このプロセッサはシングルスレッドであるため、Redis はシングルスレッド モデルとして設計されています。

Reactor パターンはイベント駆動型の設計パターンであり、その中心的な考え方は、イベント処理をイベント配布とイベント処理の 2 つの段階に分割することです。イベント配信フェーズでは、システムはイベント ループ (イベント ループ) を通じてイベントを継続的に監視し、イベント処理フェーズでは、イベントが発生すると、システムは対応するイベント ハンドラーにイベントを渡して処理します。このモードでは、システム内のスレッドの数を減らすことができ、システムのスケーラビリティとパフォーマンスを向上させることができます。

Redis では、イベント ループは「メイン ループ」と呼ばれ、すべてのネットワーク イベントとファイル イベントをリッスンし、これらのイベントをイベント キューに追加します。イベント キューにイベントがある場合、Redis は対応するイベント ハンドラーを呼び出して処理します。プロセッサの実行中、Redis は内部データ構造とアルゴリズムを呼び出して、データを効率的に処理します。

さらに、Redis は多重化テクノロジーを使用してイベント監視を実装します。つまり、1 つのスレッドを使用して複数のネットワーク接続を監視することで、スレッド切り替えのオーバーヘッドを回避し、システムのパフォーマンスを向上させます。

12. キャッシュされたデータに有効期限を設定する必要があるのはなぜですか?

キャッシュされたデータの有効期限を設定する Redis の主な機能は、キャッシュされたデータのライフ サイクルを制御することです。

1. キャッシュ内のデータが常に存在するとは限らないため、キャッシュの有効性が確保され、メモリ負荷が軽減されます。

2. ビジネスニーズ。

具体的には、Redis でキーと値のペアに有効期限が設定されている場合、Redis はその時間が経過するとキーと値のペアをキャッシュから自動的に削除するため、キャッシュの有効期限を回避するためにキャッシュ スペースが間に合うように解放されます。メモリの無駄遣いで。同時に、クライアントがキーと値のペアをリクエストしたときに、キーと値のペアの有効期限が切れていることを Redis が検出すると、Null 値を返すか、最新のデータをキャッシュに再ロードします。

さらに、有効期限を設定すると、キャッシュの故障やキャッシュなだれなどの問題を防ぐこともできます。キャッシュが故障すると、キャッシュには存在しないがデータベースには存在するデータを大量のリクエストが同時に要求し、その結果データベースに過剰な負荷がかかります。キャッシュなだれとは、キャッシュに存在しないデータが原因でデータベースに負荷がかかることを指します。キャッシュが突然増加した場合、多数のキーと値のペアが同時に期限切れになります。有効期限を設定すると、これらの問題を効果的に回避できます。

13. Redis はデータの有効期限が切れているかどうかをどのように判断しますか?

Redis は、遅延削除と定期削除を使用してデータの有効期限が切れているかどうかを判断します。

1. 遅延削除

遅延削除とは、Redis クライアントがキーと値のペアをリクエストすると、Redis はデータを返す前にキーと値のペアが期限切れかどうかを確認し、期限切れの場合は削除して null 値を返すか、最新のデータをキャッシュに再ロードすることを意味します。この方法の利点は、データのリアルタイム パフォーマンスを保証できることですが、欠点は、期限切れのデータはクライアントの要求時にしか見つからないため、一部の要求では応答時間が長くなる可能性があることです。

2. 定期的に削除する

定期的な削除とは、Redis がバックグラウンドでタイマーを開始し、有効期限が設定されたすべてのキーと値のペアを定期的にチェックし、キーと値のペアの有効期限が切れていることが判明した場合はそのキーと値のペアを削除することを意味します。Redis は、「有効期限辞書」と呼ばれる構造を使用して、すべてのキーと値のペアを有効期限付きで保存します。この辞書のキーはキーと値のペアのキーであり、値はキーと値のペアの有効期限タイムスタンプです。 。通常のデリーターが実行されると、Redis は期限切れの辞書を走査し、期限切れのキーと値のペアをすべて削除します。

遅延削除と定期削除の長所と短所のバランスをとるために、Redis はハイブリッド戦略を使用します。キーの有効期限が切れると、Redis はそのキーを有効期限ディクショナリに追加し、遅延削除戦略を使用して期限切れのキーをクリーンアップします。さらに、Redis は定期的に定期的な削除タスクを実行して、遅延削除では時間内にクリーンアップできない期限切れのキーをクリーンアップします。

メモリ内に期限切れキーが過度に蓄積されるのを避けるために、Redis は期限切れキーのクリーニング プロセス中にいくつかの技術的手段を使用します。たとえば、パーティション テクノロジを使用して期限切れキーをさまざまな領域に分散し、定期的な削除ごとに処理される期限切れキーを制限します。タスクの量など

14. Redis のメモリ削除メカニズムについて話す

Redis はさまざまなメモリ削除メカニズムを実装しています。Redis メモリ削除メカニズムの一般的な実装をいくつか次に示します。

  1. LRU (最も最近使用されていない) アルゴリズム: Redis は LRU アルゴリズムを使用して、削除するキーを選択します。LRU アルゴリズムは、最も最近使用されていないキー、つまりめったにアクセスされていないか、最近アクセスされていないキーの削除を優先します。

  2. LFU (Least Frequently Used) 最も使用頻度の低いアルゴリズム: Redis は LFU アルゴリズムを使用して、削除するキーを選択します。LFU アルゴリズムは、最も使用されていないキー、つまり、めったにアクセスされていないか、最近アクセスされていないキーの削除を優先します。

  3. ランダム アルゴリズム: Redis は、ランダム アルゴリズムを使用して、削除するキーを選択することもできます。ランダム アルゴリズムは、削除するすべてのキーからキーをランダムに選択します。

  4. TTL (Time To Live) 有効期限アルゴリズム: Redis は有効期限に基づいてキーを削除することもできます。Redis はメモリが不足すると、期限切れのキーの削除を優先します。

15. Redis の永続化メカニズムは何ですか?

Redis の永続化メカニズムとは、データ損失を防ぐために Redis データをディスクに永続化することを指します。Redis は、RDB と AOF という 2 つの異なる永続化メカニズムを提供します。

1. RDB (Redis Database) 永続化メカニズム

RDB は、Redis のデフォルトの永続化メカニズムです。RDB メカニズムは、Redis データのスナップショットを取得し、指定された時間間隔内にディスク上の RDB ファイルに書き込みます。RDB ファイルは、特定の時点での Redis データのスナップショットを含むバイナリ ファイルです。

アドバンテージ:

  • RDB ファイルは小さいため、大量のデータのバックアップと復元に適しています。
  • RDB ファイルはバイナリであるため、はるかに高速にロードできます。
  • データ セットが大きい場合、RDB は AOF よりもデータの復元が高速です。

欠点:

  • Redis がダウンすると、最後に保存された RDB ファイル内のデータが失われ、ある程度のデータ損失が発生する可能性があります。
  • RDB は定期的に実行されるため、Redis がダウンすると、最後に永続化されたデータがダウンタイム前のデータと大きく異なり、データの損失につながる可能性があります。

2. AOF (Append-Only File) 永続化メカニズム

AOF メカニズムは、すべての書き込みコマンドを記録し、ディスク上の AOF ファイルに追加します。Redis が再起動したら、AOF ファイル内のすべてのコマンドを再実行することでデータを復元できます。

アドバンテージ:

  • AOF ファイルには、Redis サーバーによって実行されるすべての書き込み操作が含まれるため、データ損失は最小限に抑えられます。
  • AOF ファイルはテキスト形式なので、読みやすくデバッグが簡単です。
  • AOF メカニズムは、no、always、everysec などの複数の同期方法をサポートしており、ニーズに応じて適切な方法を選択できます。

欠点:

  • AOF ファイルは RDB ファイルよりも大きいため、少量のデータのバックアップと復元に適しています。
  • AOF メカニズムでは、AOF ファイルに書き込みコマンドを継続的に追加する必要があるため、書き込みパフォーマンスの点で低下する可能性があります。

一般に、実際の状況に応じて適切な永続化メカニズムを選択する必要があります。データ セットが小さい場合は、AOF メカニズムを使用してデータ損失を最小限に抑えることができます。データ セットが大きい場合は、RDB メカニズムを使用して、低コストでデータのバックアップと復元を行うことができます。

同時に、RDB と AOF の仕組みを組み合わせて、それぞれの利点を最大限に活用することもできます。たとえば、AOF メカニズムを常にに設定し、定期的なデータ バックアップには RDB メカニズムを使用できます。これにより、データが失われないようにできるだけでなく、データ セットが大きい場合のデータ回復速度も向上します。

16. RDBトリガー方式? 

手動トリガー: save コマンドを実行します。問題: rdb が完了し、運用環境が無効になるまで、データ ボリュームが現在のサーバーをブロックします。

解決策: bgsave コマンド (バックグラウンド保存)、つまりバックグラウンド バックアップを使用します。メイン プロセスはサブプロセスをフォークして RDB プロセスを完了し、完了後に自動的に終了します (オペレーティング システムのマルチプロセス コピー オン ライト メカニズム)。システム、COW と呼ばれます)。フォークは子プロセスもブロックしますが、時間は非常に短いです。

自動トリガー:

1. redis.conf を構成し、トリガー ルールを構成し、自動的に実行します。

# 当在规定的时间内,Redis发生了写操作的个数满足条件,会触发发生BGSAVE命令。
# save <seconds> <changes>
# 当用户设置了多个save的选项配置,只要其中任一条满足,Redis都会触发一次BGSAVE操作
save 900 1 
save 300 10 
save 60 10000
# 以上配置的含义:900秒之内至少一次写操作、300秒之内至少发生10次写操作、
# 60秒之内发生至少10000次写操作,只要满足任一条件,均会触发bgsave

2. shutdownコマンドを実行してサーバをシャットダウンする際、AOF永続化機能が有効になっていない場合、bgsaveが自動的に実行されます。

3. マスター/スレーブ同期 (スレーブとマスターが同期メカニズムを確立します)

スレーブ ライブラリとマスター ライブラリ間の接続が確立されると、マスター ライブラリは bgsave を実行して現在のバックアップ データをスレーブ ライブラリに転送し、バックアップ プロセス中に発生する書き込み操作もキャッシュします。

17. RDB実行の具体的なプロセス

Redis は主に、オペレーティング システムのマルチプロセス カウ (コピー オン ライト) メカニズムを使用して、RDB スナップショットの永続性を実装します。

1. bgsave を実行すると、メインスレッドはまず rdb/aof 永続タスクを実行している子プロセスが存在するかどうかを判断し、存在する場合は直接リターンします。

2. メインプロセスは子プロセスをフォークし、フォークプロセス中にメインプロセスは一時的にブロックされます。

3. 子プロセスは、メイン プロセスのメモリに基づいて一時的なスナップショット ファイルを生成します。永続化が完了すると、元の rdb ファイルが置き換えられます。バックアップ プロセス中に新しい書き込み要求が引き続き受信されるため、これらの書き込み要求は、操作はメイン プロセスのメイン メモリ (つまり、バックアップ時に読み取られるメモリ) では行われません。一時メモリ領域にコピーとして書き込みます。

4. 子プロセスはRDB永続化が完了するとメインプロセスに通知し、バックアップ時に一時メモリに書き込まれた書き込みデータをメインメモリに同期します。

18. AOF は書き込み前ログですか、それとも書き込み後ログですか?

AOF は書き込み後のログ メカニズムです。つまり、Redis が書き込み操作を実行すると、まずコマンドがメモリ内の AOF バッファーに追加され、ハードディスクとの同期を待ちます。コマンドが AOF ファイルに正常に追加され、ハード ディスクと同期された場合にのみ、Redis は実際の書き込み操作を実行します。したがって、書き込み操作中に Redis がクラッシュした場合でも、AOF バッファーに追加されたものの、ハードディスクに同期されていないコマンドは失われず、AOF ファイルを再生することでデータを回復できます。

書き込み後のログ メカニズムでは、ハード ディスクへの各書き込み操作を直ちに同期する必要がないため、Redis の書き込みパフォーマンスを大幅に向上させることができます。先行書き込みログ メカニズムを使用する場合、各書き込み操作はクライアントに戻る前にハード ディスクとの同期を待つ必要があり、これにより、特に書き込み負荷が高い場合に大きな遅延が発生します。書き込み後ログ メカニズムを採用した後、Redis は最初に書き込み操作をメモリ内のバッファに保存し、次にバッファの内容をハードディスクに非同期に書き込むことができるため、書き込みパフォーマンスが大幅に向上します。

次に、書き込み後のログ メカニズムを使用すると、Redis の信頼性も向上します。AOF ファイルには Redis によって実行されたすべての書き込み操作が記録されるため、操作中に Redis がクラッシュした場合でも、AOF ファイルを再生することでデータを回復できます。ただし、ログ前書き込みメカニズムを使用する場合は、各書き込み操作を直ちにハードディスクに同期する必要があるため、クラッシュが発生するとデータが失われます。

19. AOFを実現するにはどうすればよいですか? 

AOF (Append-Only File) メカニズムを実装するには、Redis 構成ファイルで AOF 機能を有効にし、AOF の関連パラメーターを設定する必要があります。Redis では、次の手順で AOF を実装できます。

  1. AOF 機能を有効にする: Redis 構成ファイル redis.conf で、appendonly パラメーターを yes に設定することで、AOF 機能を有効にできます。例えば:appendonly yes

  2. AOF ファイル名とパスを設定する: dir パラメーターと appendfilename パラメーターを設定することで、AOF ファイルの保存パスとファイル名を指定できます。例:dir /var/lib/redisそしてappendfilename "appendonly.aof"

  3. AOF 同期戦略を設定する: appendfsync パラメーターを設定することで、AOF 同期戦略を指定できます。つまり、AOF バッファー内のデータをハードディスク内の AOF ファイルに同期するタイミングを指定できます。Redis は、次の 3 つの同期戦略を提供します。

  • always: データの整合性を確保するために、すべての書き込み操作は直ちにハードディスク上の AOF ファイルと同期されますが、パフォーマンスは低下します。

  • Everysec: AOF バッファー内のデータをハードディスク内の AOF ファイルに毎秒同期します。これによりパフォーマンスがある程度向上しますが、1 秒間のデータが失われる可能性があります。

  • no: AOF バッファ内のデータは定期的にハードディスク上の AOF ファイルに書き込まれ、パフォーマンスは最高ですが、データ損失が発生する可能性があります。

例えば:appendfsync everysec

        4. Redis サービスを再起動します。Redis 構成ファイル内の AOF 関連パラメータを変更した後、構成を有効にするために Redis サービスを再起動する必要があります。

20. AOF書き換えとは何ですか?

aof Rewrite は aof ファイルを圧縮するプロセスですが、元のファイルに基づいて圧縮されるのではなく、RDB スナップショットと同様に、COPY ON WRITE に基づいてメモリ内のデータを走査し、最終状態データを次の形式で保存します。コマンドに相当します。 1 つのデータが複数の操作を経て複数のコマンドに対応する場合がありますが、最終的には最終状態を表すコマンドになります。

rdb と同様に、書き換えも子プロセスをフォークする必要があり、子プロセス内で完了します。書き換えプロセス中も、新しい操作は元の aof ファイルに書き込まれ、これらの操作も redis によって収集されます。書き換えが完了すると、これらの操作も新しい aof ファイルに追加されます。

トリガー機構

手動トリガー: bgrewriteaof コマンドを直接呼び出して書き換え操作を実行します。

自動トリガー: auto-aof-rewrite-min-size および auto-aof-rewrite-percentage パラメーターに従って自動トリガーのタイミングを決定します。

auto-aof-rewrite-min-size:表示运行AOF重写时文件最小体积,默认为64MB(我们线上是512MB)。

auto-aof-rewrite-percentage:相对于“上一次”rewrite,本次rewrite触发时aof文件应该增长的百分比。 代表当前AOF文件空间(aof_current_size)和上一次重写后AOF文件空间(aof_base_size)的值

21. ログのプロセス全体を書き換える場合、メインスレッドはどこでブロックされますか?

  1. Redis が子プロセスをフォークする場合、親プロセスのメモリ マッピング テーブルをコピーする必要があるため、メイン スレッドがブロックされます。

  2. Redis メイン プロセスが bigkey データを書き込むとき、オペレーティング システムはデータのページのコピーを作成し、元のデータをコピーします。この操作によりメイン スレッドもブロックされます。

  3. AOF 書き換えプロセス中、子プロセスは独立して書き換え操作を実行しますが、子プロセスの実行終了後、子プロセスはメイン プロセスにシグナルを送信して、メイン プロセスが書き換えバッファーの内容を AOF に追加できるようにします。ファイル。この操作によりメインスレッドがブロックされる可能性があります。

22. AOF リライトが元の AOF ログを再利用しないのはなぜですか?

  1. 親プロセスと子プロセスの間で同じファイルを書き込むと、競合の問題が発生し、親プロセスのパフォーマンスに影響します。
  2. AOF 書き換えプロセスが失敗すると、元の AOF ファイルが汚染されることと同じになり、データの回復には使用できません。

おすすめ

転載: blog.csdn.net/qq_33129875/article/details/129419866