Redis哈希对象(listpack介绍)

2023-12-01 15:04

本文主要是介绍Redis哈希对象(listpack介绍),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

        哈希对象的编码可以是ziplist或者hashtable。再redis5.0版本之后出现listpack,为了是代替ziplist。

一. 使用ziplist编码

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

  • 保存了同一键值对的两个节点总是紧挨在一起的,保存键的节点在前,保存值的节点在后。
  • 先添加到哈希对象中的键值对会被放到压缩列表头方向,而后来添加到哈希对象中的键值对会被放在压缩列表的表尾方向。
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> 

        如果Redis使用ziplist作为哈希对象的的编码,那么对象和对象使用的压缩列表会如下图:

二.使用hashtable编码

        当使用hashtable编码的作为哈希对象的编码,是使用字典作为底层实现,哈希对象的每一个键值对都使用一个字典键值对来保存。

//字典节点结构
typedef struct dictEntry {//键void *key;//值union {void *val;uint64_t u64;int64_t s64;double d;} v;//指向下一个节点,形成链表struct dictEntry *next;
} dictEntry;
  • 字典每一个键都是一个字符串对象,对象中保存了键值对的键
  • 字典每一个值都是一个字符串对象,对象中保存了键值对的值

举个例子,如果前面的profile键创建的不是ziplist编码的哈希对象,而是hashtable编码的哈希对象,那么这个哈希对象结构如下图:

三. 编码转换

         当哈希对象可以同时满足以下两个条件时,哈希对象使用ziplist编码:

  • 哈希对象保存的所有的键和值的字符串长度都小于64字节
  • 哈希对象保存的键值对数量小于512个,不能满足这个条件的哈希对象需要使用hashtable编码。

四.哈希命令的实现

五. listpack编码

        5.1 介绍

         listpack(紧凑列表)时Redis5版本出现的,作用是为了代替ziplist。Redis7.0版本之后,listpack就完全替代了ziplist。

        ziplist的缺点是,在极端的情况下,可能会出现连锁更新的情况,时间复杂度是O(N^2),会带来不小的性能消耗。ziplist介绍:Redis压缩列表-CSDN博客

        虽然Redis在3.0版本后使用quicklist,通过quicklistNode来控制ziplist的大小和元素的个数,减少连锁更新带来的性能问题,但是它并没有避免连锁更新,使用的还是ziplist。

        而listpack最大的特点是,每一个节点不再包含前一个节点的长度,而压缩列表正是因为节点中包含前一个节点的长度,所以存在连锁更新的隐患。

typedef struct {/* 当使用string时,它具有长度(slen)。 */unsigned char *sval;uint32_t slen;/* 当使用integer时,“sval”为 NULL,lval 保存该值。*/long long lval;
} listpackEntry;

        listpackEntry中的slen属性记录的是当前节点的长度,而非前一个节点的长度。并且listpackEntry可以保存整数或者字符串。

  • 当存储整数时,lval就是对应的整数值,sval为NULL,slen为0。
  • 当存储字符串时,sval保存的时字符串的值,slen保存字符串的长度。

        5.2 结构

        通过创建一个listpack函数我们可以得到listpack的结构:
 

unsigned char *lpNew(size_t capacity) {unsigned char *lp = lp_malloc(capacity > LP_HDR_SIZE+1 ? capacity : LP_HDR_SIZE+1);if (lp == NULL) return NULL;lpSetTotalBytes(lp,LP_HDR_SIZE+1);lpSetNumElements(lp,0);lp[LP_HDR_SIZE] = LP_EOF;return lp;
}

        结构为:

  • encoding:编码,会对不同长度的整形和字符串进行编码
  • data: 数据
  • len:当前节点的长度。 

        5.3 与ziplist的区别

  1. listpack节点不包含前一个节点的长度,避免了连锁更新问题
  2. listpack结构没有指向末尾节点地址的偏移量,解决ziplist内存长度限制的问题,但是一个listpack最大内存使用不能超过1G。

这篇关于Redis哈希对象(listpack介绍)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/441632

相关文章

Redis 命令详解与实战案例

《Redis命令详解与实战案例》本文详细介绍了Redis的基础知识、核心数据结构与命令、高级功能与命令、最佳实践与性能优化,以及实战应用场景,通过实战案例,展示了如何使用Redis构建高性能应用系统... 目录Redis 命令详解与实战案例一、Redis 基础介绍二、Redis 核心数据结构与命令1. 字符

SpringBoot18 redis的配置方法

《SpringBoot18redis的配置方法》本文介绍在SpringBoot项目中集成和使用Redis的方法,包括添加依赖、配置文件、自定义序列化方式、使用方式、实际使用示例、常见操作总结以及注意... 目录一、Spring Boot 中使用 Redis1. 添加依赖2. 配置文件3. Redis 配置类

Redis中群集三种模式的实现

《Redis中群集三种模式的实现》Redis群集有三种模式,分别是主从同步/复制、哨兵模式、Cluster,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录1. Redis三种模式概述2、Redis 主从复制2.1 主从复制的作用2.2 主从复制流程2

Redis的安全机制详细介绍及配置方法

《Redis的安全机制详细介绍及配置方法》本文介绍Redis安全机制的配置方法,包括绑定IP地址、设置密码、保护模式、禁用危险命令、防火墙限制、TLS加密、客户端连接限制、最大内存使用和日志审计等,通... 目录1. 绑定 IP 地址2. 设置密码3. 保护模式4. 禁用危险命令5. 通过防火墙限制访问6.

深入理解Redis线程模型的原理及使用

《深入理解Redis线程模型的原理及使用》Redis的线程模型整体还是多线程的,只是后台执行指令的核心线程是单线程的,整个线程模型可以理解为还是以单线程为主,基于这种单线程为主的线程模型,不同客户端的... 目录1 Redis是单线程www.chinasem.cn还是多线程2 Redis如何保证指令原子性2.

Docker + Redis 部署集群的实现步骤

《Docker+Redis部署集群的实现步骤》本文详细介绍了在三台服务器上部署高可用Redis集群的完整流程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋... 目录一、环境准备1. 服务器规划(3 台服务器)2. 防火墙配置(三台服务器均执行)3. 安装 docke

Redis中删除策略的几种实现方式

《Redis中删除策略的几种实现方式》本文详细介绍了Redis的过期键删除策略和内存淘汰策略,过期键删除策略包括定时删除、惰性删除和定期删除,具有一定的参考价值,感兴趣的可以了解一下... 目录前言一、设计背景:为什么需要删除策略?二、第一类:过期键的 3 种核心删除策略1. 定时删除(Timed Dele

Spring Boot整合Redis注解实现增删改查功能(Redis注解使用)

《SpringBoot整合Redis注解实现增删改查功能(Redis注解使用)》文章介绍了如何使用SpringBoot整合Redis注解实现增删改查功能,包括配置、实体类、Repository、Se... 目录配置Redis连接定义实体类创建Repository接口增删改查操作示例插入数据查询数据删除数据更

sqlserver、mysql、oracle、pgsql、sqlite五大关系数据库的对象名称和转义字符

《sqlserver、mysql、oracle、pgsql、sqlite五大关系数据库的对象名称和转义字符》:本文主要介绍sqlserver、mysql、oracle、pgsql、sqlite五大... 目录一、转义符1.1 oracle1.2 sqlserver1.3 PostgreSQL1.4 SQLi

C++中unordered_set哈希集合的实现

《C++中unordered_set哈希集合的实现》std::unordered_set是C++标准库中的无序关联容器,基于哈希表实现,具有元素唯一性和无序性特点,本文就来详细的介绍一下unorder... 目录一、概述二、头文件与命名空间三、常用方法与示例1. 构造与析构2. 迭代器与遍历3. 容量相关4