原 荐 Redis 哈希结构内存模型剖析

栏目: 数据库 · 发布时间: 7年前

内容简介:本文共 1231字,阅读大约需要 5分钟 !在前文

原 荐  <a href='https://www.codercto.com/topics/18994.html'>Redis</a>  哈希结构内存模型剖析

本文共 1231字,阅读大约需要 5分钟 !

概述

在前文 《Redis字符串类型内部编码剖析》 之中已经剖析过 Redis 最基本 的 String类型的内部是怎么编码和存储的,本文再来阐述 Redis中使用 最为频繁 的数据类型:哈希(或称散列),在Redis内部是怎么存的。

  • 实验源码环境:Redis 4.0.10

注:本文首发于 My Personal Blog ,欢迎光临 小站

本文内容脑图如下:

原 荐 Redis 哈希结构内存模型剖析

哈希类型内部编码详情

对于 Redis的常用 5 种数据类型(String、Hash、List、Set、sorted set),每种数据类型都提供了 最少两种 内部的编码格式,而且每个数据类型内部编码方式的选择 对用户是完全透明的 ,Redis会根据数据量自适应地选择较优化的内部编码格式。

如果想查看某个键的内部编码格式,可以使用 OBJECT ENCODING keyname 指令来进行,比如:

127.0.0.1:6379> 
127.0.0.1:6379> set foo bar
OK
127.0.0.1:6379> 
127.0.0.1:6379> object encoding foo  // 查看某个Redis键值的编码
"embstr"
127.0.0.1:6379> 
127.0.0.1:6379>

对于使用最为频繁的 Hash类型,其内部编码方式可能有两种:

  • OBJ_ENCODING_ZIPLIST (压缩列表)
  • OBJ_ENCODING_HT (哈希表)

Redis 会根据 数据量 的情况来 自适应 地选择这两种编码方式中 较优 的一种,而这一切对用户完全透明。

数据条目较少数据值较小 的时候 Redis会采用 压缩列表 (OBJ_ENCODING_ZIPLIST)编码方式进行存储。这里成员"较少",成员值"较小"的标准可以通过如下配置项进行配置:

hash-max-ziplist-entries 512
hash-max-ziplist-value 64

Redis 默认给出了默认值,当然用户可根据实际情况自行配置。

Hash类型键的字段个数 < hash-max-ziplist-entries 并且 每个字段名和字段值的长度 < hash-max-ziplist-value 时,Redis 会使用 OBJ_ENCODING_ZIPLIST来存储该键,反之则会转换为 OBJ_ENCODING_HT的编码方式。

口说无凭,我们不妨先来做个实验感受一下吧:

原 荐 Redis 哈希结构内存模型剖析

很明显该实验验证了当 字段值长度大于64 时,编码格式会由 ZIPLIST方式切换为 Hashtable方式。

源码之前,了无秘密,我们再来看一下Redis关于这部分切换的源码实现,那就理解得更加清楚了:

原 荐 Redis 哈希结构内存模型剖析

原 荐 Redis 哈希结构内存模型剖析

下面详解 OBJ_ENCODING_ZIPLISTOBJ_ENCODING_HT 这两种编码格式的内部存储模型,知道了其各自特点和优缺点,自然也就明白了Redis内部使用它们的意图。

OBJ_ENCODING_ZIPLIST 编码

Ziplist 压缩列表是一种紧凑编码格式,总体思想是 时间换空间 ,即以部分读写性能为代价,来换取极高的内存空间利用率,因此只会用于 字段个数少 ,且 字段值也较小 的场景。

压缩列表内存利用率极高的原因与其连续内存的特性是分不开的,其典型的内存结构可以用下图形象地展示出来:

原 荐 Redis 哈希结构内存模型剖析

所以如果用 Ziplist来存储 Redis的散列类型的话,元素的排列方式就变成了如下图所示的形象示意图:即key和value都是逻辑连续内存:

原 荐 Redis 哈希结构内存模型剖析

OBJ_ENCODING_HT 编码

OBJ_ENCODING_HT 这种编码方式内部才是真正的哈希表结构,或称为字典结构,其可以实现O(1)复杂度的读写操作,因此效率很高。

在 Redis内部,从 OBJ_ENCODING_HT类型到底层真正的散列表数据结构是一层层嵌套下去的,关系如下:

原 荐 Redis 哈希结构内存模型剖析

这一关系我们可以从 Redis哈希表定义部分的源码来看出:

原 荐 Redis 哈希结构内存模型剖析

下面来详解一下各个部分:

  • 关于哈希节点(dictEntry)

原 荐 Redis 哈希结构内存模型剖析

  • 关于哈希表(dictht)和字典(dict)

原 荐 Redis 哈希结构内存模型剖析

  • 关于dictType

原 荐 Redis 哈希结构内存模型剖析

  • Redis如何计算Hash值

Redis计算Hash的源代码如下:

原 荐 Redis 哈希结构内存模型剖析

这是一个 C语言 宏定义,其实幕后真正承担 Hash值计算的是上面介绍的 dictType 结构体中的函数指针 hashFunction

而该 hashFunction 函数指针在初始化时会对应被赋值为一个个真实的计算 Hash值的实际函数,就像下面这样:

原 荐 Redis 哈希结构内存模型剖析

  • Redis如何计算存取索引Index值

Index值的计算依赖于上面计算得出的 Hash值,代码如下:

原 荐 Redis 哈希结构内存模型剖析

到此,还有一个 一直非常值得关注的细节 :即字典 dict里总是保存有两个 Hash表结构 ht[2] ,以及与其高度相关的 rehash操作 ,这在下一篇文章里详解。

后 记

由于能力有限,若有错误或者不当之处,还请大家批评指正,一起学习交流!


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Cascading Style Sheets 2.0 Programmer's Reference

Cascading Style Sheets 2.0 Programmer's Reference

Eric A. Meyer / McGraw-Hill Osborne Media / 2001-03-20 / USD 19.99

The most authoritative quick reference available for CSS programmers. This handy resource gives you programming essentials at your fingertips, including all the new tags and features in CSS 2.0. You'l......一起来看看 《Cascading Style Sheets 2.0 Programmer's Reference》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

随机密码生成器
随机密码生成器

多种字符组合密码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具