Redis6 数据结构Hash

前言

在Redis中,hashtable 被称为字典(dictionary),它是一个数组+链表到结构。每个键值对都会有一个dictEntry

OBJ_ENCODING_HT
这种编码夯实内部才是真正的哈希表结构,或称为字典结构,其可以实现O(1)复杂度的读写操作,因此效率很高。
在Redis内部。从OBJ_ENCODING_HT:
在这里插入图片描述

编码格式

redis6

ziplist
hashtable

ziplist

ziplist 压缩列表是一种紧凑编码格式,总体思想是花时间来(压缩,解压)获取节约空间,即以部分读写性能为代价,来换取极高的内存空间利用率,因此只会用于字段个素少,且字段值也比较小的场景。压缩类标内存利用率极高的原因与其连续内存的特性是分不开的。

ziplist为了节约内存开发的,他是由连续内存卡组成的顺序型数据结构,优点类似于数组。
zi plist是一个特殊编码的双向链表,他不存储指向前一个链表节点prev和执行下一个链表节点的指针next.
而是存储上一个节点长度和当前节点长度。通过牺牲部分读写性能,来换取高效的内存空间利用率,节约内存,是一种时间换空间的思想。

在这里插入图片描述
在这里插入图片描述

zplist 中 的zlentry

对比java hashMap中 Map.entry<K,V>
static class Node<K,v> implements Map.entry<K,V>{
final K key;
V value;
Node<K,V> next;
}
而 zap中是zlEntry
在这里插入图片描述

zipList 的存取

zlentry 属性解析

压缩列表zlentry 节点结构: 每个zlenrty由前一个节点的长度,encoding和entry-data三部分组成
在这里插入图片描述
前节点: (前节点占用的内存字节数)表示前1个zlentry的长度,privious_entry_lengthy有两种取值情况: 1字节和5字节。取值1字节时,表示上一个entry的长度小于254字节。虽然1字节的值能表示0到255,但是压缩列表中zlend到的取值默认时255,因此就默认使用255表示整个压缩列表的结束,其他表示疮毒的地方就不能使用255这个值了。所以上一个长度小于等于254字节时,pre_len取值为1字节,否则为5字节。记录长度的好处:暂用内存小,1或者5个字节

encoding:记录节点的context保存的类型和context的长度

在这里插入图片描述

zlentry 为什么要这么设计?

在这里插入图片描述

privious_entry_length,encoding长度都可以根据编码方式推算,正在变化的是context,而context长度记录在encoding里,因此entry的长度就知道了
entry的总长度= privious_entry_length字节数+encoding字节数+context字节数。

链表在内存中,一般是不连续的,遍历相对比较慢,而zipList可以很好的解决这个问题。如果知道当前的起始地址,因为entry是连续的,entry后一定是另一个entry,想知道下一个entry的地址,只要将当前的起始地址加上当前entry的总长度。如果还想知道下一个enrty,则继续上一步的操作。

在这里插入图片描述

在这里插入图片描述

结构

hash-max-ziplist-entries: 使用压缩列表保存时哈希集合中的最大元素个数
hash-max-ziplist-value: 使用压缩列表保存时哈希集合中单个元素的最大长度。

结论

1.哈希对象保存的键值对数量小于512个;
2.所有的键值对的键和值的字符串长度都小于等于64byte(一个英文字符一个字节,一个数字一个字节)
3. ziplist 升级到hash table 可以,hashtable变为ziplist不可用,在节省内存空间方面hashtable没有zi plist高效
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值