当前位置:   article > 正文

Redis学习小计(6) - 基本数据类型:哈希(hash)_redis hash size

redis hash size

Redis基本数据类型:哈希(hash)

  Redis内部使用两种结构来实现hash

  • 压缩列表(ziplist)
  • 哈希表(hashtable)

1. 压缩列表(ziplist)

  Redis每次创建哈希类型的时候,都会先使用默认ziplist。
  使用这种结构时,redisObject.encoding = OBJ_ENCODING_ZIPLIST

robj *createHashObject(void) {
    unsigned char *zl = ziplistNew();
    robj *o = createObject(OBJ_HASH, zl);
    o->encoding = OBJ_ENCODING_ZIPLIST;
    return o;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

  当ziplist不满足下面条件时,会自动转成哈希表

hash-max-ziplist-entries 512

hash-max-ziplist-value 64


2. 哈希表(hashtable)

  使用这种结构时,redisObject.encoding = OBJ_ENCODING_HT
  先来简单介绍下hashtable用到的结构:


  dict struct

typedef struct dict {
  dictType *type;
  void *privdata;
  dictht ht[2];
  long rehashidx;
  unsigned long iterators;
} dict;

  • ht[2] - 默认建立两个hashtable,正常时都使用ht[0],当需要移动hashtable时,会逐个把ht[0]里面的节点拷贝到ht[1]。如果此时有更新操作,也会直接对ht[1]进行修改。当ht[0]全部移动到ht[1]里面后,将两个hashtable进行切换
  • rehashidx - 移动hashtable标识,-1表示没有发生移动
ht = dictIsRehashing(d) ? &d->ht[1] : &d->ht[0];
  • 1

  dictht struct

typedef struct dictht {
  dictEntry **table;
  unsigned long size;
  unsigned long sizemask;
  unsigned long used;
} dictht;

  • table - 字典数组,记录每个节点信息,初始化为NULL
  • size - 字典数组的大小,初始化为0
  • sizemask - size-1,初始化为0
  • used - 字典数组已经使用的个数,初始化为0
static void _dictReset(dictht *ht)
{
    ht->table = NULL;
    ht->size = 0;
    ht->sizemask = 0;
    ht->used = 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

当插入节点大于空闲节点数时(size-used),就会对hashtable进行扩容,大概的步骤:

  1. 创建一个新的hashtable,size是原来的2倍(如果原来的size是0,会使用默认大小4)
  2. 将字典的ht[1]替换为新创建的hashtable
  3. 将ht[0]里面的节点移动到ht[1]
  4. 移动完成,切换ht[1]到ht[0]

  dictEntry struct

typedef struct dictEntry {
  void *key;
  union {
     void *val;
     uint64_t u64;
     int64_t s64;
     double d;
  } v;
  struct dictEntry *next;
} dictEntry;

  • key - 节点索引
  • val - 节点值
  • next - 指向下一个节点的指针,当索引相同时,使用“拉链法”处理冲突

3. command

  • HDEL - Delete one or more hash fields
  • HEXISTS - Determine if a hash field exists
  • HGET - Get the value of a hash field
  • HGETALL - Get all the fields and values in a hash
  • HINCRBY - Increment the integer value of a hash field by the given number
  • HINCRBYFLOAT - Increment the float value of a hash field by the given amount
  • HKEYS - Get all the fields in a hash
  • HLEN - Get the number of fields in a hash
  • HMGET - Get the values of all the given hash fields
  • HMSET - Set multiple hash fields to multiple values
  • HSCAN - Incrementally iterate hash fields and associated values
  • HSET - Set the string value of a hash field
  • HSETNX - Set the value of a hash field, only if the field does not exist
  • HSTRLEN - Get the length of the value of a hash field
  • HVALS - Get all the values in a hash

上一篇:Redis学习小计(5) - 基本数据类型:列表(list)
下一篇:Redis学习小计(7) - 基本数据类型:集合(set)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/代码探险家/article/detail/800920
推荐阅读
相关标签
  

闽ICP备14008679号