常见面试题-Redis底层的SDS、ZipList、ListPack

Redis 的 SDS 了解吗?

答:

Redis 创建了 SDS(simple dynamic string) 的抽象类型作为 String 的默认实现

SDS 的结构如下:

struct sdshdr {
  // 字节数组,用于保存字符串
  char buf[];
  // buf[]中已使用字节数量,称为SDS的长度
  int len;
  //  buf[]中尚未使用的字节数量
  int free;
}

为什么 Redis 不使用 C 语言默认的字符串呢?(Redis 是用 C 实现的)

  • 提升获取长度性能:使用 SDS 可以以 O(1) 的时间复杂度取到字符串的长度,因为 SDS 中存储了字符串的长度;在 C 语言的字符串中,需要遍历才可以获取长度

  • 保障二进制安全:C 字符串只能包含符合某种编码格式的字符,如 ASCII、UTF-8,并且除了字符串末尾外,不能含有 '\0',这是因为 C 字符串是以 '\0' 结尾的,而在视频、图片中的数据以 '\0' 作为分隔符很常见,因此 C 字符串无法存储这些数据;而在 SDS 中存储了字符串的长度,因此不需要分隔符

  • 减少内存再分配数:SDS 采用了空间预分配策略,每次 SDS 进行空间扩展时,程序会同时分配所需空间和额外的未使用空间,以减少内存的再分配次数。额外分配的未使用空间大小取决于空间扩展后SDS的len属性值。

    • 如果len < 1M,那么分配的未使用空间大小与 len 相同
    • 如果len >= 1M,那么分配的未使用空间大小为 1M

    SDS 也采用了惰性空间释放策略,即 SDS 字符串长度变短,并不会立即释放空间,而是将未使用的空间添加到 free 中,以便后期扩展 SDS 时减少内存分配次数

Redis 的 zipList

答:

Redis 的压缩列表即 ziplist,可以包含多个节点,每个节点可以保存一个长度受限的字符数组或者整数

因为 ziplist 节约内存的性质,哈希键、列表键和有序集合键初始化的底层实现皆采用 ziplist

ziplist 底层结构由 3 部分组成:head、entries、end,这三部分在内存上连续存放

  • head

    head由三部分组成

    • zlbytes:占4B,表示 zipList 整体所占字节数,包括 zlbytes 本身长度
    • zltail:占4B,用于存放 zipList 最后一个 entry 在整个数据结构中的偏移量,可用于定位链表末尾的 entry
    • zllen:占2B,存放列表包含的 entry 个数
  • entries

    entries 是真正的列表,由很多 entry 构成,由于元素类型、数值不同,每个 entry 的长度也不同

    entry由三部分组成

    • prevlength:记录上一个 entry 的长度,用于逆序遍历,默认长度为 1 字节,如果上一个 entry 的长度 >= 254B,prevlength 就会扩展为 5B
    • encoding:标志后面的 data 的具体类型。如果 data 为整数,encoding 固定长度为1B,如果data为字符串,encoding可能为1B、2B、5B,data字符串不同的长度,对应着不同的encoding长度
    • data:真正存储的数据,数据类型只能是整数或字符串
  • end

    end只包含一部分,称为 zlend,占1B,值为255,也就是8个1,表示 zipList 列表的结束

在这里插入图片描述

Redis 的 listPack

答:

Redis 的 zipList 存在一些缺点:

  • 实现复杂,为了实现逆序遍历,每一个 entry 都存储了前一个 entry 的长度,这样在插入和更新时可能会造成连锁更新

    连锁更新举例:假如 ziplist 中每一个 entry 都是很接近但又不到 254B,此时每个 entry 的 prevlength 使用 1 个字节就可以保存上个节点的长度,但是此时如果向 ziplist 中间插入一个新的节点,长度大于 254B,那么新插入节点后边的节点需要把 prevlength 扩展为 5B 来存储新插入节点的长度,那么扩展后该节点长度又大于 254B,因此后边节点需要再次扩展 prevlength 来存储该节点的长度,导致了插入节点后边的所有节点都需要更新 prevlength 的值,这属于是极端情况下才会发生

因此为了更好的性能,在 Redis7.0 中,将 ziplist 全部替换为了 listpack,但是为了兼容,还是保留了 ziplist 的相关属性

  • head

    head包括两部分:

    • totalBytes:占4B,存放 listPack 整体所占字节数,包含 totalBytes 本身
    • elemNum:占 2B,存放 entry 个数
  • entries

    entries是真正的列表,由很多entry组成,每个entry长度不同

    entry包括三部分(删除了prevlength,增加了element-total-len)

    • encoding:标志后面的 data 的具体类型。如果 data 为整数,encoding 固定长度为 1B,如果 data 为字符串,encoding 可能为 1B、2B 或 5B,data 字符串不同的长度,对应着不同的 encoding 长度
    • data:存储真正数据
    • element-total-len:记录当前 entry 长度,用于实现逆序遍历,占1、2、3、4或5字节

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

介绍YOLO-NAS Pose:姿势估计的技术

YOLO-NAS 姿势 YOLO-NAS Pose models是对 Pose Estimation 领域的最新贡献。今年早些时候,Deci 因其突破性的目标检测基础模型 YOLO-NAS 获得了广泛认可。在 YOLO-NAS 成功的基础上,该公司现在推出了 YOLO-NAS Pose 作为其姿势估计的对应产品。该姿势模型在延迟和准确性之间…

linux入门---自旋锁和读写锁

自旋锁 首先通过一个例子来带着大家理解自旋锁&#xff0c;在生活中大家肯定都等过人比如你们一家人准备出去玩可是出发的时候妻子发现自己还没有化妆于是连忙赶回了家这个时候其他人就得在楼下等着&#xff0c;但是这个等又分为两种情况第一种是真的在楼下等其他的什么事都没…

DeCLIP 论文阅读

DeCLIP:supervision exists everywhere:a data efficient contrastive language-image pre-training paradigm 贡献&#xff1a; 论文是为了充分利用单模态和多模态&#xff0c;充分利用单模态特征用自监督&#xff08;SIMSAM和MLM&#xff09;&#xff0c;多模态用图像文本对…

P6入门:项目初始化4-项目详情之预算日志及汇总Budget

前言 使用项目详细信息查看和编辑有关所选项目的详细信息&#xff0c;在项目创建完成后&#xff0c;初始化项目是一项非常重要的工作&#xff0c;涉及需要设置的内容包括项目名&#xff0c;ID,责任人&#xff0c;日历&#xff0c;预算&#xff0c;资金&#xff0c;分类码等等&…

ELK之Logstash解析时间相差8h的问题

一、问题描述 服务器当前时间为&#xff1a;2022年 06月 28日 星期二 11:24:22 CST 而logstash解析的时间为2022-06-28T03:15:25.545Z与实际时间相差8h 一、解决办法&#xff1a; 需改logstash的配置文件&#xff1a; 原理就是&#xff1a;定义一个中间变量timestamp&…

Unity如何保存场景,如何导出工程文件/如何查看保存位置?【各版本通用】

如何保存场景&#xff1f; 在unity中CtrlS 或者File—>Save 输入你要保存的场景名【建议保存在Scenes文件夹下】 下图&#xff0c;保存场景不在Scenes文件夹下&#xff1a; 下图&#xff0c;保存在Scenes文件夹下&#xff1a; 下图&#xff0c;保存完成 如何导出工程文…

nginx配置和热部署实践

目录 一、nginx配置文件 1.配置文件 2.nginx配置文件语法 3.include 二、nginx.conf参数 1.user参数 2.nginx.conf重要的指令块 3.nginx命令行 三、nginx热部署功能实践 1.热部署的特点 2.大致流程 3.环境准备 4.备份旧nginx二进制文件 5.下载编译安装新的nginx …

Mac电脑配置Flutter开发环境

1.进入官网下载页&#xff1a; Flutter SDK releases | Flutter 可以看到有 Windows、macOS、Linux三种系统的下载包 选择macOS&#xff0c;然后点击下载 Stable channel&#xff08;稳定版&#xff09;中的最新版本&#xff0c;下载完成后可以移动到资源库Library中。 2.下载…

Unity Input System最简单使用

开始学的是 Input Manager 比较好理解&#xff0c;Input System却不好理解&#xff0c;教程也找了很多&#xff0c;感觉都讲的不清楚&#xff0c;我这里做一个最简单的用 Input System 添加鼠标左键和右键的效果。 1. 安装 Input System 包 首先这个功能不是内置的&#xff0…

Flutter笔记:使用Flutter构建响应式PC客户端/Web页面-案例

Flutter笔记 使用Flutter构建响应式PC客户端/Web页面-案例 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://blog.csdn.net/qq_28550263/article/detai…

红黑树,AVLTree树(平衡二叉树)迭代器原理讲解

红黑树&#xff0c;AVLTree树底层实现逻辑都是平衡二叉树&#xff08;AVLTree高度平衡&#xff0c;红黑树以某种规则平衡&#xff09;&#xff0c;但终究不像链表的迭代器那样逻辑简单。 简单叙述以下&#xff0c;二叉树上面迭代器的运行逻辑&#xff0c;根据下面的图&#xff…

leetcode-链表经典题

1.反转单链表 206. 反转链表https://leetcode.cn/problems/reverse-linked-list/这里我们使用创建一个变量cur来遍历原链表&#xff0c;再创建一个新节点newnode&#xff0c;首先使用一个循环来遍历原链表&#xff0c;cur为NULL是循环结束&#xff0c;每次进入循环将cur的下一…

.mallab勒索病毒数据恢复|金蝶、用友、管家婆、OA、速达、ERP等软件数据库恢复

导言&#xff1a; .mallab勒索病毒是一种极具威胁性的数字病毒&#xff0c;通过高级加密算法深度侵袭用户文件&#xff0c;迫使受害者支付赎金以获取解密密钥。了解其侵害方式和对抗手段对数字安全至关重要。数据的重要性不容小觑&#xff0c;您可添加我们的技术服务号&#x…

threejs(12)-着色器打造烟雾水云效果

一、自己封装水波纹效果 src/main/main01.js import * as THREE from "three";import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"; import gsap from "gsap"; import * as dat from "dat.gui"; import ver…

【文件IO】

文章目录 File常见方法和属性属性构造方法方法 InputStream方法FileInputStream OutputStream利用 OutputStreamWriter 进行字符写入 总结按字节读取数据按字节写入数据按字符读取数据按字符写入数据 File常见方法和属性 属性 修饰符及类型属性说明static StringpathSeparato…

网络安全(黑客技术)-高效自学

1.网络安全是什么 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“安全运营”、“安全运维”则研究防御技术。 2.网络安全市场 一、是市场需求量高&#xff1b; 二、则是发展相对成熟…

思科设备静态路由配置

一、静态路由基本知识 路由器的主要功能就是用来转发IP 数据包以使数据包到达正确的目的主机。可以想象数据包到达路由器就像一辆汽车开到十字路口&#xff0c;路由表就类似路标&#xff0c;列出可能到达的目的地&#xff0c;以及应该选择哪条路到达目的地。 路由器必须要有相应…

Linux - 基础IO(重定向 - 重定向模拟实现 - shell 当中的 重定向)- 下篇

前言 上一篇博客当中&#xff0c;我们对 文件 在操作系统当中是 如何就管理的&#xff0c;这个问题做了 详细描述&#xff0c;本篇博客将基于上篇 博客当中的内容进行 阐述&#xff0c;如有疑问&#xff0c;请参考上篇博客&#xff1a; Linux - 基础IO&#xff08;Linux 当中…

应用层——HTTP协议

文章目录 HTTP协议1.HTTP简介2.认识URL3.urlencode和urldecode4.HTTP协议格式&#xff08;1&#xff09;HTTP请求协议格式&#xff08;2&#xff09;HTTP响应协议格式 5.HTTP的方法6.HTTP的状态码7.HTTP常见的Header8.Cookie和Session HTTP协议 1.HTTP简介 HTTP&#xff08;Hy…

mac安装brew

命令 /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"如图 选择下载源&#xff0c;进行安装 安装完成 验证