Hash 数据结构

  1. 使用 ziplist

    当同时满足下面两个条件时,使用 ziplist 存储数据

    • 元素个数少于512个 (hash-max-ziplist-entries: 512)
    • 每个元素长度小于64字节 (hash-max-ziplist-value: 64)
  2. 不满足上面的条件, 使用 hashtable

Hash使用 ziplist 图解

可以看到, 当hash以ziplist编码存储时,键值对依次按顺序存放在ziplist中,key在前,value在后.

Hash使用 hashtable 图解

哈希表相关的数据结构

//字典
typedef struct dict {
dictType *type; // 类型特定函数
void *privdata; // 私有数据
dictht ht[2]; // 每个字典使用两个哈希表,实现渐进式 rehash
int rehashidx; // rehash 索引,当 rehash 不在进行时,值为 -1
int iterators; // 目前正在运行的安全迭代器的数量
} dict; //哈希表
typedef struct dictht {
dictEntry **table; // 哈希表数组
unsigned long size; // 哈希表大小
unsigned long sizemask; // 哈希表大小掩码,用于计算索引值, 总是等于 size - 1
unsigned long used; // 该哈希表已有节点的数量
} dictht; //哈希表节点
typedef struct dictEntry {
void *key; // 键
union {
void *val; // 值, 正常是指向一个 redisObject
uint64_t u64;
int64_t s64;
} v;
struct dictEntry *next; // 指向下个哈希表节点,形成链表 (拉链法解决hash冲突)
} dictEntry;

哈希表图解

渐进式rehash流程

当hashtable需要扩容时,redis使用渐进式rehash

  1. 为ht[1]分配空间,此时字典同时持有ht[0]和ht[1]
  2. 将rehashidx设为0,表示rehash正式开始
  3. 在rehash期间,每次对字典执行任意操作时,程序除了执行对应操作之外,还会顺带将ht[0]在rehashidx索引上的所有键值对rehash到ht[1],操作完后将rehashidx的值 + 1
  4. Redis本身也会有事件轮询,哪怕没有命令访问,也会通过轮询事件逐渐完成数据迁移
  5. 当rehashidx的值增加到 ht[0].size,此时ht[0]的所有键值对都已经迁移到ht[1]了。程序会把ht[1]赋值给ht[0],并重新在ht[1]上新建一个空表。将rehashidx重新置为-1,以此表示rehash完成

Redis为什么需要渐进式rehash?

当存在超大的hashTable进行扩容时,如果不去渐进式扩容,单次扩容时间太长,扩容期间Redis服务不可用,将导致线程阻塞

Hash的常用命令

  • HSET key field value 将一个或多个field/value插入到哈希表中
  • HGET key field 返回key中指定 field 的 value 值
  • HKEYS key 返回哈希表 key 中的所有field
  • HGETALL key 返回哈希表 key 中,所有的field和value
  • HVALS key 返回哈希表 key 中的所有value
  • HEXISTS key field 检查哈希表 key 中,field 是否存在
  • HDEL key field 删除哈希表 key 中的一个或多个field
  • HLEN key 返回哈希表 key 中field的数量
  • HSETNX key field value :将哈希表 key 中的 field 的值设置为 value , 仅当 field 不存在时才会执行

Redis 原理 - Hash的更多相关文章

  1. Redis详细讲解(Redis原理,Redis安装,Redis配置,Redis使用,Redis命令)

    一.Redis介绍 Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API.从2010年3月15日起,Redis的开发 ...

  2. Redis原理与实践总结

    Redis原理与实践总结 本文主要对Redis的设计和实现原理做了一个介绍很总结,有些东西我也介绍的不是很详细准确,尽量在自己的理解范围内把一些知识点和关键性技术做一个描述.如有错误,还望见谅,欢迎指 ...

  3. Redis原理篇

    Redis原理篇 1.发布 订阅模式 1.1列表 的局限 ​ 前面我们说通过队列的 rpush 和 lpop 可以实现消息队列(队尾进队头出),但是消费者需要不停地调用 lpop 查看 List 中是 ...

  4. redis数据类型--hash

    /** Redis应用之Hash数据类型* 问题1:操作命令* 问题2:存储实现原理和数据结构* 问题3:应用场景* */ 先了解下什么是hash,什么是hash碰撞:hash:是包含键值对的kv的数 ...

  5. Redis原理详解

    Redis原理详解 数据类型 Redis最为常用的数据类型主要有以下五种: String Hash List Set Sorted set 在具体描述这几种数据类型之前,我们先通过一张图了解下Redi ...

  6. 面试被吊打系列 - Redis原理

    小张兴冲冲去面试,结果被面试官吊打! 小张: 面试官,你好.我是来参加面试的. 面试官: 你好,小张.我看了你的简历,熟练掌握Redis,那么我就随便问你几个Redis相关的问题吧.首先我的问题是,R ...

  7. redis的hash操作在集中式session中的应用

    在集群部署时,为了高可用性的目的,往往把session进行共享,共享分为两种:session复制和集中式管理. redis在session集中式管理中可以起到比较大的作用. 制约session集中式共 ...

  8. Redis操作Hash工具类封装,Redis工具类封装

    Redis操作Hash工具类封装,Redis工具类封装 >>>>>>>>>>>>>>>>>> ...

  9. Redis之Hash

    一.Redis之Hash简介 1. Hash是一个string类型的field和value的映射表,适合用于存储对象. 2. 每个hash可以存储232-1个键值对(40多亿). 二.Redis之Ha ...

  10. redis对hash进行的相关操作

    redis对hash类型操作的相关命令以及如何在python使用这些命令 redis对hash类型操作的命令: 命令 语法 概述 返回值 Redis Hdel 命令 hdel key field [f ...

随机推荐

  1. IM技术干货:假如你来设计微信的群聊,你该怎么设计?

    本文由苏三说技术分享,原题"微信群聊功能,原来是这样设计的!",下文进行了排版和内容优化等. 1.引言 当我那天拿着手机,正在和朋友们的微信群里畅聊着八卦新闻和即将到来的周末计划时 ...

  2. kubernetes系列(八) - 控制器的资源清单定义

    1. ReplicaSet 1.1 ReplicaSet资源清单 1.2 selector 2. Deployment 2.1 Deployment资源清单 2.2 其他相关操作 2.2.1 应用ya ...

  3. 几种常见的Web服务器-copy

    Apache与Tomcat的区别 ,几种常见的web/应用服务器 APACHE是一个web服务器环境程序 启用他可以作为web服务器使用 不过只支持静态网页 如(asp,php,cgi,jsp)等动态 ...

  4. JVM:方法区、堆

    https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.6.2

  5. jdk 5.0 新增的foreach循环(用于遍历集合、数组)

    使用 foreach 循环遍历集合元素 Java 5.0 提供了 foreach 循环迭代访问 Collection和数组. 遍历操作不需获取Collection或数组的长度,无需使用索引访问元素 ...

  6. Spring AI + DeepSeek:提升业务流程的智能推理利器

    今天,我们将深入探讨如何利用DeepSeek来真正解决我们当前面临的一些问题.具体来说,今天我们仍然会将DeepSeek接入到Spring AI中进行利用.需要注意的是,虽然DeepSeek目前主要作 ...

  7. JMeter下载与环境配置

    前置 使用JMeter前需要先配置好Java的环境变量,不会的朋友可以阅读:https://www.cnblogs.com/test-gang/p/18144441 JMeter下载 JMeter官网 ...

  8. Docker部署 .Net程序

    项目准备   首先创建一个项目,这里准备的是api项目,当然也可以是其他项目,按照自己需要的项目创建即可: 添加Dockerfile   接下来添加Dockfile文件,Dockerfile文件是Do ...

  9. QStringListModel的使用

    主要为 :添加.插入.修改.删除.清空等操作 例子:本例子中QListView 没有做任何处理,只是拖放至ui文件,设置了布局 MainWindow.h #ifndef MAINWINDOW_H #d ...

  10. 《uTools:提升效率的神奇工具》

    utools5.0 一.引言 在如今快节奏的工作和生活中,我们都在寻找能够帮助我们节省时间.提高效率的工具.uTools 就是这样一款令人惊艳的工具,它为我的日常带来了极大的便利. 相关链接:uToo ...