当前位置: 首页 > ds >正文

【Redis——数据类型和内部编码和Redis使用单线程模型的分析】

文章目录

  • Redis的数据类型和内部编码
  • 单线程模型的工作过程
  • Redis虽然是一个单线程模型,为啥效率那么高,速度快呢?


在这里插入图片描述
在这里插入图片描述
总而言之,Redis提供的哈希表容器并不一定真的是真的哈希表,而是在特点的场景下,用别的容器去实现,为了保证时间复杂度符合承诺(就是为了高效)

Redis的数据类型和内部编码

在这里插入图片描述

string
(由于只学过C++,这里只站在C++的角度理解Redis中的数据结构

  • raw:最基本的字符串,底层就是持有一个char数组(C++)。
  • int:当value是一个整数时,此时redis可能用int来保存。
  • embstr:针对短字符串进行的特殊优化。

以上内部编码方式Redis会自动适应,在使用时感知不到。

hash:

  • hashtable:虽然有可能实现方式不太一样,但是整体的思想跟C++的哈希表是一样的。
  • ziplist:压缩列表,在哈希表元素较少的时候,可能优化成ziplist压缩列表,就能够节省空间。因为元素较少,所以遍历的时候仍然能视为O(1)的时间复杂度。

为啥要压缩,为啥要节省时间呢?
因为在key特别多的情况下,如果key对应的value都是哈希表,则对应的hash也特别多,但是每个hash又不大的情况下,就可以将这些hash压缩,让整体占用内存更少。

list:

  • linkedlist:链表,就是数据结构中熟悉的那个链表,包括单链表,双链表。
  • ziplist:如果元素个数少,就用压缩列表实现,因为节省空间,如果元素个数多,那就会用链表。
    从redis3.2版本开始,引入了新的实现方式:quicklist,这个就同时兼顾了linkedlist和ziplist的优点。
    可以认为quicklist就是一个链表,链表的每个元素是ziplist。这样的折中方案把空间和效率都兼顾了。
    所以quicklist就比较像C++的deque。

set:

  • hashtable:这个跟前面那个讲解一样,看上面那个即可。
  • intset:针对特定场景的优化:比如集合中都是一个整数,就优化成intset

zset:

  • skiplist:跳表。在链表的笔试题中,有一道题叫做:“复杂链表的复制”,除了有一个next指向下一个节点外,还有一个Random节点指向其他随机节点。这里的跳表同理,每个节点上有多个指针域的指向,巧妙的搭配这些指针域的指向,就能做到查找时的时间复杂度O(logN)

  • ziplist:看上面的解释

通过object encoding key来查看key对应的value的编码方式。
比如:

set key1 1
object encoding key1,可以得到key1对应的value的编码方式是int

单线程模型的工作过程

在这里插入图片描述

Redis虽然是一个单线程模型,为啥效率那么高,速度快呢?

(面试题)(说Redis快的参照物是关系型数据库:MySQL等)

  • 1.redis访问内存,MySQL访问硬盘。
  • 2.redis的核心功能比数据库的核心功能简单。比如针对插入删除,数据库的各种约束(主键约束,外键约束),在插入时,会先判断在不在,判断完成后,还得找个位置插入。这样同样又会有消耗。
  • 3.单线程模型避免了不必要的线程竞争开销。Redis的每个基本操作都是短平快的,就是简单地操作内存,没多大消耗CPU,就算搞个多线程提升不大(具体得看业务场景)。
  • 4.处理网络IO时,使用了epoll的I/O多路复用。一个线程可以管理多个socket,对TCP来说,当客户端到来时,都要给该客户端设置一个socket,并且在很多情况下,大部分客户端的通信并没有那么频繁,而是仅仅有少量客户端是活跃的。但是在传统的IO时,是为一个客户端创建一个线程专门服务的。而大部分客户端只发了几次数据就不活跃了。此时线程也会被阻塞住,而线程创建,销毁,调度都是消耗性能的操作。所以使用I/O多路服用,让一个线程同时监听处理多个socket,大大提高了效率。(但是,一个线程监听多个socket是只有当这些socket只有少量是活跃的时候才能这样做。否则这些socket如果同时非常活跃,就可能导致线程忙不过来。打游戏+和女朋友打电话的例子)
http://www.xdnf.cn/news/3065.html

相关文章:

  • EtherCAT 分布式时钟(DC)补偿技术解析
  • React Native 动态切换主题
  • 使用js写一个发布订阅者
  • 给 BBRv2/3 火上浇油的 drain-to-target
  • 26考研 | 王道 | 计算机网络 | 第一章 计算机网络的体系结构
  • Python核心机制与实战技巧:从变量作用域到GIL的深度解析
  • 基于Springboot + vue实现的列书单读书平台
  • 技术赋能与模式重构:开源AI大模型驱动下的“一盘货”渠道革命——基于美的案例与S2B2C生态融合的实证研究
  • 部署一个自己的Spring Ai 服务(deepseek/通义千问)
  • 20250429 垂直地表发射激光测量偏转可以验证相对性原理吗
  • 学习海康VisionMaster之线圆测量
  • 一个SciPy图像处理案例的全过程
  • java 加入本地lib jar处理方案
  • 暑假里系统学习新技能(马井堂)
  • AWS创建多块盘并创建RAID0以及后增加空间
  • 【OSG学习笔记】Day 14: 操作器(Manipulator)的深度使用
  • Go语言Context机制深度解析:从原理到实践
  • 【Java核心】一文理解Java面向对象(超级详细!)
  • 测试基础笔记第十六天
  • 【沉浸式求职学习day29】【信科知识面试题第一部分】【新的模块,值得收藏】
  • Opencv中图像深度(Depth)和通道数(Channels)区别
  • 嵌入式复习第一章
  • 基于C++的IOT网关和平台1:github项目ctGateway
  • ppt箭头素材图片大全
  • Python实例题:ebay在线拍卖数据分析
  • OpenAI Embedding 和密集检索(如 BERT/DPR)进行语义相似度搜索有什么区别和联系
  • Transformer-LSTM-SVM回归
  • 扣子流程图批量导入飞书多维表格
  • 如何在Java中去除字符串中的空格?
  • 16、路由守卫:设置魔法结界——React 19 React Router