Redis之Redis 6.0中Hash(ziplist)解读

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: Redis之Redis 6.0中Hash(ziplist)解读

hash数据类型概述

Redis中hash数据类型使用了两种编码格式:ziplist(压缩列表)、hashtable(哈希表) 在redis.conf配置文件中,有以下两个参数,意思为:当节点数量小于512并且字符串的长度小于等于64时,会使用ziplist编码。

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

ziplist(压缩列表)

基本介绍

ziplist 是一个经过特殊编码的双向链表,旨在提高内存效率。 它存储字符串和整数值,其中整数被编码为实际整数而不是一系列字符。 它允许在 O(1) 时间内在列表的任一侧进行推送和弹出操作。 但是,由于每个操作都需要重新分配 ziplist 使用的内存,因此实际复杂性与 ziplist 使用的内存量有关。

ziplist 是一个特殊双向链表,不像普通的链表使用前后指针关联在一起,它是存储在连续内存上的。

结构详解

  • zlbytes: 32 位无符号整型,记录 ziplist 整个结构体的占用空间大小。当然了也包括 zlbytes 本身。这个结构有个很大的用处,就是当需要修改 ziplist 时候不需要遍历即可知道其本身的大小。
  • zltail: 32 位无符号整型, 记录整个 ziplist 中最后一个 entry 的偏移量。所以在尾部进行 POP 操作时候不需要先遍历一次。
  • zllen: 16 位无符号整型, 记录 entry 的数量, 所以只能表示 2^16。但是 Redis 作了特殊的处理:当实体数超过 2^16 ,该值被固定为 2^16 - 1。 所以这种时候要知道所有实体的数量就必须要遍历整个结构了。
  • entry: 真正存数据的结构。
  • zlend: 8 位无符号整型, 固定为 255 (0xFF)。为 ziplist 的结束标识。

entry 中包含有previous_entry_length、encoding、content等属性

第一中情况:一般结构 <prevlen> <encoding> <entry-data>

  • prevlen:前一个entry的大小;
  • encoding:不同的情况下值不同,用于表示当前entry的类型和长度;
  • entry-data:真是用于存储entry表示的数据;

第二种情况:此时entry结构:<prevlen> <encoding>

  • 在entry中存储的是int类型时,encoding和entry-data会合并在encoding中表示,此时没有entry-data字段;
  • redis中,在存储数据时,会先尝试将string转换成int存储,节省空间;

prevlen编码:当前一个元素长度小于254(255用于zlend)的时候,prevlen长度为1个字节,值即为前一个entry的长度,如果长度大于等于254的时候,prevlen用5个字节表示,第一字节设置为254,后面4个字节存储一个小端的无符号整型,表示前一个entry的长度;

encoding编码:

encoding的长度和值根据保存的是int还是string,还有数据的长度而定;

前两位用来表示类型,当为“11”时,表示entry存储的是int类型,其他表示存储的是string;

存储int时:

  • |11000000| encoding为3个字节,后2个字节表示一个int16;
  • |11010000| encoding为5个字节,后4个字节表示一个int32;
  • |11100000| encoding 为9个字节,后8字节表示一个int64;
  • |11110000| encoding为4个字节,后3个字节表示一个有符号整型;
  • |11111110| encoding为2字节,后1个字节表示一个有符号整型;
  • |1111xxxx| encoding长度就只有1个字节,xxxx表示一个0 - 12的整数值;

存储string时:

  • |00pppppp| :此时encoding长度为1个字节,该字节的后六位表示entry中存储的string长度,因为是6位,所以entry中存储的string长度不能超过63;
  • |01pppppp|qqqqqqqq| 此时encoding长度为两个字节;此时encoding的后14位用来存储string长度,长度不能超过16383;
  • |10000000|qqqqqqqq|rrrrrrrr|ssssssss|ttttttt| 此时encoding长度为5个字节,后面的4个字节用来表示encoding中存储的字符串长度,长度不能超过2^32 - 1;
连锁更新问题

entry中的prevlen字段表示前一个entry的长度,有两种取值,1byte或者5byte.

当一个entry前边的entry的长度发生变化时,会导致需要增大entry 的prevlen字段的size 来存储前一个entry的长度,如果有连续多个entry的容量接近254时,就会发生多个entry的prevlen的size需要扩容,这时就发生所谓的级联更新。

这种更新本质是prevlen size的变化,它以下有两种情形,

  • 一种是扩大(1byte —> 5bytes),
  • 一种是收缩(5bytes—>1byte)


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
2月前
|
存储 NoSQL Java
Redis如何处理Hash冲突?
在 Redis 中,哈希表是一种常见的数据结构,通常用于存储对象的属性,对于哈希表,最常遇到的是哈希冲突,那么,当 Redis遇到Hash冲突会如何处理?这篇文章,我们将详细介绍Redis如何处理哈希冲突,并探讨其性能和实现细节。
65 1
|
6月前
|
存储 NoSQL Redis
Redis系列学习文章分享---第十六篇(Redis原理1篇--Redis数据结构-动态字符串,insert,Dict,ZipList,QuickList,SkipList,RedisObject)
Redis系列学习文章分享---第十六篇(Redis原理1篇--Redis数据结构-动态字符串,insert,Dict,ZipList,QuickList,SkipList,RedisObject)
85 1
|
2月前
|
存储 NoSQL Redis
Redis 哈希(Hash)
10月更文挑战第16天
40 1
|
2月前
|
存储 分布式计算 NoSQL
大数据-40 Redis 类型集合 string list set sorted hash 指令列表 执行结果 附截图
大数据-40 Redis 类型集合 string list set sorted hash 指令列表 执行结果 附截图
27 3
|
1月前
|
存储 NoSQL Redis
Redis常见面试题:ZSet底层数据结构,SDS、压缩列表ZipList、跳表SkipList
String类型底层数据结构,List类型全面解析,ZSet底层数据结构;简单动态字符串SDS、压缩列表ZipList、哈希表、跳表SkipList、整数数组IntSet
|
3月前
|
存储 JSON NoSQL
redis基本数据结构(String,Hash,Set,List,SortedSet)【学习笔记】
这篇文章是关于Redis基本数据结构的学习笔记,包括了String、Hash、Set、List和SortedSet的介绍和常用命令。文章解释了每种数据结构的特点和使用场景,并通过命令示例演示了如何在Redis中操作这些数据结构。此外,还提供了一些练习示例,帮助读者更好地理解和应用这些数据结构。
redis基本数据结构(String,Hash,Set,List,SortedSet)【学习笔记】
|
3月前
|
存储 NoSQL 算法
5)深度解密 Redis 的哈希(Hash)
5)深度解密 Redis 的哈希(Hash)
28 0
|
4月前
|
存储 NoSQL Redis
redis数据结构-ziplist
redis数据结构-ziplist
29 2
|
4月前
|
存储 NoSQL 算法
Redis6入门到实战------ 三、常用五大数据类型(列表(List)、集合(Set)、哈希(Hash)、Zset(sorted set))
这是关于Redis 6入门到实战的文章,具体内容涉及Redis的五大数据类型:列表(List)、集合(Set)、哈希(Hash)、有序集合(Zset(sorted set))。文章详细介绍了这些数据类型的特点、常用命令以及它们背后的数据结构。如果您有任何关于Redis的具体问题或需要进一步的帮助,请随时告诉我。
|
4月前
|
NoSQL Redis
redis 6源码解析之 ziplist
redis 6源码解析之 ziplist
33 5