文字列、リスト、ハッシュ、コレクション、順序集合 - ソースコード解析は、(5)のRedis

オブジェクト

Redisのは、カプセル化されているredisObjectへのすべてのオブジェクトのために使用されます。

typedef struct redisObject {

    // 对象类型
    unsigned type:4;

    // 编码
    unsigned encoding:4;

    // 对象最后一次被访问的时间
    unsigned lru:REDIS_LRU_BITS; /* lru time (relative to server.lruclock) */

    // 引用计数
    int refcount;

    // 指向实际值的指针
    void *ptr;

} robj;

二つのパラメータにレッツ・フォーカス

和エンコーディングを入力します。

/* Object types */
// 对象类型
#define REDIS_STRING 0
#define REDIS_LIST 1
#define REDIS_SET 2
#define REDIS_ZSET 3
#define REDIS_HASH 4
/* Objects encoding. Some kind of objects like Strings and Hashes can be
 * internally represented in multiple ways. The 'encoding' field of the object
 * is set to one of this fields for this object. */
// 对象编码
#define REDIS_ENCODING_RAW 0     /* Raw representation */
#define REDIS_ENCODING_INT 1     /* Encoded as integer */
#define REDIS_ENCODING_HT 2      /* Encoded as hash table */
#define REDIS_ENCODING_ZIPMAP 3  /* Encoded as zipmap */
#define REDIS_ENCODING_LINKEDLIST 4 /* Encoded as regular linked list */
#define REDIS_ENCODING_ZIPLIST 5 /* Encoded as ziplist */
#define REDIS_ENCODING_INTSET 6  /* E  dncoded as intset */
#define REDIS_ENCODING_SKIPLIST 7  /* Encoded as skiplist */
#define REDIS_ENCODING_EMBSTR 8  /* Embedded sds string encoding */

私たちは、このコードで見ることができるようにサポートRedisのデータ型は次の通りです:

type	类型
REDIS_STRING	字符串
REDIS_LIST	列表
REDIS_SET	集合
REDIS_ZSET	有序集合
REDIS_HASH	哈希表

Redisの特定の基になるデータによってオブジェクトptrが。データの基礎となるのRedis:

编码	类型
REDIS_ENCODING_RAW	SDS 实现的动态字符串对象
REDIS_ENCODING_INT	整数实现的动态字符串对象
REDIS_ENCODING_HT	字典实现的 hash 对象
REDIS_ENCODING_ZIPMAP	压缩map实现对对象,(3.0)版本未使用
REDIS_ENCODING_LINKEDLIST	双向链表实现的对象
REDIS_ENCODING_ZIPLIST	压缩列表实现的对象
REDIS_ENCODING_INTSET	整数集合实现的对象
REDIS_ENCODING_SKIPLIST	跳跃表实现的对象
REDIS_ENCODING_EMBSTR	使用 embstr 实现的动态字符串的对象

PS:以下はRAWとEMBSTRの違いを説明します。

Redisのは、私がオーダーの種類に応じて異なるオブジェクトタイプを達成するための基礎となるデータ構造の使用を見てどのようです。

REDIS_STRING(文字列)

Redisの文字列、主にint型、生データと実装の基礎となるemstr。Redisのは、基礎となるデータ構造の使用の使用を決定するために、以下の原則に従ってください。

  • データを長くしてもよい整数で表される場合、それはPTRの種類を設定するために直接使用される長さです。RedisObjectエンコーディングはREDIS_ENCODING_INTに設定されています。
  • それは文字列の場合、それは文字列のバイト数を調べる必要があります。数が39バイト未満の場合REDIS_ENCODING_EMBSTRの使用にエンコードする、emstrを使用することで、下はまだ私達の前の記事をSDSています。
  • 文字列は、それは生の39の使用を超えている場合は、エンコーディングはREDIS_ENCODING_RAWです。

質問は次のとおりです。

  1. 39文字のはなぜですか?
    私たちは、StringオブジェクトはRedisObjectとsdshdrで構成されています。だから我々は、64ビットシステム、emstrの最大占有64biteに次の式を有します。
    RedisObject(16B)+ SDSヘッダ( 8B)+ emstr + "\ 0"(1B)<= 64
    簡単な四則emstr <= 39。
  2. 39それは常にされていますか?
    時間の3.2バージョンでは、著者のsdshdrは44に39から修正されました。なぜ?
    私たちが言う前に3.2がlen前sdshdrは、井戸BUFなど自由lenの3つのパラメータを、含まれており、データ型はunsigned int型の自由です。上記式SDSヘッダは8バイトである理由です。sdshdrの新バージョンがsdshdr8、sdshdr16とsdshdr32そこsdshdr64なります。最適化の場所は、小さなBUF場合、lenを記述するためのデータ型の少ないビット数を使用してフリーチャーフラグを添加しながら、メモリのそれらの量を減らすことです。emstr最小sdshdr8を使用しています。この時間は、SDSヘッダなる(LEN(1B)+フリー( 1B)+フラグ(1B))3 5バイト未満以前の実装よりバイト。だから、新しいバージョンemstr最大バイトが44になりました。再びRedisのメモリは、実際には「気を取られます」
  3. SDSは動的である、なぜemstr生を区別する必要がありますか?
    違いは、生生産は、そこに二段階の操作であること、及びredisObject sdshdrを生成するときです。生成しredisObjectのsdshdrながら、emstrを形成します。それは効率的にあります。またemstrは不変であることに注意。
  4. それらの間の関係は何ですか?
    データは長いで表現することができない場合は、ダブルまたはemstrは、生を保存するために使用されます。
    これら三つの条件に応じてRedisのルーチンは発生手段を変更します、基になるデータで満たされています。REDIS_ENCODING_INTデータは整数でない場合、それは生になるかemstrます。emstrの変更は、生となります。

REDIS_LISTリスト

レイズリストまたは底がziplist LinkedListのです。

オブジェクトのリストの長さが格納されている場合、文字列要素が64バイト未満です。
512記憶されている要素の数よりも少ないです。
両方の条件が2つの条件のいずれかが満たされない場合、コーディングziplistを用いて満たされ、ziplistはLinkedListのなります。

3.2クイックは、保存した後。これは、このデータ構造の前に説明されていません。

実際、クイックは、組み合わせのziplistと二重リンクリストの製品です。私たちは、このことを理解し、各ノードは、二重リンクリストziplistです。このような設計はトレードオフの空間と時間、あるいは妥協案との間にあるべき理由。私は内部の将来の記事で特定の実装を分析します。

REDIS_SET(コレクション)

これは、RedisのをINTSETまたは辞書(ハッシュテーブル)の基礎となるのコレクションです。

これは理解しやすいです。

あなたはINTSET使用する場合場合は整数の集合は、512を超えるではありません。
残りは辞書使用されています。
コレクションのすべての主要な要素が辞書のときの辞書を使用して、対応する値はnullです。

REDIS_ZSET(順序集合)

Redisのはziplistが達成skiplistコレクションまたは使用することを命じました。

128個の未満の要素
少ない64バイト以上の長さの要素ごと。
同時に満たすにはziplistを使用して上記の条件は、そうでない場合skiplistを使用しています。

ziplistを達成するために、隣接する2つのストアドたオブジェクトおよびオブジェクトの順序係数を用いてエンティティのRedis。したがって、挿入とクエリの複雑さはO(N)です。ダイレクト図:
[鎖が失敗画像ダンプ、ソース局は、(直接アップロード(IMG-oaNn00zx-1573628572107)下方画像を保存することが推奨され、セキュリティ・チェーン機構を有することができるメディア/ 15663772797131 / 15663782632938.jpg)]

開発エンジニア、その給与因子の一種の要素。(まあ、PHPは、世界最高の言語です)。

skiplistの実現に向けて:

typedef struct zset{

    zskiplist *zsl;
    
    dict *dict

}zset;

skiplistの整然としたリストはちょうどのみskiplistと同様に、配列決定における重要な要因と辞書ストレージオブジェクトのマッピングではありません、これはO(1)の程度を担当する時間に応じたときにキー問い合わせていることを確認することです。同じ時間順序でskiplistメンテナンスを依存しています。あなたは私の前のチュートリアルで見ることができます。ダイレクトプラグインので:

ここに画像を挿入説明

REDIS_HASH(ハッシュ表)

Redisのハッシュテーブルとziplist辞書の実装を使用しています。

キーとキーと値のペアは、64バイト未満である
未満512のキー番号を。
すべての回でそれ以外の辞書を使用し、使用ziplistを満たすことができます。

ZSETの実装に似同様ziplist実装、。2つのエンティティペア。ストレージ・キー、別のストレージvelue。

ziplist
又は上記図の使用を介して使用することができます。この時間は、エンティティを注文ません。キーは、ジョブ・タイトル、velue対応する給与です。(まあ、PHPは、世界最高の言語です)。達成ZSETクエリとの間の差はO(N)であり、尾部は、ラインのバックはO(1)の時間複雑さに直接挿入されるまで挿入されます。

ハッシュテーブルを実装するために辞書を使用してください。より多くの何も言わないする場合。

INT参照カウント(参照カウンタ)

このパラメータは参照カウントです。参照カウント - 私たちは、最も単純なメモリ管理を使用して、独自のメモリ管理をRedisの。

オブジェクトカウンタ1を作成する場合
、それぞれがローカル基準カウンタプラス
逆参照当たり、カウンタはデクリメント
到達がゼロカウンタを、そのオブジェクトを配置する必要がないことを意味します。メモリはRedisの回収されます。

符号なしLRU:REDIS_LRU_BITS

このパラメータは、最後のアクティブなオブジェクトの時間を記録します。

Redisのは制圧戦略、LRUと引数が便利に来た道のうちを有効にした場合。Redisのは、最も古いオブジェクトが優先順位を回復しLRUます。

公開された257元の記事 ウォンの賞賛223 ビュー320 000 +

おすすめ

転載: blog.csdn.net/csdn_kou/article/details/103049508