Redisのソースコード解析(3) - RDB永続

RedisのRDB持続性

  RDBとAOF:Redisのは、2つの永続方法をサポートしています。ディスクに格納されたシーケンスの記憶ノードのRDBデータは、データが可能な省スペース方法のシーケンスに格納され、完全にASCII図ありません。これは、省スペース化、高速回復、すべてのメモリのデータのために必要な操作のすべての列、および持続性を変更するプロセスが失われる欠点の利点があります。記憶するようにし、動作コマンドデータAOF、ファイルからAOFコマンドAOFから読み込まれた後、コマンドを実行しているデータを回復します。利点は、永続コマンド生成処理を記録することができることであるが、欠点は、完全に符号化されたASCII、空間をより使用、および回復に遅いこと。この章では、簡単な紹介を行うための永続的なファイルRDBの方法に焦点を当てています。

  Redisの異なるタイプを実行するために、(辞書、格納されている文字列、リスト、データのセット及び他のタイプであるDB即ちA)が存在などの文字列、セット、ZSET、ハッシュ、リストなどのデータのいくつかの種類があり、DBを複数有しますシリアル化されたデータは、Redisのは、対応する永続化フォーマットを設計しました。

1.シリアル化された文字列

  文字列をシリアル化するとき、文字列の長さは、その後、最初の文字列に格納された実際の値が格納されます。文字列の様々な長さのために、Redisのは、その長さを格納するように少しスペースを使用し、スペースを節約するため、次の形式で格納されている文字列の長さの設計には:     

  1. LEN <1 << 6、1バイトのコード長を使用して、上位バイトが00 2ビットであり、代表的な長さ低い6bits
  2. 1 << 6 <= 1 << 14は、後続の代表長さ2バイトのコード長は、最初の2つの01ビットの上位バイト、14bitsを使用LEN <
  3. 1 << 14は、<= LEN <= UINT32_MAX、5つのバイトを使用してコード長は、最初のバイトが0x80であり、後続の4バイトの長さを表します
  4. UINT32_MAX <lenは、9つのバイトコード長を使用して、最初のバイトは0x81と、その後の8バイトの代表的な長さであります

次のように定義し、対応するのRedis:

/ * ダンプ・ファイル形式に関連する定義します。32ビットを格納するには短いため長
 *キースペースの多くを必要とするので、私たちはの上位2ビットのチェック
 の長さをインタプリタに最初のバイト*:
 * 
 * 00 | 2 MSBが00であればXXXXXX => lenがありますこのバイトの6ビット
 * 01 | XXXXXX XXXXXXXX => 01、lenが14の不戦勝、次のバイトの+ 8ビットの6ビットである
 * 10 | 000000 [32ビット整数] =>ネットバイト順でlenの完全な32ビットが続きます
 * 10 | 000001 [64ビット整数] =>続くネットバイト順でlenの完全な64ビット
 * 11 | OBKINDこれ:続く特別に符号化されたオブジェクト。6ビット
 *数は、以下のオブジェクトの種類を指定します。
 * RDB_EN​​C_ *定義を参照してください。
 *
 *長さは63までのシングルバイト、ほとんどのDBのキーを使用して保存されている、とも
 *値は、内部にフィットします。* /

例えば、エンコード文字列「Hello World」の次のように:

0xC「こんにちは、世界」

1バイトの文字列の長さで表現から0xCは12バイト、文字列のフォローアップの真値であり、12バイトです。非プリフィックスコードので、それらはどのような形式を区別するために、最初のバイトの値に基づくことができるが、最初のバイトのデシリアライゼーションの内容を読み、このバイトの値の正しい動作を選択すること、です。

  rdb.cのRedisのソースファイルrdbSaveLen機能完了コード長、及びrdbLoadLenは長さの値を復号化され。

int型の2列

  整数値の必要なシーケンスの値は、バイナリ整数値を直接シリアル化されるときに、むしろ一層省スペース化、ASCIIコードの文字列配列に変換するより。さらに、整数値の大きさに応じて、同様にRedisのような小さなスペースは、値を格納します。同様に、文字列、最初のバイトが高い2ビット11に設定されているバイト数の低い値は6bitsを区別するために使用しながら、後続の値は、整数値で表しています。

  1.   (値> = - (1 << 7)&&値<=(1 << 7)-1)、低6ビットは0、ストレージ後続の整数値の1バイト。
  2.   1 - (値> =(1 << 15)&&値<=(1 << 15)-1)、低6btis値、格納整数値のその後の2バイト。
  3.   (値> = - ((長い長い)1 << 31)&&値<=((長い長い)1 << 31)-1)、低6bits 2、後続の4バイトストアの整数値です。

全体の形:  

11000000 [ 8 ビット整数]
 11000001 [ 16 ビット整数]
 11000002 [ 32ビット整数]

例えば、整数値のシーケンスは、以下のように結果が0x300から。

0xC1  0x0300

0xC1は、整数値であるINT16として格納された値、0x0300に続く整形を示します。最初のバイトが高い2ビット11であるため、フォーマットタイプは、文字列の長さが同じではない、これは文字列またはintとして区別することができる示しています。

  最初のバイトが高い2ビット11である場合、3(RDB_EN​​C_LZF)などの低6bitsさらに、その後のデータは、それぞれ、長さの値の後に2つのバイトが続く圧縮データであり、圧縮後の圧縮前のデータの長さ当時のデータ長、実際のデータ。

3. RDB_TYPE_ *とRDB_OPCODE_ *

  Redisのは、すべての値が辞書DBに格納されたキー値の形態であり、キーと値のキャッシュシステムです。Redisの値の文字列の種類に限定されるものではないが、それはまた、そのようなセットのような構造、リスト、ハッシュなどのタイプであってもよいです。これらの型をシリアル化するために、最初のRedisのデータ型のバイトを格納する、及び複合型場合、このタイプのメンバの数を記憶し、次に基本的な整数値または文字列タイプが格納されているメンバーを横断します。

  次の値で定義されているRedisのタイプ:

/ * RDBのオブジェクトタイプにマップオブジェクトタイプ。OBJ_で始まるマクロはのためのものです
 *メモリストレージと変更されることがあります。ので、代わりに、RDBの種類が固定されている必要があり
 、我々は、ディスクに保存します*。* / 
の#define RDB_TYPE_STRING 0
 の#define RDB_TYPE_LIST 1
 の#define RDB_TYPE_SET 2
 の#define RDB_TYPE_ZSET 3
 の#define RDB_TYPE_HASH 4
 の#define RDB_TYPE_ZSET_2 5 / *バイナリ形式で格納されたダブルスとZSETバージョン2。* /
 の#define RDB_TYPE_MODULE 6
 の#defineずに解析するための注釈付きRDB_TYPE_MODULE_2 7 / *モジュール値
                               生成モジュールがロードされます。* /
 / * 注:下記NEW RDBのTYPE、UPDATE rdbIsObjectTypeを()を追加* / 

/ * エンコードされたオブジェクトのオブジェクトタイプ。* / 
の#define RDB_TYPE_HASH_ZIPMAP 9
 の#define RDB_TYPE_LIST_ZIPLIST 10
 の#define RDB_TYPE_SET_INTSET 11
 の#define RDB_TYPE_ZSET_ZIPLIST 12
 の#define RDB_TYPE_HASH_ZIPLIST 13
 の#define RDB_TYPE_LIST_QUICKLIST 14
 の#define RDB_TYPE_STREAM_LISTPACKS 15
 / * 注:新しいRDBタイプを追加、UPDATE rdbIsObjectType()BELOW * /

これらの値は、そのようなリストとして、値のタイプであり、そのようなハッシュテーブルとして、特定の実装の値を示すことに加えて、等を設定し、設定を達成するために使用することができる対応する値型RDB_TYPE_SETのシーケンスの種類を表し、使用して注文することができますアレイの実現を成形する、対応するタイプはRDB_TYPE_SET_INTSETあります。最初のデシリアライズするバイト値が後続のデータの種類、適切な入力し、再構築を決定読み出します。

例えば、こんにちは、世界「として」結果「KEY1」のキーと値の型配列の文字列:

RDB_TYPE_STRING 0x4の「キー1」から0xC「こんにちは、世界」

最初、1バイトのタイプ値RDB_TYPE_STRING、長さを0x4バイトの値、キーワード文字列の後ろに、すなわち4バイト、すなわち、12バイトの文字が続くバイト長の値から0xC、 Chuanzhi。

ときデシリアライズ:

  1. RDB_TYPE_STRING利用可能な最初のバイトを読み取る、文字列オブジェクトに続いて得られました
  2. 次に、0x4の値は、長さを読み、キーワードを取得し、対応する4つのバイトを読み取ります
  3. 最後に、長さから0xCを読み、12バイト分の値に対応する値を読み出します。

例えば、キーと値のペアのリストは、タイプ「KEY2」2の直列3 4 0x300からです。

RDB_TYPE_LISTの0x4の「KEY2」を0x4  0xc0で 0x2の 0xc0から 0x3の 0xc0から 0x4の 0xC1  0x0300

第1バイトタイプ値RDB_TYPE_LIST、値を0x4の次に長、4バイトのキーワード列を表し、次に0x4のリストは、4つのメンバーがあることを示し、次いで4つのシリアルフォーマット整形部材を順次の。

ときデシリアライズ:

  1. 第1のオブジェクトリストを与えるためのフォローアップとして、RDB_TYPE_LIST得られるバイトを読み出し、
  2. 、0x4のの鍵長を読む4バイトを与えるために、「キー2」を読んで
  3. 長0x4のを読んで、リストメンバーの数を与えるために4
  4. オブジェクトリストの再構築を完了するために、4サイクルの長さを読み、整数値を読み取ります。

  格納されたデータ型に対応するのRedisのRDB_TYPE *に加えて、のようないくつかの他のデータを表す*クラスRDB_OPCODEがある:RDB_OPCODE_EXPIRETIMEオブジェクトタイムアウトの次のデータがあることを示し、RDB_OPCODE_SELECTDBが満たされるまで、後続のデータは、DBのインデックス付けされていることを示しRDB_OPCODE_SELECTDB前次に、デシリアライズデータの全ては、辞書DBのインデックスに格納されます。Redisのは、次の種類のRDB_OPCODE *値を定義しました。

/ * 特殊RDBのオペコード(rdbSaveType / rdbLoadTypeでロード/セーブ)。* / 
の#define RDB_OPCODE_MODULE_AUX 247 / *モジュールの補助データ。* /
 の#define RDB_OPCODE_IDLE 248 / * LRUアイドル時間。* /
 の#define RDB_OPCODE_FREQ 249 / * LFU頻度。* /
 の#define RDB_OPCODE_AUX 250 / * RDBの補助フィールド。* /
 の#define RDB_OPCODE_RESIZEDB 251 / *ハッシュテーブルのサイズ変更ヒント。* /
 の#defineは、ミリ秒単位で時間を期限切れ* / 252をRDB_OPCODE_EXPIRETIME_MS。* /
 の#define RDB_OPCODE_EXPIRETIME 253 / *古いが、時間を秒単位で期限が切れます。* /
 の#define RDB_OPCODE_SELECTDB 254 / *以下のキーのDB数。* /
#define RDBファイルのRDB_OPCODE_EOF 255 / *終了。* /

RDB_OPCODE_EXPIRETIMEが発現タイムアウト時間を32ビットよう後続値のこれらの特定のタイプの長さは、通常、固定されているSであり; RDB_OPCODE_EXPIRETIME_MS背後ミリ秒の単位で表さタイムアウト64ビットである。RDB_OPCODE_SELECTDBフォローは、符号化をlenのために使用されるDB指数でありますRDB_OPCODE_AUXは、いくつかのキーと値のペアを表し、これらのキー、値の文字列とintは基本タイプであるが、保存します。

  コード・バイトのマジックRDBファイルの先頭を固定することに加えて、すべてのRDBシリアル化されたデータは、正しい動作デシリアライズを取るために、後続のデータが格納されていることを示す値または上流RDB_TYPE_ * RDB_OPCODE_ *値を有します。

4. RDBのシリアル化プロセス

そのようなマジック識別子、バージョン番号、タイムスタンプなどのプリアンブル情報、の1配列

2。Dbのトラバーサル、DBの各シーケンス

   2.1シリアルRDB_OPCODE_SELETCTDB

   2.2シリアライゼーションRDB_OPCODE_RESIZEDB、DBの記憶サイズ

   2.3デシベルでのキーと値のペアの各シーケンス

       2.3.1シリアル化のタイムアウトRDB_OPCODE_EXPIRETIME

       2.3.2 LRUシリアル化された値は、RDB_OPCODE_IDLE

       2.3.3 LFUシリアル化された値は、RDB_OPCODE_FREQ

       2.3.4シリアル化された値の型

       2.3.5直列化キー(文字列)

       2.3.6逐次化値

リオRedisのは、先のリオへのインタフェースとしてリオシリアライゼーションにある最初のファイルの抽象化層を導入したファイルのコンテンツシーケンスに出力することができる、出力シーケンスは、コンテンツにあってもよいです複数のソケットインチ ソケットへの出力対象として永続的なファイルを使用して、マスター・スレーブ同期データの一般的な操作は、シリアル化された根本的なIOをデカップリングするリオを抽象化することにより、出力対象として使用することができます。

  Redisのシリアライズ関数コールスタックは次のとおりです。

          

 

左、右は、ソケットの呼出関係シリアライズの出力目標である、シリアライズされたオブジェクトの出力の関係にファイルを呼び出すことです。

5. RDBデシリアライゼーションプロセス

 1。9マジックフラグバイトを読み取り、ベリファイ

サイクル2-3ステップ

2.読み取りバイトフラグRDB_TYPE_ *またはRDB_OPCODE_ *

RDB_OPCODE_ *またはRDB_TYPE_の値に応じて前記対応する処理*

第三のステップでは、この基本的なint型または文字列を読み取ることが必要な場合、プロセスは次のとおりです。

  1. rdbLoadLenを呼び出して長さを読んで
  2. rdbLoadLenに従って読み戻り値文字列または整数値

対応するタイプは、リストのような複合型である場合、等を設定し、プロセスは次のとおりです。

  1. コールrdbLoadLenは、複合型のメンバーの数を読んで
  2. 指定された値の数が読み出されるまでのサイクルは、メンバーシップ値を読み取ります。すなわち、読み出し動作は、会員または実質的に文字列型intを読み込みます。

デシリアライズ入力ファイルは、出力先がシリアルソケットであっても、受信側は、最初のデータファイルに格納され、ファイルがデシリアライズ。コールスタックは、直列化復元されます

  1. rdbLoad、リオの初期化ファイルストリーム
  2. 入力としてリオrdbLoadRioは、ファイルからデータを読み出すと、逆シリアル化が完了します。

6.デーモン

 Redisのシングルスレッドモードので、それ以外のプロセスが要求の持続性への応答を停止し、子供に対して実行永続性操作を選択します。

  フォーク機能メモリの内容の後に作成された子プロセスの特性に応じて、この時点でDBの完全な内容を取得するためにフォーク関数呼び出し後に子プロセスがので、同じ親を持ちます。書き込み操作が発生した場合にのみ、コピーオンライト特性は、メモリコピーの多くはつまり、操作は非常に時間がかかることはありません、コピーのコピーのためにのみ対応するページメモリ、発生しません。

  しかし、対応する親プロセスは、クライアントの注文を受け付けると、子プロセスには反応しないメモリの内容を変更するので、失われる過程で生じる持続的な変更をRDBし続けています。

おすすめ

転載: www.cnblogs.com/yang-zd/p/11627779.html