Redis 面试必备 > redis 基础数据结构
redis 基础数据结构 Hash

Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。

Redis 中每个 hash 可以存储 232 - 1 键值对(40多亿)。

哈希等价于Java语言的HashMap或者是Python语言的dict,在实现结构上它使用二维结构,第一维是数组,第二维是链表,hash的内容key和value存放在链表中,数组里存放的是链表的头指针。通过key查找元素时,先计算key的hashcode,然后用hashcode对数组的长度进行取模定位到链表的表头,再对链表进行遍历获取到相应的value值,链表的作用就是用来将产生了「hash碰撞」的元素串起来。





Redis hash 命令

下表列出了 redis hash 基本的相关命令:

序号命令及描述
1HDEL key field1 [field2]
删除一个或多个哈希表字段
2HEXISTS key field
查看哈希表 key 中,指定的字段是否存在。
3HGET key field
获取存储在哈希表中指定字段的值。
4HGETALL key
获取在哈希表中指定 key 的所有字段和值
5HINCRBY key field increment
为哈希表 key 中的指定字段的整数值加上增量 increment 。
6HINCRBYFLOAT key field increment
为哈希表 key 中的指定字段的浮点数值加上增量 increment 。
7HKEYS key
获取所有哈希表中的字段
8HLEN key
获取哈希表中字段的数量
9HMGET key field1 [field2]
获取所有给定字段的值
10HMSET key field1 value1 [field2 value2 ]
同时将多个 field-value (域-值)对设置到哈希表 key 中。
11HSET key field value
将哈希表 key 中的字段 field 的值设为 value 。
12HSETNX key field value
只有在字段 field 不存在时,设置哈希表字段的值。
13HVALS key
获取哈希表中所有值
14HSCAN key cursor [MATCH pattern] [COUNT count]
迭代哈希表中的键值对。



扩容 当hash内部的元素比较拥挤时(hash碰撞比较频繁),就需要进行扩容。扩容需要申请新的两倍大小的数组,然后将所有的键值对重新分配到新的数组下标对应的链表中(rehash)。如果hash结构很大,比如有上百万个键值对,那么一次完整rehash的过程就会耗时很长。这对于单线程的Redis里来说有点压力山大。所以Redis采用了渐进式rehash的方案。它会同时保留两个新旧hash结构,在后续的定时任务以及hash结构的读写指令中将旧结构的元素逐渐迁移到新的结构中。这样就可以避免因扩容导致的线程卡顿现象。


缩容 Redis的hash结构不但有扩容还有缩容,从这一点出发,它要比Java的HashMap要厉害一些,Java的HashMap只有扩容。缩容的原理和扩容是一致的,只不过新的数组大小要比旧数组小一倍。