【问题标题】:The relation with redis key redisObject and redis value redisObjectredis key redisObject和redis value redisObject的关系
【发布时间】:2017-08-27 14:39:40
【问题描述】:

我知道无论redis键或redis值是redisObject
它是这样的结构

  typedef struct redisObject {
        unsigned type:4;
        unsigned encoding:4;
        unsigned lru:LRU_BITS; /* lru time (relative to server.lruclock) */
        int refcount;
        void *ptr;
    } robj;

键 redisObject.ptr 是指向键的值而不是值的值

但我想知道redis如何通过键找到值?值的 redisObject 没有 ptr。

【问题讨论】:

标签: redis


【解决方案1】:

Redis 使用 Hash table 机制来存储 key-value 以便快速检索。哈希表维护了一个桶列表,每个桶都有一个链表来存储key-value。

当你给db添加一个key时,它首先使用hash函数来计算一个索引。索引告诉 redis 哪个桶应该容纳这个键。然后redis为key创建一个entry,将该entry添加到属于这个bucket的linked-list头部,并将value的object ptr,key object的ptr保存到entry中。 该条目实际上是链表的一个元素。

所以当你想通过键找到值时,它使用哈希表来实现这一点。您可以阅读 dict.h/dict.c 以了解更多信息。


更多信息

db.c实现你想知道的操作。

  void setKey(redisDb *db, robj *key, robj *val) {
    if (lookupKeyWrite(db,key) == NULL) {
        dbAdd(db,key,val);
    } else {
        dbOverwrite(db,key,val);
    }
    incrRefCount(val);
    removeExpire(db,key);
    signalModifiedKey(db,key);
  }

但它只是一个包装函数,内部使用dbAdddbOverwrite 将密钥添加到db。

这是dbAdd,它使用dictAdd来链接key和val。

void dbAdd(redisDb *db, robj *key, robj *val) {
    sds copy = sdsdup(key->ptr);
    int retval = dictAdd(db->dict, copy, val);

    serverAssertWithInfo(NULL,key,retval == DICT_OK);
    if (val->type == OBJ_LIST) signalListAsReady(db, key);
    if (server.cluster_enabled) slotToKeyAdd(key);
 }

所以神奇的事情发生在 dict.c 中,阅读它!

【讨论】:

    最近更新 更多