Redisソース研究のredisObject

2959 ワード

本論文では,Redis key‐value構造における5種類のvalueをカプセル化したredisObject構造について主に説明する.
I、神の視点redisObject構造は主にvalueオブジェクトの下位符号化方式、および実際の指向などの内容を説明する.
/*src/redis.h/redisObject */
typedef struct redisObject {
    //    32 bits
    //      ,   /  /  /   
    unsigned type:4;
    //        
    unsigned notused:2; /* Not used */

    //      ,Redis       ,             
    //   :“123456789”        123456789
    unsigned encoding:4;

    //      ,         
    unsigned lru:22; /* lru time (relative to server.lruclock) */

    //     
    int refcount;

    //     ,       
    void *ptr;
} robj;  

以下、上記の属性について説明します.
II、type属性redisObjectデータ構造は、オブジェクトの属性とオブジェクトのデータを分離し、良好な特性を有し、まず属性に基づいて検査判断などの操作を行うことができ、これらはデータ自体に直接アクセスする必要はない.
typeはvalueオブジェクトのデータ型をマークします.
/* Object types */
#define REDIS_STRING 0
#define REDIS_LIST 1
#define REDIS_SET 2
#define REDIS_ZSET 3
#define REDIS_HASH 4  

III、encoding属性
Redisは最適化メモリであり、各typeタイプに対して少なくとも2つの下位実装方式があり、zsetのようにziplistとskiplistであってもよい.redisObject構造のencodingプロパティは、オブジェクトが使用する下位データ構造をマークします.
/* 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 /* Encoded as intset */
#define REDIS_ENCODING_SKIPLIST 7 /* Encoded as skiplist */    

IV、refcount属性
Redisではメモリ領域をより最適化するために,数値文字列に対して共有メモリの操作を行い,参照カウント方式で管理した.
次の関数は、参照を増やして適用を減らす操作です.
//    Redis     
void incrRefCount(robj *o) {
    o->refcount++;
 }
//    Redis     。            
void decrRefCount(robj *o) {
    if (o->refcount <= 0) redisPanic("decrRefCount against refcount <= 0");
    //             ,     
    if (o->refcount == 1) {
    //       ,      
    switch(o->type) {
        case REDIS_STRING: freeStringObject(o); break;
        case REDIS_LIST: freeListObject(o); break;
        case REDIS_SET: freeSetObject(o); break;
        case REDIS_ZSET: freeZsetObject(o); break;
        case REDIS_HASH: freeHashObject(o); break;
        default: redisPanic("Unknown object type"); break;
    }
    zfree(o);
  } else {
      o->refcount--;
  }
}  

ここでの参照カウントについては,Redisは単一スレッド動作モードであるため,参照カウントの増加と減少は原子性を保証するものに及ばない.
V、lru属性
Redisがデータセットに使用するメモリのサイズは周期的に計算され、制限を超えるとタイムアウトしたデータは淘汰されます.すなわち,淘汰の基準はoversize&overtimeである.
【参考】[1]『Redis設計と実現』[2]『Redisソースログ』