前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >redis源码之hash结构的实现

redis源码之hash结构的实现

作者头像
程序员小饭
发布2020-10-14 10:59:25
5020
发布2020-10-14 10:59:25
举报
文章被收录于专栏:golang+phpgolang+php

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

代码语言:javascript
复制
127.0.0.1:6379> hset user:001 name john age 25 sex man
(integer) 3
127.0.0.1:6379> hgetall user:001
1) "name"
2) "john"
3) "age"
4) "25"
5) "sex"
6) "man"

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

代码语言:javascript
复制
127.0.0.1:6379> hset user:002 name john age 25 sex man extra xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
(integer) 4
127.0.0.1:6379> hgetall user:002
1) "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获取属性的时候和设置的顺序不一样

压缩表的结构如图

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

而对于hash类型的来说,hash不存在dictht不断rehash的问题

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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-10-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员养成日记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档