Redis 源码分析哈希对象(z_hash)

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: Redis 源码分析哈希对象(z_hash)

数据结构


Redis 的 hash 对象采用了两种方式来实现,前面分析过连续内存和非连续内存的优缺点,这里 hash 列表也折中了两种情况。


两种存储结构(代码位置 src/t_hash.c):


image.png


ziplist 编码:


ziplist 编码的哈希对象使用压缩列表作为底层实现,每当有新的键值对要加入到哈希对象时,程序会先将保存了键的压缩列表节点推入压缩列表表尾,然后在将保存了值的压缩列表表尾,因此:


1、保存了同一个键值对的两个节点总是紧挨在一起,保存键的节点在前面,保存值的节点在后面。


2、先添加到哈希对象的键值对会被放在压缩列表的表头方向,而后添加到哈希对象中的键值对会被放在压缩列表的表尾方向。


举个例子:


127.0.0.1:6379> hset profile name "Tom"
(integer) 1
127.0.0.1:6379> hset profile age 25
(integer) 1
127.0.0.1:6379> hset profile career "Programmer"
(integer) 1
127.0.0.1:6379> object encoding profile
"ziplist"


数据结构如下:


image.png


压缩列表底层实现(profile  key 结构):


image.png

hashtable 编码:


image.png


编码转换:


同时满足一下两个条件的时候选择 ziplist 编码:


  • 哈希对象保存的所有键值对的键和值的字符串长度都小于64 字节;


  • 哈希对象保存的简直对数量小于 512 个;不满足这两个条件的哈希对象需要使用 hashtable 编码(可以通过 hash-max-ziplisthash-maxziplist-value 修改)。


举个例子(profile  key 结构)::


127.0.0.1:6379> hset profile desc "Programmer 11111112121v121kl lldklakdkalgam fsfdslkgkskgsklgklsklgklsklgsdkgkskgdsklmvm,,vm,vm,,maafaklglkaklsfakslkf"
(integer) 1
127.0.0.1:6379> object encoding profile
"hashtable"


注意点


  • 由 ziplist 转换为 dict 的操作是不可逆的


  • 尽可能的使用 ziplist 来作为 hash 底层实现。长度尽可能控制在 1000 以内,否则由于存取操作复杂度 O(n) , 长列表会导致 CPU 消耗亚种,对象也不要太大


  • 两个参数 hash-max-ziplisthash-maxziplist-value 可在配置文件中修改


  • ziplist 底层存储对象时, 查找时间负载度为 O(n)


使用场景



  • 存储对象(定长或者不定长字符串)


set user:1:name Mack
set user:1:age 23
set user:1:city shanghai


  • 序列化字符串(结合 pb 一起使用,最为广泛)


set user:1 serialize(userinfo)


  • 优点:简单直观,每个属性都支持单独更新


  • 缺点:占用过多的键,内存占用量大,同时用户信息内聚性差,盛昌环境比较少使用


  • 哈希类型


hmset user:1 name tom age 23 city shanghai


  • 优点:简化编程,合理运用序列化,可以提高内存的使用效率。


  • 缺点:要控制在 ziplist 和 hashtable 两种内部编码的转换, hashtable 会消耗更多的内存


常见操作



image.png


参考资料


  • 《Redis 设计与实现》黄健宏



相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
6月前
|
NoSQL Redis
Redis的常用数据结构之哈希类型
Redis的常用数据结构之哈希类型
35 0
|
25天前
|
存储 消息中间件 NoSQL
Redis 数据结构与对象
【10月更文挑战第15天】在实际应用中,需要根据具体的业务需求和数据特点来选择合适的数据结构,并合理地设计数据模型,以充分发挥 Redis 的优势。
54 8
|
29天前
|
存储 NoSQL Redis
Redis 哈希(Hash)
10月更文挑战第16天
34 1
|
1月前
|
JSON 缓存 NoSQL
Redis 在线查看序列化对象技术详解
Redis 在线查看序列化对象技术详解
37 2
|
2月前
|
存储 NoSQL 算法
5)深度解密 Redis 的哈希(Hash)
5)深度解密 Redis 的哈希(Hash)
26 0
|
6月前
|
存储 缓存 NoSQL
深入浅出Redis(一):对象与数据结构
深入浅出Redis(一):对象与数据结构
|
3月前
|
存储 NoSQL 算法
Redis6入门到实战------ 三、常用五大数据类型(列表(List)、集合(Set)、哈希(Hash)、Zset(sorted set))
这是关于Redis 6入门到实战的文章,具体内容涉及Redis的五大数据类型:列表(List)、集合(Set)、哈希(Hash)、有序集合(Zset(sorted set))。文章详细介绍了这些数据类型的特点、常用命令以及它们背后的数据结构。如果您有任何关于Redis的具体问题或需要进一步的帮助,请随时告诉我。
|
4月前
|
存储 缓存 NoSQL
Redis问题之一致性Hash是如何解决哈希+取余方法中的稳定性问题的
Redis问题之一致性Hash是如何解决哈希+取余方法中的稳定性问题的
65 10
|
4月前
|
消息中间件 存储 NoSQL
Redis数据结构—跳跃表 skiplist 实现源码分析
Redis 是一个内存中的数据结构服务器,使用跳跃表(skiplist)来实现有序集合。跳跃表是一种概率型数据结构,支持平均 O(logN) 查找复杂度,它通过多层链表加速查找,同时保持有序性。节点高度随机生成,最大为 32 层,以平衡查找速度和空间效率。跳跃表在 Redis 中用于插入、删除和按范围查询元素,其内部节点包含对象、分值、后退指针和多个前向指针。Redis 源码中的 `t_zset.c` 文件包含了跳跃表的具体实现细节。
|
5月前
|
存储 JSON NoSQL
Redis第五弹-HASH结构相关指令和介绍,计数功能Hash-哈希(Redis本来就是键值对结构,哈希,就相当于键值对嵌套了一个键值对)的多种指令Hset key field value-
Redis第五弹-HASH结构相关指令和介绍,计数功能Hash-哈希(Redis本来就是键值对结构,哈希,就相当于键值对嵌套了一个键值对)的多种指令Hset key field value-