序文
私たちはKVのRedisのデータベースを設定すると、KVは、格納されましたか?私たちは、いつ、出てどこから入手する場合。時間の複雑さ、スペースの複雑さなど、およびその問題の範囲を最適化する方法。
Serverデータベース
Redisのサーバーのすべてのデータベース情報がredis.h ## redisService構造体に格納されています。コードは以下の通りであります:
1 構造体redisServer { 2 。3 // ... 。4 。5 / * 一般* / 6 7。 // 設定ファイルの絶対パス 8。 CHAR *たconfigfile; / * 絶対configファイルパス、またはNULL * / 9。 10 // データベース 11。 redisDb DB *; 12は 13である // パスワードであるか 14 のchar * requirepass; / * AUTHコマンドのパス、またはNULL * / 15 16 // PIDファイル 17 のchar * PidFileオプション。 / * PIDファイルのパス* / 18 19 // TCPポートを聞く 20 INTポート; / * TCPリスニングポート* / 21 22 // ... 23 24 }
列の数は、私がもっと重要だと思います。最も重要なのは、確かに一つのredisDb *デシベル、このデータ構造を格納し、私たちのすべてのデータ。
Redisのは、キー値ペア(キーと値のペア)のデータベース・サーバであり、各データベースの構成要素は redis.h/redisDb
、構造 redisDb
の構造 dict
辞書データベースは、右内のすべてのキーを保持し、我々は辞書キー空間として知られるであろう(スペースキー)。コードは以下の通りであります:
/ * Redisのデータベース表現。識別される複数のデータベースがあり 、最大構成さまで0からの整数(デフォルトのデータベース)によって* ザ・が「ID」での構造体のフィールドで、データベースの*データベース。番号。* / typedefの構造体redisDb { // スペースキーデータベースは、データベースがすべての鍵を保持 辞書の*の辞書を; / * このDBのための鍵空間で* / // 有効期限キー、キーが辞書の鍵となり、辞書には、期限切れのイベントUNIXタイムスタンプである *辞書有効期限; / * タイムアウトにSETとキーのタイムアウト* / // キーをブロックされた状態にある のdict * blocking_keys; / * データ(BLPOP)を待っているクライアントでのキー* / //キーブロックを解除 辞書を* ready_keys; / * ブロックされた受信キーPUSH * / // され、監視WATCHコマンドキーで 辞書が* watched_keys; / * MULTI / EXECのCASのために新加入ランキングキー* / 構造体 evictionPoolEntry * eviction_pool; / * プールの立ち退きのキー* / // データベース番号 ; int型のID / * データベースID * / // 平均TTL鍵データベース、統計ロングロング avg_ttl; / * 平均TTL、ジャスト統計用* / } redisDb。
最も重要なことはある * dictの辞書;彼は辞書です、あなたは(https://www.cnblogs.com/wenbochang/p/11673590.html)の1の前に私の記事を見ることができ、小さなパートナーを理解していない、ためにRedisのは、詳細な説明を辞書。
dictの私たちの本当のデータストレージ。
データベースを直接対応するユーザから見たキーとスペース:
- キーは、キーのスペースキーデータベースであり、各キーは、文字列オブジェクトです。
- 鍵空間の値がデータベースの値であり、各値は、文字列、リスト、ハッシュテーブル、オブジェクト、オブジェクトのコレクションも、あらゆるRedisのオブジェクトを含むオブジェクトのコレクションを、注文することができます。
など、データベースへのキーと値のペアを追加すること、またはキー値ペアにデータベースから削除、またはデータベース内のキーと値のペアを取得するよう-キー空間データベースは、データベースに対するので、すべての操作辞書であるので、実際に達成するための鍵空間辞書の操作によって行われています。だから、基本的には、明白な複雑さO(1)レベルであり、これは非常に速くRedisのできる重要な理由です。
債券の価値
キー値のデータベースは、実際には、鍵空間におけるターゲット鍵に対応する値をとります。コードは以下の通りであります:
1 / * 2 *は、辞書に含まれるキーのノード鍵戻り 3 * 4 *リターンノード見出され、見つからない戻るヌル 。5 * 6 * T = O(1) 。7 * / 8 dictEntry * dictFind(辞書Dが*、CONST 空隙 * キー) 9 { 10 dictEntry * 彼の、 図11 の符号なし整数H、IDX、テーブル、 12は 13であり、 // 辞書(ハッシュ・テーブル)空 14 IF(D-> HT [ 0 ] .size == 0)リターン NULL ; / * 我々は、すべてのテーブルに持っています* / 15は、 16 // 条件が許すならば、単一のステップで焼き直し 17。 IF (dictIsRehashing(D))_dictRehashStep(D) 18である 19。 // キーのハッシュ値を計算 で20 H = dictHashKey(D、KEY); 21であるが / / 辞書ボタン内のルックアップハッシュテーブル 22は、 // T O =(1) 23れる ため(表= 0 ;表<= 1 ;表++ ){ 24 25 // 指標値算出 26は、 IDX = H&D-> HT [表] .sizemask; 27 28 // キー見て、指定されたインデックス上のすべてのノードにリストをトラバース 29 彼= D-のを>HT [表] .table [IDX]; 30 // (1)T O = 31である 一方で(彼の){ 32 33である IF(dictCompareKeys(D、キー、HE-> キー)) 34が 戻り、彼の、 35 36 の彼の彼は= - > 次; 37 } 38 39 // プログラムは0ハッシュテーブルを横断した場合は、まだ指定されたノードのキーが見つかりませんでした 40 // プログラムは、焼き直しの際に辞書かどうかをチェックします 41 // 直接返すことを決定する前にNULL、またはハッシュテーブルルックアップ号続行 42れる IF(!dictIsRehashing(D))のリターン; NULL 43である } 44である 45 //本明細書に記載の2つのハッシュテーブル見つからなかった場合 46である リターンNULL; 47 }
コードを見て、実際には非常に簡単です。
- まず、辞書が空であるかどうかを判断する、空の場合は、直接のリターンはnullを継続する必要はありません
- 第二の工程、焼き直し、第1のプログレッシブタイプの焼き直しを行う場合。(私は、ブログの記事になって、理解していません)
- ハッシュキー値を算出する第3の工程。
- HTを見つけるための第四工程、[0]、HT、[1] 2つのテーブルのテーブル。これはリストのであればどこに、あなたは、whileループを探すことができます。
- リターンを検索、nullを返し見つけることができませんでした。非常に単純明快ロジック。
- 図は次のよう:
見た目に似て、追加、削除、更新する債券、。私はソースを表示されません。
言葉の後
データベースが読み取りとRedisのコマンドを使用して書き込むようにすると、サーバーは、読み取り操作と書き込み指定された鍵空間を行うだけでなく、その他にもいくつかのメンテナンス操作を実行します、を含みます:
- 単一のキーを(読みキーであることを読み取り操作と書き込み)読んだ後、サーバは、キーに基づいて行われますが存在し、サーバースペースキーヒット(ヒット)またはキースペースミス(ミス)の数の数を更新するためにこれら2つの値が可能 のINFO statsコマンド
keyspace_hits
プロパティおよびkeyspace_misses
ビュープロパティ。
- キーを読んだ後、鍵サーバは、コマンド使用して、この値が計算されたアイドル時間を結合するために使用することができ、LRU(最後に使用)に更新されて 表示するアイドル時間のOBJECT <キー>キーコマンドを
key
アイドル時間を。
- サーバーがキーを読み取る際に場合は、キーの有効期限が切れていることが判明し、サーバはまず、期限切れのキーを削除します他の操作の残りの部分の実装前に。
- 使用しているクライアントがある場合は 、特定のキーを監視するために、WATCHコマンドを、キーの後にサーバーが変更を加えるために監視されているトランザクションが変更されたこのキーのプログラムのノートを取ったように、キーは、汚れ(汚い)とマークされます。
- 値がダーティであろう(ダーティ)キーカウンタが1だけインクリメントされるたびにサーバーキーを変更した後、カウンタは、持続サーバとコピー操作が行われたトリガします。