Redis基础(数据结构和内部编码)

news2024/9/20 14:11:37

目录

前言

Redis的数据结构和内部编码

string结构和内部编码

string数据机构的特点

string数据结构的内部编码

list结构和内部编码

List 数据结构的特点

List 的内部编码

1. ziplist(压缩列表)

2. quicklist

hash结构和内部编码

hash数据结构的特点

hash数据结构的内部编码

1.ziplist 压缩列表 

2. hashtable 哈希表

set结构和内部编码

set数据结构的特点

set数据结构和内部编码

1. intset(整数集合)

2. hashtable(哈希表)

zset结构和内部编码

zset数据结构的特点

zset数据结构和内部编码

总结


前言

这篇文章主要介绍了redis的基础使用,包括在服务器上安装redis,配置redis,以及一些使用的基础命令. 

Redis入门icon-default.png?t=O83Ahttps://blog.csdn.net/qq_63525426/article/details/134705665?spm=1001.2014.3001.5502接下来我们将继续介绍关于redis的更多知识以及使用.

Redis的数据结构和内部编码

在学习redis的数据结构和内部编码之前,我们先介绍一个命令.

type命令: type命令就是返回当前键的数据结构类型,redis中有5种数据结构,他们分别是string(字符串),list(列表),hash(哈希),set(集合),zset(有序集合).这些结构只是redis对外的数据结构.

上述的图片时redis提供给外部的数据结构,其实redis针对每种数据结构在内部都有自己的底层编码实现,而且是多种实现.这样做的目的就是来应对不同场景的需求.

 可以看到每种数据结构都至少有两种以上的实现.比如list就有linkedList和ziplist两种内部编码.

同时有些内部编码,比如ziplist就作为多种数据结构的内部编码.

在redis中可以通过object encoding命令来查询内部编码.使用type来查询外部编码

 

 可以看到我们设置的键的数据结构,hello键的结构是embstr,mylist的键是quickList

string结构和内部编码

string是redis中最基本的数据结构,也是使用最频繁的一个数据结构,不仅可以存储普通字符串,还可以存储二进制数据(序列化对象,图片)等数据,redis也是针对string在不同场景进行不同编码和优化.

string数据机构的特点

  1. 简单灵活  可以存储任意格式的数据,包括二进制数据,整数,浮点数等
  2. 最大长度  字符串最大长度可以达到512MB
  3.  高效  大多数string类型的操作时间复杂度为O(1).

string数据结构的内部编码

redis针对不同字符串的长度和类型,采用不同的内部编码来优化和节省内存,主要有三种编码方式.

  1. int(整数编码)
  2. embsrt(紧凑型字符串编码)
  3. raw(普通字符串编码)

当字符串被解析为64位有符号整数时,redis会将其以整数的形式存储,

当字符串的长度小于44字节时,redis会使用embstr编码,这种编码方式会将对象和实际字符串存储在同一块连续的内存中.降低了内存碎片和分配的开销.

当字符串长度超过44字节时,就会使用raw编码,这种方式将对象和实际字符串分开存储,适用于比较大的字符串.

list结构和内部编码

注意:quickList其实是ziplist和linkedList两种数据结构的结合,结构和这两种数据机构的优点,为列表类型提供了一种更优质的内部编码,而用户是感知不到的.也就是redis可以随时的改进自己的内部编码.而不用考虑外部编码.

多种不同的内部编码可以在不同场景下发挥各自的优势,例如ziplist比较节省内存,但是在列表元素变多的时候,性能就会下降,这时redis会根据配置选项进行切换,从而将列表类型的内部结构转换为linkedList.整个转换的过程用户是无感知的.

在 Redis 中,List(列表) 是一种有序的集合,支持在头部或尾部插入、删除元素,同时可以通过索引来访问元素。Redis 中的列表结构非常灵活,适合多种场景,如消息队列、任务调度等。

List 数据结构的特点

  1. 有序性:列表中的元素按插入顺序排序。
  2. 双向操作:可以从列表的头部或尾部进行操作。
  3. 高效:列表操作的时间复杂度通常是 O(1),特别适合大量数据的插入和删除操作。

List 的内部编码

Redis 中,List 有两种内部实现编码,Redis 会根据列表的长度及元素大小在两者之间进行切换:

  1. ziplist(压缩列表):当列表元素较少且每个元素都较小时使用。
  2. quicklist:用于存储较大的列表数据,这是 Redis 3.2 版本后引入的结构,用于替代之前的 linkedlist
1. ziplist(压缩列表)
  • 简介ziplist 是一种内存紧凑的数据结构,专门用于存储小量数据,它将数据存储在一个连续的内存块中,减少了内存开销。
  • 特性
    • 数据以连续的方式存储,节省了指针和额外的元数据占用的空间。
    • 适合存储小型列表,避免内存碎片问题。
    • 插入和删除操作的性能会随着列表的长度变大而下降,时间复杂度为 O(n)。
  • 使用场景:当列表的长度小于配置参数 list-max-ziplist-entries,默认512个 , 且列表中每个元素的大小小于 list-max-ziplist-value  默认64字节 时,Redis 会使用 ziplist 作为编码方式。
2. quicklist
  • 简介quicklist 是 Redis 3.2 之后引入的新的 List 实现方式,结合了压缩列表(ziplist)和双向链表(linkedlist)的优势。
  • 结构
    • quicklist 是由多个 ziplist 片段通过双向链表连接起来的。
    • 每个 quicklist 节点是一个 ziplist,这种设计既保证了存储密度(通过 ziplist 节省内存),又提升了操作效率(通过双向链表提供高效的插入和删除)。
    • quicklist 使得即使在处理较大的列表时,内存效率也更高。
  • 优势
    • 插入、删除等操作仍然是 O(1) 的复杂度,因为操作可以发生在 ziplist 的头部或尾部。
    • 避免了纯链表带来的内存碎片问题,降低了内存开销。

Redis 会根据列表的元素个数和元素的大小自动在 ziplistquicklist 之间切换:

  • 当列表较小时,使用 ziplist,以节省内存。
  • 当列表变大或其中有大元素时,自动切换为 quicklist 以提高操作效率。

Redis 中 List 的实现主要有两种编码方式:

  • ziplist:用于存储小型列表,内存紧凑,但插入、删除操作效率较低。
  • quicklist:结合了 ziplistlinkedlist 的优势,适合存储较大的列表,且插入、删除操作效率高。

hash结构和内部编码

hash数据结构的特点

在 Redis 中,hash(哈希) 是一种用于存储键值对的集合。每个 Hash 本质上是一个键(key),这个键对应的是一个映射表(类似于一个小型的数据库)。Redis 的 Hash 适合用于存储对象的属性,比如可以用来存储用户信息,属性包括用户名、年龄、邮箱等。

hash数据结构的内部编码

redis为了提高内存使用率和性能,针对不同大小的hash和场景设置了两种不同内部编码.

1.ziplist 压缩列表 

当hash中字段数量较少,每个字段的长度值较小时,redis使用ziplist作为底层实现, ziplist作为一种连续内存块的数据结构,存储元素紧凑并节省内存.适用于小型hash表,插入和查找的性能随着数据增加而下降,因为需要遍历整个ziplist.每个字段的值以顺序的方式存储(有序的).

当满足以下条件时,使用ziplist存储,反之使用Hashtable存储:

哈希表中每个元素的数量小于512(默认)

哈希表中每个字段的值和长度小于64字节(默认)

2. hashtable 哈希表

当 hash 中的字段数量或字段/值的大小超过一定阈值时,Redis 会切换到 hashtable 编码。这种编码方式是标准的哈希表实现,具有快速的查找、插入和删除性能

  • 插入和查找的时间复杂度为 O(1),非常高效。
  • 相较于 ziplist,它消耗更多的内存,但性能更高,适用于大规模的哈希表。
  • 使用条件:当哈希表不满足 ziplist 编码的条件时,Redis 自动切换为 hashtable 编码。

set结构和内部编码

在 Redis 中,Set(集合) 是一种无序的集合数据结构,用于存储唯一的值。集合中的每个元素都是唯一的,且不允许重复。在 Redis 中,Set 是一种非常灵活且常用的数据类型,适合用于处理不需要重复值的场景,如标签系统、好友关系、共同爱好等。

set数据结构的特点

  • 无序性:集合中的元素是无序的,不能通过索引来获取特定元素。
  • 唯一性:集合中的所有元素都是唯一的,重复元素会自动去重。
  • 高效的操作:集合支持常见的集合运算,如交集、并集和差集,并且这些操作的时间复杂度通常为 O(1) 或 O(N),其中 N 是集合的大小。

set数据结构和内部编码

Redis 中的 Set 使用两种不同的内部编码来优化性能和内存使用,这两种编码分别是:

  1. intset(整数集合)
  2. hashtable(哈希表)
1. intset(整数集合)
  • 简介:当 Set 中的元素都是整数且数量较少时,Redis 使用 intset 编码。intset 是一种紧凑的结构,用于存储整数类型的集合。
  • 特点
    • 节省内存:intset 使用连续的内存块来存储整数,非常紧凑。
    • 操作效率:由于 intset 是有序的,Redis 在插入、删除、查找时会进行二分查找,性能较好。
  • 使用条件:如果 Set 中所有元素都是整数且集合的大小不超过一定阈值(默认 512 个),则 Redis 会使用 intset 编码。
2. hashtable(哈希表)
  • 简介:当 Set 中的元素不是整数或元素数量超过一定阈值时,Redis 会切换到 hashtable 编码。hashtable 是常见的哈希表实现,用于存储任意类型的元素。
  • 特点
    • 插入、删除、查找的时间复杂度为 O(1),非常高效。
    • 相较于 intsethashtable 编码占用更多的内存。
  • 使用条件:如果 Set 中包含非整数元素,或者元素的数量超过阈值(默认 512 个),则 Redis 会使用 hashtable 编码。

zset结构和内部编码

在 Redis 中,Zset(Sorted Set, 有序集合) 是一种带有排序的集合类型,类似于 Set 但每个元素都会关联一个分值(score)。Zset 中的元素仍然是唯一的,但元素会根据分值从小到大进行排序,允许进行快速的范围查找和排序操作。

应用场景:

  • 排行榜系统:Zset 可以根据分值对元素进行排序,非常适合实现排行榜、积分榜、排名系统等场景。例如,游戏中可以使用 Zset 实现玩家的积分排名。
  • 按时间排序的数据:可以使用 Zset 存储按时间戳排序的消息、事件、日志等,支持按时间范围快速查询。
  • 优先队列:由于 Zset 提供了分值的排序功能,它可以实现优先级队列,按照任务的优先级进行调度。

zset数据结构的特点

  1. 元素唯一:Zset 中的每个元素(member)都是唯一的,但分值(score)可以重复。
  2. 有序性:Zset 中的元素按照分值进行排序,支持按分值或按元素的插入顺序进行操作。
  3. 分值可以重复:虽然 Zset 中的元素是唯一的,但不同元素可以有相同的分值。
  4. 支持范围查询:可以根据分值范围来获取集合中的元素,适合实现排行榜、排名等功能。
  5. 高效的插入、删除、查找:Zset 使用跳表(SkipList)实现,保证在 O(log N) 的时间复杂度下进行插入、删除、更新和范围查询操作。

zset数据结构和内部编码

当zset中数据较少时,使用ziplist存储,反之使用跳表存储(SkipList).

ziplist(压缩列表)

当有序集合的元素个数⼩于 zset-max-ziplist-entries 配置(默认 128 个), 同时每个元素的值都⼩于 zset-max-ziplist-value 配置(默认 64 字节)时,Redis 会⽤ ziplist 来作 为有序集合的内部实现,ziplist 可以有效减少内存的使.

跳表(SkipList)

  • 简介:跳表是一种可以替代平衡树的有序数据结构,具有多层链表结构。通过为链表增加多级索引,跳表能够在 O(log N) 时间内进行插入、删除和查找操作。
  • 作用:跳表用于按照分值顺序存储 Zset 中的元素,并支持范围查询、排序等操作。
  • 优点:插入和删除的效率稳定,能够处理大量数据,且实现较为简单。

总结

这篇文章主要介绍了redis中外部的数据结构和内部数据结构的编码.

下篇将主要对这些数据结构进行操作以及操作命令讲解.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2149115.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

OpenCV特征检测(3)计算图像中每个像素处的特征值和特征向量函数cornerEigenValsAndVecs()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 计算图像块的特征值和特征向量用于角点检测。 对于每一个像素 p ,函数 cornerEigenValsAndVecs 考虑一个 blockSize blockSize 的邻…

Java 在 GIS 领域的学习路线?

Java是一门广泛应用于企业级开发的编程语言,而GIS则是一种常用于地理信息处理和分析的技术。将Java与GIS结合起来,可以在企业级应用中实现更多的功能和业务需求,且在实际领域越来越广泛。 Java在GIS中重要的作用 1、跨平台性 Java具有跨平台…

基于C语言+SQL Server2008实现(控制台)图书管理系统

第1章 概述 1.1项目背景 随着科技的发展,尤其是计算机技术的迅猛发展,图书馆管理的问题从以往的人工管理,到现在的电脑化,系统化,是对图书馆管理方法的质的飞跃,这些技术不仅让图书馆管理变得更加方便、快…

美国联邦基金有效利率及目标利率历史数据集(1990.1-2024.9)

美联储在2024年9月18日宣布将其调50个基点,降至4.75%至5.00%之间的水平。这是美联储自2020年3月以来首次降息,也是自2023年7月将利率水平调升至历史高位后的首次下调,标志着货币政策由紧缩周期向宽松周期的转向。一、数据介绍 数据名称&…

web基础—dvwa靶场(八)XSS

XSS(DOM) 跨站点脚本(XSS)攻击是一种注入攻击,恶意脚本会被注入到可信的网站中。当攻击者使用 web 应用程序将恶意代码(通常以浏览器端脚本的形式)发送给其他最终用户时,就会发生 XSS 攻击。允许这些攻击成…

网络-内核是如何与用户进程交互

1、socket的直接创建 net/socket.cSYSCALL_DEFINE3(socket, int, family, int, type, int, protocol) {...retval sock_create(family, type, protocol, &sock);... }int sock_create(int family, int type, int protocol, struct socket **res) {return __sock_create(cu…

字符串函数的使用与模拟(2)——C语言内存函数

目录 1. memcpy函数的使用与模拟 2. memmove函数的使用与模拟 3. memset函数的使用 4. memcmp函数的使用 5. memchr函数的使用 前言&#xff1a;C语言内存函数是一组用于直接操作计算机内存的内置函数。使用时要包含头文件<string.h> 1. memcpy函数的使用与模拟 函…

【MYSQL表的增删改查(进阶)】

MYSQL表的增删改查&#xff08;进阶&#xff09; 一、新增二、查询2.1 聚合查询2.1.1 聚合函数count&#xff08;&#xff09;sum&#xff08;&#xff09;AVG&#xff08;&#xff09;MAX&#xff08;&#xff09;&#xff0c;MIN&#xff08;&#xff09;GROUP_CONCAT() 2.1.…

前端学习杂乱记录

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、Html二、CSS1. BFC布局2. 定位总结3. 动画1. transform变换2. transition过渡3. keyframes 和 animation 3. 伸缩盒模型&#xff1a;flex布局 三、JS1. 逻辑中断…

nvm安装实现node多版本的切换

nvm安装实现node多版本的切换 方式一 下载安装包安装下载安装包解压安装设置 nvm 环境变量查看 nvm 是否安装完成安装 node 环境切换 node 版本列出已经安装的版本 方式二 一键脚本安装下载安装查看 nvm 是否安装完成安装 node 环境切换 node 版本列出已经安装的版本nvm相关命令…

PyTorch中的学习率预热(warmup)

PyTorch提供了学习率调度器(learning rate schedulers)&#xff0c;用于在训练过程中实现各种调整学习率的方法。实现在torch.optim.lr_scheduler.py中&#xff0c;根据epoch数调整学习率。大多数学习率调度器可以称为背对背(back-to-back)&#xff0c;也称为链式调度器&#x…

Linux入门2

文章目录 一、Linux基本命令1.1 文件的创建和查看命令1.2 文件的复制移动删除等命令1.3 查找命令1.4 文件的筛选和管道的使用1.5 echo、tail和重定向符 二、via编辑器三、权限控制3.1 root用户&#xff08;超级管理员&#xff09;3.2 用户和用户组3.3 权限信息3.4 chmod命令 一…

Streamlit:使用 Python 快速开发 Web 应用

一、简单介绍 Streamlit 是一个开源 Python 库&#xff0c;官网地址&#xff1a; https://streamlit.io/http://StreamlitStreamlit 是一个开源的 Python 框架&#xff0c;旨在为数据科学家和 后端工程师们提供只需几行代码即可创建动态数据应用的功能。 让没有任何前端基础…

C#软键盘设计字母数字按键处理相关事件函数

应用场景&#xff1a;便携式设备和检测设备等小型设备经常使用触摸屏来代替键盘鼠标的使用&#xff0c;因此在查询和输入界面的文本或者数字输入控件中使用软件盘来代替真正键盘的输入。 软键盘界面&#xff1a;软键盘界面实质上就是一个普通的窗体上面摆放了很多图片按钮&…

使用SpringCloud构建可伸缩的微服务架构

Spring Cloud是一个用于构建分布式系统的开源框架。它基于Spring Boot构建&#xff0c;并提供了一系列的工具和组件&#xff0c;用于简化开发分布式系统的难度。Spring Cloud可以帮助开发人员快速构建可伸缩的微服务架构。 要使用Spring Cloud构建可伸缩的微服务架构&#xff0…

实时监控局域网计算机桌面怎么设置!五个可实现的方法分享,绝了!

员工在工作时间里究竟在做什么&#xff1f;他们的网络活动是否合规&#xff1f;如何确保敏感信息不被泄露&#xff1f; 在企业管理层面&#xff0c;实时监控局域网计算机桌面已成为提升工作效率、确保数据安全与规范员工行为的重要手段。 技术的不断进步&#xff0c;多种解决…

【C++进阶】map和set的使用

【C进阶】map和set的使用 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;C&#x1f96d; &#x1f33c;文章目录&#x1f33c; 1. 序列式容器和关联式容器 2. set系列的使用 2.1 set 和 multiset 2.2 set 类的介绍 2.3 set 的构造和…

【Linux篇】常用命令及操作技巧(基础篇)

&#x1f30f;个人博客主页&#xff1a;意疏-CSDN博客 希望文章能够给到初学的你一些启发&#xff5e; 如果觉得文章对你有帮助的话&#xff0c;点赞 关注 收藏支持一下笔者吧&#xff5e; 阅读指南&#xff1a; 开篇说明帮助命令常见的七个linux操作终端实用的技巧跟文件目录…

C++11之统一的列表初始化

一.{}初始化 在c98中&#xff0c;标准允许使用{}对数组或结构体元素进行统一的列表初始值设定&#xff1a; struct mess {int _x;string _str; }; int main() {//注意&#xff0c;使用new的一定是指针int* arr new int[4] {1, 2, 3, 4};//数组初始化int arr[] { 1,3,5,6 };…

基于Spring Boot和Vue的私人牙科诊所系统的设计与实现(毕业论文)

目 录 1 前言 1 1.1 研究目的与意义 1 1.2 国内外研究概况 1 1.3 主要研究内容 2 1.4 论文结构 3 2 系统分析 3 2.1 可行性分析 3 2.1.1 技术可行性分析 3 2.1.2 经济可行性分析 3 2.1.3 操作可行性分析 4 2.1.4 法律可行性分析 4 2.2 需求分析 4 2.2.1 管理员需求分析 4 2.2.2…