专栏首页golang+phpredis源码之hash结构的实现

redis源码之hash结构的实现

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

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获取所有属性,这一切看起来还比较正常 但是接下来

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的方式

本文分享自微信公众号 - 程序员养成日记(programmer_grow),作者:redis

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-10-04

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • redis的两种持久化的机制,你真的了解么?

    AOF(Append-Only File):指所有的命令行记录以redis命令请求协议的格式完全持久化存储保存为AOF文件

    程序员养成日记
  • redis不小心清空了数据库(flushall),只能跑路吗?

    一名程序员因为对公司不满,删除了公司的数据库,后来被判7年,这也给咱们程序员敲响了一记警钟,无论发生什么,这种做法都是非常不妥当的,不光是职业道德的问题,而且还...

    程序员养成日记
  • redis的持久化

    Redis借助了fork命令的copy on write机制。在生成快照时,将当前进程fork出一个子进程,然后在子进程中循环所有的数据,将数据写成为RDB文件...

    程序员养成日记
  • MONGODB 加索引 大内存 与连锁思维

    创建MONGODB 的索引,属于基本操作,但如果是一个有2T 的 collection 要加一个索引,也属于基本操作,实际上量变产生质变,很多问题的考虑都不在那...

    AustinDatabases
  • Mysql性能优化

     1. 优化SQL   1)通过show status了解各种sql的执行频率         show status like 'Com_%' ...

    大闲人柴毛毛
  • 数据库创建索引的条件和注意事项

    索引可以分为聚簇索引和非聚簇索引。聚簇索引通过树形结构重排表中的数据来提高数据的访问速度,非聚簇索引则通过维护表中的数据指针来提高数据的索引。

    Steve Wang
  • MySQL开发规范

    1)    使用InnoDB存储引擎 2)    数据库字符集使用UTF8,校对字符集使用utf8_general_ci 3)    所有表、字段都尽量添加注释...

    动力节点Java学院
  • 腾讯面试:一条SQL语句执行得很慢的原因有哪些?

    说实话,这个问题可以涉及到 MySQL 的很多核心知识,可以扯出一大堆,就像要考你计算机网络的知识时,问你“输入URL回车之后,究竟发生了什么”一样,看看你能说...

    小云
  • MySQL 索引知识点总结

    ? 作者:fanili,腾讯 WXG 后台开发工程师 知其然知其所以然!本文介绍索引的数据结构、查找算法、常见的索引概念和索引失效场景。 什么是索引? 在关系...

    腾讯技术工程官方号
  • mysql常见的面试回答

    innodb这种原生的数据文件就是索引文件的组织结构,这种默认的主键索引为聚簇索引。就是因为这个原因,innodb表要求必须有主键的,但是myisam表不要求必...

    技术从心

扫码关注云+社区

领取腾讯云代金券