02、Hash数据类型

01、操作

02、Hash与String的主要区别?

1、把所有相关的值聚集到一个key中,节省内存空间

2、只使用一个key,减少key冲突

3、当需要批量获取值的时候,只需要使用一个命令,减少内存/IO/CPU的消耗

03、操作命令

hset key1 f 6

hset key1 e 7

hmset key1 a 5 b 4 c 3

hget key1 f

hmget key1 a b c

hkeys key1

hvals key1

hgetall key1

hget key1

hdel key1

hlen key1

04、存储(实现)原理

Hash本身也是一个KV的结构,类似于Java中的HashMap。

外层的哈希(RedisKV的实现)只用到了hashtable。当存储hash数据类型时,我们把它叫做内层的哈希

内层的哈希底层可以使用两种数据结构实现:

 ziplist:OBJ_ENCODING_ZIPLIST(压缩列表)

hashtable:OBJ_ENCODING_HT(哈希表)

05、 ziplist

【1】、ziplist压缩列表

ziplist是特殊编码的双向链表,它不存储指向上一个链表节点和指向下一个链表节点的指针,而是存储上一个节点长度和当前节点长度,通过牺牲部分读写性能,来换取高效的内存空间利用率,是一种时间换空间的思想。只用在字段个数少,字段值小的场景里面。

【2】、ziplist的内部结构

 

【3】、什么时候使用ziplist存储?

1、所有的键值对的健和值的字符串长度都小于等于64byte

2、哈希对象保存的键值对数量小于512个。

 【4】、什么时候成为hashtable

一个哈希对象超过配置的阈值(键和值的长度有>64byte,键值对个数>512个)时,会转换成哈希表(hashtable)。

 06、hashtable(dict)

hashtable被称为字典(dictionary),它是一个数组+链表的结构。

【1】、代码结构

dictEntry的多层的封装

dictEntry放到了dictht(hashtable里面):如下

ht放到了dict里面:如下

 从最底层到最高层dictEntry——dictht——dict——OBJ_ENCODING_HT

 【2】、哈希的存储结构

【3】、为什么要定义两个哈希表呢?ht[2]

redis的hash默认使用的是ht[0],ht[1]不会初始化和分配空间。

哈希表dictht是用链地址法来解决碰撞问题的。哈希表的性能取决于它的大小(size属性)和它所保存的节点的数量(used属性)之间的比率:

  • 比率在1:1时(一个哈希表ht只存储一个节点entry),哈希表的性能最好;
  • 如果节点数量比哈希表的大小要大很多的话(这个比例用ratio表示,5表示平均一个ht存储5个entry),那么哈希表就会退化成多个链表,哈希表本身的性能优势就不再存在。

在这种情况下需要扩容。Redis里面的这种操作叫做rehash。

1、rehash的步骤:

  1. 为字符ht[1]哈希表分配空间,这个哈希表的空间大小取决于要执行的操作,以及ht[0]当前包含的键值对的数量。扩展:ht[1]的大小为第一个大于等于ht[0].used*2。
  2. 将所有的ht[0]上的节点rehash到ht[1]上,重新计算hash值和索引,然后放入指定的位置。
  3. 当ht[0]全部迁移到了ht[1]之后,释放ht[0]的空间,将ht[1]设置为ht[0]表,并创建新的ht[1],为下次rehash做准备。

2、什么时候触发扩容?

  • ratio=used/size,已使用节点与字典大小的比例
  • dict_can_resize为1并且dict_force_resize_ratio已使用节点数和字典大小之间的比率超过1:5,触发扩容 

06、应用场景

比String节省了更多key的空间,也更加便于集中管理。

购物车

key:用户id;field:商品id;value:商品数量。

+1:hincr。-1:hdecr。删除:hdel。全选:hgetall。商品数:hlen。

07、细节可参考

https://blog.youkuaiyun.com/qiezikuaichuan/article/details/46574301

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值