redis hash 存储顺序_redis源码之hash结构的实现

Redis中的Hash数据结构在元素数量或单个元素大小超过一定阈值时,会从ziplist编码转为hashtable编码。这解释了为何使用`hgetall`时属性顺序可能发生变化。ziplist适用于小数据量和元素,而string类型虽能设置过期时间,但大量增长会导致rehash。在实际应用中,应权衡使用string和hash的优缺点。
摘要由CSDN通过智能技术生成

redis的hash的基本命令暂时先不多说,我们直接步入正文 在redis的hash结构中,存在这样一种现象

127.0.0.1:6379> hset user:001 name john age 25 sex man(integer) 3127.0.0.1:6379> hgetall user:0011) "name"2) "john"3) "age"4) "25"5) "sex"6) "man"

我们先给user:001分别设置了name,age,sex属性,然后通过hgetall获取所有属性,这一切看起来还比较正常 但是接下来

127.0.0.1:6379> hset user:002 name john age 25 sex man extra xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx(integer) 4127.0.0.1:6379> hgetall user:0021) "name"2) "john"3) "extra"4) "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"5) "sex"6) "man"7) "age"8) "25"

我们给user:002多设置了一个extra属性,并且设置的值比较大,然后用hgetall获取所有属性的时候发现返回的顺序不是按照我们设置的时候的属性的顺序了,这是为什么呢?

其实主要原因是:hash数据结构底层实现为一个字典(dict),也是redisDb用来存储k-v的数据结构,当数据量比较小,或者单个元素比较小的时候,底层用ziplist存储,数据大小和元素数量阈值可以通过如下参数设置

hash-max-ziplist-entries 512 //ziplist元素个数超过512,将改为hashtable编码 hash-max-ziplist-value 64 //单个元素大小超过64byte时,将改为hashtable编码 对于上面的例子,主要是因为单个元素大小超过了64byte,所以改为了hashtable编码,导致了hgetall获取属性的时候和设置的顺序不一样

压缩表的结构如图cd0e21840e136a16eb3b692efaee4eb6.png

其实很多同学也有一个疑问,hash和string类型到底有啥本质的区别?其实我们从源码可以看出来, 对于string类型来说,string类型是基于RedisDb的,如果string的数量不断的变多,就会导致dictht部分不断的rehashff6b677908c54b06e224a2f7079ba37e.png而对于hash类型的来说,hash不存在dictht不断rehash的问题3cb0e9c21a87367a580cf46b8a5d2956.png

但是其实也是各有利弊,比如hash就没法对某个key设置过期时间,而且redis中有一个很大的忌讳,就是不要让某个key过大,容易阻塞,所以个人还是更推荐string的方式

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值