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

Redis ⑤-单线程模型 | 常用数据结构

在这里插入图片描述

常用数据结构

当前版本的 Redis 支持 10 多种数据结构,但主要使用的就只有 5 种。

  • String(字符串),相当于 Java 的 String 类型。
  • Hash(哈希),相当于 Java 的 HashMap 集合。
  • List(列表),相当于 Java 的 List 集合。
  • Set(集合),相当于 Java 的 Set 集合。
  • zset(有序集合),相当于存储了 member 之外,还存储了一个 score(分数,权重)。

实际上,Redis 在实现这些数据结构时,会在源码层面,针对某些情况进行特殊的优化,以节省空间或者时间。

也就是说,Redis 承诺你这是个 Hash,但实际的底层可能并不是一个真的 Hash,但起增删查改的时间复杂度确实都是 O(1)。

数据结构

Redis 承诺给你的,也可以理解为数据类型。

编码方式

Redis 内部底层的实现。

常用数据结构

数据结构编码方式
String(字符串)raw
int
embstr
Hash(哈希)hashtable
ziplist
List(列表)linkedlist
ziplist
Set(集合)hashtable
intset
zset(有序集合)skiplist
ziplist

在Redis 5.0 版本后,ziplist 被 listpack 替代,但本质还是一种压缩的链表,其目的还是为了优化

  • String(字符串)
    • raw:最基本的字符串,底层就是一个char数组(C++),byte数组(Java)。
    • int:整数,但值为整数时,会采用自动整数编码。
    • embstr:短字符串,针对短字符串进行的特殊优化。
  • Hash(哈希)
    • hashtable:哈希表,底层是一个哈希表,但还是和 Java 的 HashTable 不太一样。
    • ziplist:压缩列表,针对小规模数据进行的特殊优化,当哈希表里元素较少时,可能就会有化成压缩列表。
  • List(列表)
    • linkedlist:链表。
    • ziplist:压缩列表,针对小规模数据进行的特殊优化。
    • 从 Redis 3.2 开始,引入了新的实现方式:quicklist,同时兼顾了 linkedlist 和 ziplist 的优点。
    • quicklist 就是一个链表,但每一个元素又是一个 ziplist,这样就能达到压缩链表的效果。
  • Set(集合)
    • hashtable:哈希表。
    • intset:整数集合,存储的都是整数。
  • zset(有序集合)
    • skiplist:跳表,跳表也是链表,不用与普通的链表,每个节点上有多个指针域,巧妙的搭配这些指针域的指向,就可以做到从跳表上查询元素的时间复杂度为 O(logN)。
    • ziplist:压缩列表,针对小规模数据进行的特殊优化。

查看某个键对应的值的类型

object encoding key

Redis 线程模型

Redis 是一个单线程模型的程序,但这并不意味着其服务器进程内部就真的只有一个线程。

在处理 网络IO 时,最开始也是只采用一个线程来处理,通过 IO多路复用 的方式进行处理。通过使用 IO多路复用 的方式,Redis 便可以通过一个线程同时处理多个 socket。

Redis 对于读写命令,采用的是单线程模型,当有多个客户端发起请求处理时,Redis 会将请求放入一个队列中,然后逐个处理。

使用单线程模型,就使得 Redis 中的线程天然安全,所有请求都是串行执行的,不存在线程安全问题。

为什么单线程?

Redis 的核心业务逻辑都是 “短平快” 的,不太消耗 CPU 资源,也就不太吃多核性能,故使用单线程模型也能很好的工作。

使用单线程,使得其编程变得更加容易且易维护。

Redis 的操作都是基于内存的,因此其速度非常快,性能瓶颈不在 CPU 上,主要还是在 内存 和 网络上。

使用多线程就会有线程安全问题,存在死锁、上下文切换等问题,甚至会影响性能。

V4.0

However with Redis 4.0 we started to make Redis more threaded. For now this is limited to deleting objects in the background, and to blocking commands implemented via Redis modules. For the next releases, the plan is to make Redis more and more threaded.

然而,在 Redis 4.0 中,我们开始使 Redis 更加线程化。目前,这仅限于在后台删除对象,以及阻止通过 Redis 模块实现的命令。对于下一个版本,计划使 Redis 越来越线程化。
在 4.0 版本中,Redis 引入了多线程,但主要针对的是一些大键值对的删除命令,使用这些命令就会使用主线程之外的其他线程来异步处理,从而减少对主线程的影响。

在 4.0 版本中,Redis 增加了一些命令:UNLIKEFLUSHALL ASYNCFLUSHDB ASYNC等非阻塞的删除命令。

尽管在 4.0 版本中引入了多线程,但这并不违背 Redis 单线程模型的设计理念,不过是在部分命令上引入的,对于整体架构而言,其还是单线程模型。

V6.0

Redis 在 网络IO 方面,引入了对多线程的支持,由于 Redis 的主要性能瓶颈出现在内存和网络上,引入多线程,可以提高 网络IO 的效率。

尽管引入了多线程,依然不需要担心线程安全问题,这是因为 Redis 的多线程只是在网络数据读写时使用多线程,执行命令的操作,依然是单线程的。

Redis 的多线程是默认禁用的,可以通过修改配置文件的操作开启多线程。

Redis 虽然是单线程模型,为什么效率这么高,速度这么快?(面试题)

Redis 的快,是相比于 MySQL 这些关系型数据库的而言的,并不是和谁比都快。

Redis 是基于内存的,数据读写速度非常快,内存的读写速度是非常快的。而像 MySQL 这样的关系型数据库则是访问硬盘的,速度则要慢很多。

Redis 的核心功能比其他数据库的要简单很多。在其他数据库上,我们通过编写 SQL 语句可以实现一些复杂功能的操作,但是 Redis 是 NoSQL 的,所以,Redis 干的活少,其功能相比于其他数据库也是更少的。

Redis 采用单线程模型,避免了不必要的线程竞争和上下文切换问题,这就保证了其高效。

在处理网络 IO 时,Redis 采用了 IO 多路复用机制,可以同时处理多个 socket 请求,这就使得 Redis 能处理更多的请求,提高了处理能力。

相关文章:

  • 【SAP-CO】成本主数据
  • UWB定位技术在钢铁厂行业中的创新应用与价值实践
  • 代理设计模式:从底层原理到源代码 详解
  • 物理机检查磁盘坏道方式
  • prtobuf的原理
  • 【Luogu】动态规划一
  • TS-300B浊度传感器详解(STM32)
  • STM32单片机入门学习——第46节: [14-1] WDG看门狗
  • Redis在.NET平台中的各种应用场景
  • AI日报 - 2025年4月23日
  • 代理模式(Proxy Pattern)详解:以延迟加载图片为例
  • NLP高频面试题(五十)——大模型(LLMs)分词(Tokenizer)详解
  • 【C++】Json-Rpc框架项目介绍(1)
  • Agent框架LangGraph:实现一个简单的Plan-and-Execute Agent
  • 电子电器架构 --- 面向下一代车辆的演进式(发展演变的)汽车网关
  • 仅追加KV数据库
  • 实验一 进程控制实验
  • 2023蓝帽杯初赛内存取证-4
  • NVIDIA 自动驾驶技术见解
  • 从零到多智能体:Google Agent开发套件(ADK)入门指南
  • 大学2025丨本科专业大调整,教育专家:化解就业难背后供需错配
  • 美团回应京东“二选一”指控:没有任何理由对某平台进行任何限制
  • 广东音像城清退,发烧友紧急“淘宝”,曾见证广州音乐黄金期
  • 解除近70家煤电厂有毒物质排放限制,特朗普能重振煤炭吗?
  • 我国成功发射试验二十七号卫星01星~06星
  • 广西东兰官方通报“村民求雨耕种”:摆拍,恶意炒作