面试题:Redis常用数据结构

news2024/11/27 20:58:21

1 string

基本编码方式,基于简单动态字符串(SDS)实现,存储上线为512mb.

如果存储的SDS长度小于44字节,则会采用EMBSTR编码,此时object head与SDS是一段连续空间。申请内存时只需要调用一次内存分配函数,效率更高。

如果存储的字符串是整数值,并且大小在LONG MAX范围内,则会采用INT编码:直接将数据保存在Redisobjiect的ptr指针位置(刚好8字节),不再需要SDS了。

结论
RAW会有两次内存分配,效率较低
如果sds长大衣小于44字节,则会使用EMBSTR编码方式,只分布一次内存
INT编码方式,则sds中存储的是正数值,且数值范围小于Long.Max

2 List

Redis的List类型可以从首尾操作。

根据List的操作可以使用如下的编码方式。

  • LinkedList:普通链表,可以从双端访问,内存占用较高,内存碎片较多

  • ZipList: 压缩列表,可以从双端访问,内存占用低,存储上限低

  • QuickList : LinkedList + zipList,可以从双端访问,内存占用较低,包含多个ZipList,存储上限高

/* LPUSH <key> <element> [<element> ...] */
void lpushCommand(client *c) {
    pushGenericCommand(c,LIST_HEAD,0);
}

/* RPUSH <key> <element> [<element> ...] */
void rpushCommand(client *c) {
    pushGenericCommand(c,LIST_TAIL,0);
}
/* Implements LPUSH/RPUSH/LPUSHX/RPUSHX. 
 * 'xx': push if key exists. */
 // where 表示从头插还是尾插
void pushGenericCommand(client *c, int where, int xx) {
    int j;
        // 将命令存放到argv中 LPUSH key v1 v2
    for (j = 2; j < c->argc; j++) {
        if (sdslen(c->argv[j]->ptr) > LIST_MAX_ITEM_SIZE) {
            addReplyError(c, "Element too large");
            return;
        }
    }
    // 找到key对象的list
    robj *lobj = lookupKeyWrite(c->db, c->argv[1]);
    // 类型校验
    if (checkType(c,lobj,OBJ_LIST)) return;
    // 检查是否为空,list不存在
    if (!lobj) {
        if (xx) {
            addReply(c, shared.czero);
            return;
        }
        // 创建quickList
        lobj = createQuicklistObject();
        // ziplist的限制
        quicklistSetOptions(lobj->ptr, server.list_max_ziplist_size,
                            server.list_compress_depth);
        dbAdd(c->db,c->argv[1],lobj);
    }

    for (j = 2; j < c->argc; j++) {
        listTypePush(lobj,c->argv[j],where);
        server.dirty++;
    }

    addReplyLongLong(c, listTypeLength(lobj));

    char *event = (where == LIST_HEAD) ? "lpush" : "rpush";
    signalModifiedKey(c,c->db,c->argv[1]);
    notifyKeyspaceEvent(NOTIFY_LIST,event,c->argv[1],c->db->id);
}

3 Set

Set是Redis中的单列集合,满足下列特点

  • 不保证有序

  • 元素唯一(可以判断元素是否存在)

  • 求交集、并集和差集

使用IntSet 或者 hash 结构。为了查询效率和唯一性,set采用HT编码 (Dict)。Dict中的key用来存储元素,value统一为null。

当存储的 所有数据都是整数 ,并且元素数量不超过set-max-intset-entries时,Set会采用IntSet编码,以节省内存。

4 ZSet

ZSet也就是SortedSet,其中每一个元素都需要指定一个score值和member值

  • 可以根据score值排序后

  • member必须唯一

  • 可以根据member查询分数

使用 sikpList 或者 (Dict) 结构

  • skipList:可以排序,并且可以同时存储score和ele值 (member)。无法根据member找score

  • HT (Dict):可以键值存储,并且可以根据key找value。无法排序

缺点:数据冗余,内存占用过高。

当元素数量不多时,HT和SkipList的优势不明显,而且更耗内存。因此zset还会采用ZipList结构来节省内存,不过需要同时满足两个条件:

  • 元素数量小于zset max ziplist entries,默认值128

  • 每个元素都小于zset max ziplist value字节,默认值64

插入元素时

ziplist本身没有排序功能,而且没有键值对的概念,因此需要有zset通过编码实现:

  • ZipList是连续内存,因此score和element是紧挨在一起的两个entry,element在前,score在后

  • score越小越接近队首,score越大越接近队尾,按照score值升序排列。

5 Hash

Hash结构与Redis中的Zset非常类似

  • 都是键值存储

  • 都需求根据键获取值

  • 键必须唯一

  • Hash结构默认采用ZipList编码,用以节省内存。ZipList中相邻的两个entry 分别保存field和value。

  • 当数据量较大时Hash结构会转为HT编码,也就是Dict,触发条件有两个:

  • ZipList中的元素数量超过了hash-max-ziplist-entries(默认512)

  • ZipList中的任意entry大小超过了hash-max-ziplist-value(默认64字节)

在不满足上述要求时会转换为HT

总结

  • String 底层采用RAW、 EMBSTRINT类型的编码。当SDS字节数不超过44字节时采用 EMBSTR,当为整数值时采用INT类型编码

  • List 底层采用quickList

  • Set 底层采用 使用IntSet 或者 hashtable 结构,当值都为整数时采用IntSet,一般采用hash,其value为null.

  • Zset 底层采用 SkipList +hashtable 或者 ziplist 结构

  • hash 底层采用zipList 和 hashtable 。

  • 采用ziplist的原因是在小数据量情况下,效率高而且内存占用少。

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

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

相关文章

【官方 | 计算机二级Python教程】第九章:Python标准库概览

【官方 | 计算机二级Python教程】第九章&#xff1a;Python标准库概览参考书目第九章&#xff1a;Python标准库概览本章知识导图10.1 turtle库10.2 random库10.3 time库习题本文代码编译环境及版本更新日志参考书目 拜读的是计算机等级考试官方推荐教程 《全国计算机等级考试二…

JavaScript入门

介绍:JavaScript(通常缩写为JS)是一门基于原型和头等函数的多范式高级解释型编程语言, 它支持面向对象程序设计、指令式编程和函数式编程。它提供方法来操控文本、数组、日期和正则表达式等。不支持I/O, 比如网络、存储和图形等, 但这些都可以由它的宿主环境提供支持。目前它被…

以太网知识-GMII / RGMII接口

今天和海翎光电的小编一起分析MII/RMII/SMII&#xff0c;以及GMII/RGMII/SGMII接口的信号定义&#xff0c;及相关知识&#xff0c;同时小编也对RJ-45接口进行了总结&#xff0c;分析了在10/100模式下和1000M模式下的连接方法。GMII 接口分析GMII接口提供了8位数据通道&#xff…

“青春树儿童摄影网”首页制作

“青春树儿童摄影网”首页制作一、实验名称&#xff1a;二、实验日期&#xff1a;三、实验目的&#xff1a;四、实验内容&#xff1a;五、实验步骤&#xff1a;六、实验结果&#xff1a;七、源程序&#xff1a;八、心得体会&#xff1a;一、实验名称&#xff1a; “青春树儿童…

Nginx转发http到https和开机自动启动

场景&#xff1a; 以下都是基于windows系统&#xff08;ip为虚构&#xff09; 1.ip:172.16.54.55需要访问172.16.54.57的接口服务&#xff0c;来查看机械臂的运行状况 2.存在网络隔离&#xff0c;172.16.54.55无法直接访问172.16.54.57 3.172.16.54.56与172.16.54.57是机械…

reac面试题

1.React有什么特点&#xff1f;&#xff08;react的主要功能有哪些&#xff1f;&#xff09; 它用于虚拟DOM&#xff0c;组件化设计模式&#xff0c;声明式代码&#xff0c;单向数据流&#xff0c;使用jsx描述信息等特点 2.什么是组件化设计模式 复用的代码可以抽成组件共同…

VS Code 1.75 发布!

欢迎使用 2023 年 1 月版的 Visual Studio Code。希望您喜欢此版本中的许多更新&#xff0c;其中一些主要亮点包括&#xff1a;配置文件、VS Marketplace 签名、辅助功能改进、更轻松地调整多视图大小、树视图搜索历史、新的 Git 命令等等。让我们一起看看吧&#xff01; 配置文…

真实还原项目案例

真实模拟项目案例&#xff1a; 核心和出口用ospf&#xff0c;出口ospf路由用 default-route-advertise always 解决默认路由。 其它的都是常规的就不说了&#xff0c;都在配置里看配置。 出口路由配置&#xff1a; [H3C]dis current-configuration version 7.1.064, Release 04…

中国大学mooc 机器人操作系统讲义以及部分笔记

这里写目录标题二进制与源码包1.7 安装RoboWare Studio新的连接配套代码 官方看了一下课程官方的讲义连接&#xff0c;似乎很多页面已经丢失&#xff1f;或者是未授权&#xff1f;二进制与源码包 https://sychaichangkun.gitbooks.io/ros-tutorial-icourse163/content/chapter…

Web3中文|太心急!谷歌匆忙上线自家“ChatGPT”导致市值蒸发逾千亿美元

谷歌想证明它可以在AI竞赛中与微软抗衡&#xff0c;创建一个新的人工智能搜索引擎&#xff0c;但一个错误回答最终导致母公司 Alphabet 的市场损失超过千亿美元。 低开低走的美股市场 周三&#xff0c;美股三大指数低开低走。道琼斯指数收盘下跌207.68点&#xff0c;跌幅0.61%…

设计模式之单例模式(C++)

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 一、单例模式是什么&#xff1f; 单例模式是一种创建型的软件设计模式&#xff0c;在工程项目中非常常见。通过单例模式的设计&am…

具有大部分相似的项目之间的项目整合

1.将多个项目文件合并&#xff0c;如&#xff1a;c2文件夹和c3文件夹不同&#xff0c;其余文件都是可以一起用的 2. router/index.js (1) 声明 公用路由&#xff0c;如 const common [{// :xxxx 代表任意匹配&#xff08;输啥都可以匹配&#xff09;path: /:channel/login,c…

html 浏览器存储方式

浏览器有三种本地存储方式&#xff1a; 1、localstorage 2、sessionStorage 3、cookie 浏览器 F12 打开调试模式&#xff0c;可以看到&#xff1a; 点击对应域名&#xff0c;可以看到当前域名下存储的数据&#xff0c;是以key&#xff0c;value形式存储的。 三种方式的共同…

某程序员去华为面试,因为错了一道题而被淘汰

题目有一道数学的逻辑题&#xff0c;这种提一般智商测试或者公务员考试中经常见到&#xff0c;传说华为有道面试题是这样的&#xff0c;求出下划线的数字应该是多少&#xff1f;请准备好纸和笔&#xff0c;思考10分钟&#xff0c;看看你能否得出正确答案。1分钟后。。。2分钟后…

MySQl学习(从入门到精通11)

MySQl学习&#xff08;从入门到精通11&#xff09;第 14 章_视图1. 常见的数据库对象2. 视图概述2. 1 为什么使用视图&#xff1f;2. 2 视图的理解3. 创建视图3. 1 创建单表视图3. 2 创建多表联合视图3. 3 基于视图创建视图4. 查看视图5. 更新视图的数据5. 1 一般情况5. 2 不可…

餐饮企业数据可视化大屏(智慧餐饮)

随着信息技术的深入发展&#xff0c;数据大屏的适用场景日益广泛&#xff0c;集工作汇报、实时监控和预测分析等功能于一身。 数据可视化的本质是视觉对话&#xff0c;数据可视化将数据分析技术与图形技术结合&#xff0c;清晰有效地将分析结果信息进行解读和传达。 当前很多餐…

第八天字符串

344.反转字符串力扣题目链接(opens new window)编写一个函数&#xff0c;其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。不要给另外的数组分配额外的空间&#xff0c;你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。你可以假设数组中…

数据结构|绪论

&#x1f525;Go for it!&#x1f525; &#x1f4dd;个人主页&#xff1a;按键难防 &#x1f4eb; 如果文章知识点有错误的地方&#xff0c;请指正&#xff01;和大家一起学习&#xff0c;一起进步&#x1f440; &#x1f4d6;系列专栏&#xff1a;数据结构与算法 &#x1f52…

基于STM32设计的音乐播放器

一、项目背景与设计思路 1.1 项目背景 时代进步,科学技术的不断创新,促进电子产品的不断更迭换代,各种新功能和新技术的电子产品牵引着消费者的眼球。人们生活水平的逐渐提高,对娱乐消费市场需求日益扩大,而其消费电子产品在市场中的占有份额越来越举足轻重。目前消费电…

FPGA纯verilog代码读写N25Q128A QSPI Flash 提供工程源码和技术支持

目录1、N25Q128A芯片解读2、N25Q128A读写时序3、整体设计思路架构4、verilog读写Flash驱动设计5、verilog读写Flash控制器设计6、FIFO缓存设计7、串口输出Flash读取数据8、vivado工程介绍9、上板调试验证并演示10、福利&#xff1a;工程源码获取1、N25Q128A芯片解读 N25Q128A的…