11天 -- Redis 中跳表的实现原理是什么?Redis 的 hash 是什么?Redis Zset 的实现原理是什么?
Redis 中跳表的实现原理是什么?
Redis 中的跳表(Skip List)是一种基于有序链表的高效数据结构,通过在链表上增加多级索引来提高数据的查找效率。以下是 Redis 中跳表的实现原理:
1. 基本概念
节点结构:跳表中的每个节点包含多个层,每层都有一个前进指针指向同一层级的下一个节点。每个节点还包含一个跨度属性,表示该节点到下一个节点的距离(在同一层级上)。底层包含所有元素,每上升一层,节点数量逐渐减少。
多级索引:跳表通过在不同层级上增加指针来加速查找。每一层都是一个有序链表,且高层链表的节点数量逐层减少。
2. 查找操作
查找过程:从最高层开始,通过前进指针逐层向下查找。如果当前节点的下一个节点的值小于要查找的值,则向右移动;如果大于要查找的值,则向下移动。重复上述过程,直到找到目标节点或确定目标节点不存在。
3. 插入操作
查找插入位置:首先进行查找操作,找到插入位置。
随机生成层数:根据预设的概率(如 0.5)随机生成一个层数,决定新节点的层数。
插入新节点:在每一层中插入新节点,并更新相关节点的前进指针。
4. 删除操作
查找要删除的节点:首先进行查找操作,找到要删除的节点。
更新指针:在每一层中删除该节点,并更新相关节点的前进指针。
5. 优势
高效性:跳表在平均情况下的时间复杂度为 O(log n),与红黑树相当,但实现起来更简单。支持动态操作(插入、删除、查找),并且在维护平衡性和有序性时的性能表现良好。
简洁性:跳表不需要复杂的平衡操作(如旋转),更容易实现和调试。在内存中的额外空间用于维护多级索引,但相对于整个数据集来说通常是可以接受的
并发友好:跳表的简单结构使得并发操作更为容易实现。在 Redis 中,跳表支持高效的并发访问和修改操作。
6. Redis 中的实现细节
节点定义:Redis 中的跳表节点由 zskiplistNode 结构定义,包含元素值、分值(用于排序)、多个层(每层包含前进指针和跨度)以及一个后退指针(指向前一个节点)。
跳表结构:Redis 中的跳表由 zskiplist 结构定义,保存了跳表节点的相关信息,如头节点、尾节点、节点数量和最大层数。
通过以上实现原理,Redis 中的跳表能够高效地支持插入、删除和查找操作,同时保持元素的有序性,非常适合实现如排行榜、范围查询等功能。
Redis 的 hash 是什么?
Redis 的 Hash 是一种非常灵活且高效的数据结构,用于存储键值对集合。它类似于其他编程语言中的字典或哈希表,能够以字段(field)和值(value)的形式存储数据。Redis 的 Hash 数据结构在实际应用中非常广泛,例如存储对象、缓存数据、统计信息等。
一、基本概念
Redis 的 Hash 是一个键值对集合,其中键(key)是唯一的,值(value)可以是任意类型的数据。Hash 的键和值都是字符串类型,但 Redis 提供了丰富的操作命令来处理这些数据。
二、数据结构
Redis 的 Hash 在底层使用哈希表实现,具有以下特点:
- 键值对存储:每个 Hash 包含多个字段(field)和对应的值(value)。
- 唯一性:字段名在同一个 Hash 中是唯一的,不能重复。
- 动态扩展:当 Hash 中的元素数量增加时,Redis 会自动扩展底层的哈希表,以保持高效的查找性能。
三、基本操作命令
Redis 提供了一系列命令来操作 Hash 数据结构,以下是一些常用的命令:
1. HSET
用于向 Hash 中添加一个字段及其对应的值。
HSET key field value
示例:
HSET user:1 name "Alice"
2. HGET
用于获取 Hash 中指定字段的值。
HGET key field
示例:
HGET user:1 name
3. HDEL
用于删除 Hash 中的一个或多个字段。
HDEL key field [field ...]
示例:
HDEL user:1 age
4. HKEYS
用于获取 Hash 中所有字段的名称。
HKEYS key
示例:
HKEYS user:1
5. HVALS
用于获取 Hash 中所有字段的值。
HVALS key
示例:
HVALS user:1
6. HLEN
用于获取 Hash 中字段的数量。
HLEN key
示例:
HLEN user:1
7. HMSET
用于同时设置 Hash 中多个字段的值。
HMSET key field value [field value ...]
示例:
HMSET user:1 name "Alice" age 25
8. HMGET
用于同时获取 Hash 中多个字段的值。
HMGET key field [field ...]
示例:
HMGET user:1 name age
9. HINCRBY
用于将 Hash 中指定字段的值增加一个整数。
HINCRBY key field increment
示例:
HINCRBY user:1 age 1
10. HSCAN
用于迭代 Hash 中的字段和值。
HSCAN key cursor [MATCH pattern] [COUNT count]
示例:
HSCAN user:1 0
四、应用场景
Redis 的 Hash 数据结构在实际应用中非常广泛,以下是一些常见的应用场景:
- 存储对象:可以将一个对象的所有属性存储在一个 Hash 中,例如用户信息、商品信息等。
- 缓存数据:可以将常用的数据缓存到 Redis 的 Hash 中,提高数据访问速度。
- 统计信息:可以使用 Hash 来统计各种信息,例如用户的行为统计、商品的销售统计等。
五、优点
- 高效性:Redis 的 Hash 数据结构具有高效的查找性能,能够快速获取和修改数据。
- 灵活性:可以存储任意数量的字段和值,字段名和值都可以是任意字符串。
- 丰富的操作命令:提供了丰富的操作命令,能够满足各种数据操作需求。
六、缺点
- 内存占用:相比于简单的字符串类型,Hash 数据结构可能会占用更多的内存。
- 数据一致性:在分布式环境下,需要考虑数据一致性的问题。
总的来说,Redis 的 Hash 数据结构是一种非常强大且灵活的数据结构,能够满足各种数据存储和操作需求。
Redis Zset 的实现原理是什么?
Redis 的 Zset(有序集合)是一种功能强大且应用广泛的数据结构,它结合了哈希表(Hash Table)和跳表(Skip List)的优势,实现了高效的元素插入、删除和范围查询操作。以下是 Redis Zset 的实现原理:
1. 基本概念
- 唯一性:Zset 中的每个元素都是唯一的,不能重复。
- 分数关联:每个元素都有一个与之关联的分数,分数为双精度浮点数。
- 有序性:Zset 中的元素按照分数从低到高进行排序;当多个元素的分数相同时,按照字典序升序排列。
2. 内部数据结构
Redis 的 Zset 使用两种主要的数据结构来实现:
- 哈希表(Hash Table):
- 用于存储元素与其分数的映射关系,支持 O(1) 的查找和更新。
- 跳表(Skip List):
- 用于维护元素的有序性,支持快速的范围查询和顺序访问。
3. 编码实现
Redis 在实现 Zset 时会根据元素数量和其他因素选择不同的编码方式,主要包括两种编码策略:
- ZIPLIST 编码:
- 当 Zset 中的元素数量较少,并且元素分数和字符串长度较小的时候,Redis 会选择使用
ziplist编码。这是一种内存紧凑的存储格式,通过连续的内存块存储多个元素,极大地节省了内存空间。
- 当 Zset 中的元素数量较少,并且元素分数和字符串长度较小的时候,Redis 会选择使用
特点:
- 内存紧凑,减少了额外的指针和元数据开销。
- 适用于小规模数据,性能和内存占用更优。
- 操作效率较高,但在元素较多时,操作效率会下降。
SKIPLIST + DICT 编码:
- 当 Zset 中的元素数量较多或分数和字符串长度较大时,Redis 会使用
skiplist + dict编码。这种编码方式结合了哈希表和跳表的优势,支持高效的查找、插入和范围查询。
特点:
- 哈希表用于快速查找和更新元素。
- 跳表用于维护元素的有序性,支持快速的范围查询。
4. 编码切换条件
Redis 会根据 Zset 的实际情况动态切换编码方式:
- 从 ZIPLIST 切换到 SKIPLIST + DICT:
- 当 Zset 中的元素数量超过
zset-max-ziplist-entries(默认为 128)时。 - 当 Zset 中的元素分数和长度超过
zset-max-ziplist-value(默认为 64 字节)的限制时。
- 当 Zset 中的元素数量超过
从 SKIPLIST + DICT 切换到 ZIPLIST:
- 当 Zset 中的元素数量和分数精度低于相应阈值时,Redis 可以选择将其重新编码为 ziplist,以节省内存。
5. 操作命令
Redis 提供了一系列命令来操作 Zset,以下是一些常用的命令:
- ZADD:向 Zset 中添加一个或多个元素。
- ZREM:从 Zset 中删除一个或多个元素。
- ZSCORE:获取 Zset 中某个元素的分数。
- ZRANGE 和 ZREVRANGE:按索引范围获取 Zset 中的元素,前者按分数升序排列,后者按分数降序排列。
- ZRANGEBYSCORE 和 ZREVRANGEBYSCORE:获取 Zset 中分数在指定范围内的元素,前者按分数升序排列,后者按分数降序排列。
6. 优势
- 高效性:Zset 在不同操作场景下都能够保持高效的性能,支持快速的查找、插入和范围查询。
- 灵活性:可以存储任意数量的元素,元素和分数都可以是任意字符串。
- 丰富的操作命令:提供了丰富的操作命令,能够满足各种数据操作需求。
总的来说,Redis 的 Zset 是一种非常强大且灵活的数据结构,能够满足各种数据存储和操作需求。
相关文章:
11天 -- Redis 中跳表的实现原理是什么?Redis 的 hash 是什么?Redis Zset 的实现原理是什么?
Redis 中跳表的实现原理是什么? Redis 中的跳表(Skip List)是一种基于有序链表的高效数据结构,通过在链表上增加多级索引来提高数据的查找效率。以下是 Redis 中跳表的实现原理: 1. 基本概念 节点结构:跳…...
JavaWeb——HTML
一、什么是HTML HTML(HyperText Markup Language):超文本标记语言 超文本:超越了文本的限制,比普通文本更强大。除了文字信息还可以定义图片,音频,视频等。标记语言:由标签构成的语言 HTML语言都是预定义好…...
Spring DIIoC
一.IoC 1.简介 什么是IoC?IoC,全称 Inversion of Control,控制反转。IoC是Spring的核心思想,Spring是⼀个“控制反转”的容器。 如果我们需要一个对象,正常来说我们是通过new一个对象,这个时候我们依赖的…...
【前端基础】Day 2 CSS层叠样式表
目录 1.CSS简历 2.CSS 基础选择器 2.1标签选择器 2.2类选择器 2.3 id选择器 2.4通配符选择器 2.5总结 3.CSS字体属性 字体属性总结 4.CSS文本属性 4.1颜色 4.2对齐文本 4.3装饰文本 4.4文本缩进 4.5行间距 4.6文本属性总结 5.CSS的引入方式 5.1内部样式表 …...
建易WordPress
建易WordPress是一家专业的WordPress建站服务提供商,专注于为企业和个人提供一站式的WordPress网站建设、维护、托管、运营推广以及搜索引擎优化(SEO)服务。 服务内容 1. 网站建设 提供模板建站和定制开发两种服务,满足不同客户的需求。模板建站价格为…...
计算机毕业设计SpringBoot+Vue.js汽车资讯网站(源码+文档+PPT+讲解)
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
nuxt常用组件库html-validator、@nuxtjs/i18n、@nuxt/image、@unocss/nuxt使用解析
html-validator 主要用于自动验证nuxt服务器呈现的HTML(SSR和SSG),以检测可能导致水合错误的HTML常见问题,有助于减少水合错误,检测常见的可访问性错误。 安装 npx nuxilatest module add html-validator配置 若自动更新nuxt.config.ts配置文…...
Leetcode-最大矩形(单调栈)
一、题目描述 给定一个仅包含 0 和 1 、大小为 rows x cols 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。 输入:matrix [["1","0","1","0","0"],["1","0&…...
Vue核心知识:动态路由实现完整方案
在Vue中实现动态路由,并结合后端接口和数据库表设计,是一个复杂的项目,需要多个技术栈和步骤的配合。以下将详细描述整个实现过程,包括数据库设计、后端接口设计、前端路由配置以及如何实现动态路由的功能。 目录 一、需求分析二…...
【Docker】使用Docker搭建-MySQL数据库服务
零、更换Docker镜像源 因为国内现在封锁了Docker默认拉取镜像的站点(DockerHub),而且国内大部分Docker镜像站已全部下线,导致现在很多朋友在拉取镜像的时候会出现无法拉取的现象,这时候就需要进行更换Docker镜像源。 可…...
DHCP配置和地址
DHCP:动态主机配置协议 DHCP系统组成 DHCP报文结构 DHCP报文类型 DHCP工作流程 DHCP租期更新 DHCP重绑定 自动保留IP 租期设置建议 IP地址释放 DHCP地址池 DHCP配置 DHCP接口地址池配置 DHCP全局地址池配置...
基于trl复现DeepSeek-R1的GRPO训练过程
1. 引入 huggingface开发了强化学习训练Transformer的库trl(参考3),借助这个trl,可以用来做GRPO的强化学习训练。魔搭ModelScope社区的文章(参考2)给出了基于Qwen基座模型Qwen2.5-0.5B-Instruct࿰…...
常用的 pip 命令
pip 是 Python 的包管理工具,可用于安装、卸载、更新和管理 Python 包。以下是一些常用的 pip 命令: 1. 安装包 安装最新版本的包 pip install package_namepackage_name 是你要安装的 Python 包的名称,例如 pip install requests 可以安装…...
基于C#的CANoe CLR Adapter开发指南
一、引言 CANoe 是一款广泛应用于汽车电子开发和测试的工具,它支持多种编程接口,方便开发者进行自定义扩展。CANoe CLR Adapter 允许我们使用 C# 语言与 CANoe 进行交互,充分利用 C# 的强大功能和丰富的类库。本文将详细介绍如何基于 C# 进行…...
eMMC安全简介
1. 引言 术语“信息安全”涵盖多种不同的设计特性。一般而言, 信息安全是指通过实践防止信息遭受未经授权的访问、使用、披露、中断、篡改、检查、记录或销毁。 信息安全的三大核心目标为 机密性(Confidentiality)、完整性(Integr…...
从零开始用react + tailwindcss + express + mongodb实现一个聊天程序(六) 导航栏 和 个人信息设置
1.导航栏(navbar) 在components下面 创建NavBar.jsx import { MessageSquare,Settings,User,LogOut} from "lucide-react" import {Link} from "react-router-dom" import { useAuthStore } from "../store/useAuthStore&qu…...
c#实现modbus rtu定时采集数据
以下是使用C#实现Modbus RTU定时采集数据的完整代码示例,包含定时任务、数据采集和异常处理: csharp 复制 using System; using System.IO.Ports; using System.Timers;public class ModbusRtuCollector : IDisposable {private readonly SerialPort _serialPort;private …...
【Python 语法】Python 数据结构
线性结构(Linear Structures)1. 顺序存储列表(List)元组(Tuple)字符串(String) 2. 线性存储栈(Stack)队列(Queue)双端队列(…...
数据库MySQL,在终端输入后,提示不是内部命令等
【解决问题】mysql提示不是内部或外部命令,也不是可运行的程序 一般这种问题是因为没有在系统变量里面添加MySQL的可执行路径 以下是添加可执行路径的方法: 第一步:winR输入services.msc 然后找到MySQL,右击属性并复制MySQL的可执…...
docker和containerd从TLS harbor拉取镜像
私有镜像仓库配置了自签名证书,https访问,好处是不需要处理免费证书和付费证书带来的证书文件变更,证书文件变更后需要重启服务,自签名证书需要将一套客户端证书存放在/etc/docker/cert.d目录下,或者/etc/containerd/c…...
《从0到1:用Python在鸿蒙系统开发安防图像分类AI功能》
在人工智能与移动应用深度融合的当下,类目标签AI功能成为众多行业提升效率和用户体验的关键技术。本文聚焦于HarmonyOS NEXT API 12及以上版本,以图像分类在智能家居安防领域的应用为例,为开发者详细阐述如何利用Python开发类目标签AI功能,助力鸿蒙技术在该领域的创新应用。…...
C语言生成二维码
1. 效果 2. 需要的代码(QRCode) qrcode.cqrcode.h 代码 3. 代码 #include <stdio.h> #include "qrcode.h"int main() {//拓展编码SetConsoleOutputCP(437);QRCode qrcode;uint8_t qrcodeBytes[qrcode_getBufferSize(3)];qrcode_initT…...
Spring Boot 消息队列(以RabbitMQ为例)
文章目录 RabbitMQ 简介与安装1. RabbitMQ 简介2. RabbitMQ 安装 Spring Boot 集成 RabbitMQ1. 创建 Spring Boot 项目2. 配置 RabbitMQ3. 定义消息队列和交换机4. 发送消息5. 接收消息6. 测试消息发送和接收 RabbitMQ 简介与安装 1. RabbitMQ 简介 RabbitMQ 是一个开源的消息…...
[Web 安全] PHP 反序列化漏洞 —— POP 链构造思路
关注这个专栏的其他相关笔记:[Web 安全] 反序列化漏洞 - 学习笔记-CSDN博客 0x01:什么是 POP 链? POP 链(Payload On Purpose Chain)是一种利用 PHP 中的魔法方法进行多次跳转以获取敏感数据的技术。它通常出现在 CTF…...
商城源码的框架
商城源码的框架通常是基于某种Web开发框架或者电子商务平台来构建的。以下是一些常见的商城源码框架: WooCommerce:基于WordPress的电子商务插件,适用于小型到中型的在线商店。 Magento:一个功能强大和灵活的开源电子商务平台&am…...
记录深度学习中有用的终端命令
1 查看 CUDA 版本 如果你安装了 CUDA 开发工具包,你可以使用 nvcc 命令来查看 CUDA 的版本。 打开终端(或命令提示符),运行: nvcc --version 2. 监控 GPU 状态 使用 nvidia-smi 命令,nvidia-smi 是一个…...
深度探索推理新境界:DeepSeek-R1如何用“自学”让AI更聪明?
今天我们要聊从1月初火到现在的AI模型——DeepSeek-R1。它就像一个“自学成材的学霸”,不用老师手把手教,就能在数学、编程、逻辑推理等领域大显身手!仔细阅读了深度求索发表的R1论文,发现它不仅揭秘了它的成长秘籍,还…...
2025春新生培训数据结构(树,图)
教学目标: 1,清楚什么是树和图,了解基本概念,并且理解其应用场景 2,掌握一种建图(树)方法 3,掌握图的dfs和树的前中后序遍历 例题与习题 2025NENU新生培训(树&#…...
keil主题(vscode风格)
#修改global.prop文件,重新打开keil即可 # Keil uVision Global Properties File # This file is used to customize the appearance of the editor# Editor Font editor.font.nameConsolas editor.font.size10 editor.font.style0# Editor Colors editor.backgro…...
使用Hydra进行AI项目的动态配置管理
引言:机器学习中的超参数调优挑战 在机器学习领域,超参数调优是决定模型性能的关键环节。不同的模型架构,如神经网络中的层数、节点数,决策树中的最大深度、最小样本分割数等;以及各种训练相关的超参数,像学习率、优化器类型、批量大小等,其取值的选择对最终模型的效果…...
