单线程 Redis 如此快的 4 个原因

单线程,redis,如此,原因 · 浏览次数 : 22

小编点评

**4 个原因导致 Redis 单线程设计如此快速** 1. **内存结构:** Redis 使用链表存储数据,链表允许在列表的头部和尾部附近进行恒定时间 O(1) 插入和删除。 2. **高效数据检索:** Redis 的 sorted set 使用跳跃列表实现,可以实现更快的查询和插入。 3. **减少上下文切换:** 单线程应用程序需要锁来进行线程同步,但大多数线程最终会在 I/O 中被阻塞。 4. **网络 I/O 优化:** I/O 多路复用模块同时监视多个套接字,并仅返回可读的套接字,以缓解网络 I/O 缓慢问题。

正文

本文翻译自国外论坛 medium,原文地址:https://levelup.gitconnected.com/4-reasons-why-single-threaded-redis-is-so-fast-414e0106f921

作为内存数据存储,Redis 以其速度和性能而闻名,通常被用作大多数后端服务的缓存解决方案。

然而,在 Redis 内部采用的也只是单线程的设计。

为什么 Redis 单线程设计会带来如此高的性能?如果利用多个线程并发处理请求不是更好吗?

在本文中,我们将探讨使 Redis 成为快速高效的数据存储的设计选择。

长话短说

Redis 的性能可归因于 4 个主要因素

  • 基于内存存储
  • 优化的数据结构
  • 单线程架构
  • 非阻塞IO

让我们一一剖析一下。

推荐博主开源的 H5 商城项目waynboot-mall,这是一套全部开源的微商城项目,包含三个项目:运营后台、H5 商城前台和服务端接口。实现了商城所需的首页展示、商品分类、商品详情、商品 sku、分词搜索、购物车、结算下单、支付宝/微信支付、收单评论以及完善的后台管理等一系列功能。 技术上基于最新得 Springboot3.0、jdk17,整合了 MySql、Redis、RabbitMQ、ElasticSearch 等常用中间件。分模块设计、简洁易维护,欢迎大家点个 star、关注博主。

github 地址:https://github.com/wayn111/waynboot-mall

基于内存存储

访问内存比访问磁盘快几个数量级

Redis 是在内存中进行键值存储。

Redis 中的每次读写操作都相当于从内存的变量中进行读写。

访问内存比直接访问磁盘快几个数量级,因此Redis 比其他数据存储快得多。

优化的数据结构

redis底层数据结构

作为内存数据存储,Redis 利用各种底层数据结构来高效存储数据,无需担心如何将它们持久化到持久存储中。

例如,Redis list 是使用链表实现的,它允许在列表的头部和尾部附近进行恒定时间 O(1) 插入和删除。

另一方面,Redis sorted set 是通过跳跃列表实现的,可以实现更快的查询和插入。

简而言之,无需担心数据持久化,Redis 中的数据可以更高效地存储,以便通过不同的数据结构进行快速检索。

单线程

单线程进程

Redis 中的写入和读取速度非常快,并且 CPU 使用率从来不是 Redis 关心的问题。

根据 Redis 官方文档,在普通 Linux 系统上运行时,Redis 每秒最多可以处理 100 万个请求。

通常瓶颈来自于网络 I/O, Redis 中的处理时间大部分浪费在等待网络 I/O 上。

虽然多线程架构允许应用程序通过上下文切换并发处理任务,但这对 Redis 的性能增益很小,因为大多数线程最终会在 I/O 中被阻塞。

所以 Redis 采用单线程架构,有如下好处

  • 最大限度地减少由于线程创建或销毁而产生的 CPU 消耗
  • 最大限度地减少上下文切换造成的 CPU 消耗
  • 减少锁开销,因为多线程应用程序需要锁来进行线程同步,而这容易出现错误
  • 能够使用各种“线程不安全”命令,例如 Lpush

非阻塞I/O

I/O 多路复用

为了处理传入的请求,服务器需要在套接字上执行系统调用,以将数据从网络缓冲区读取到用户空间。

这通常是阻塞操作,线程被阻塞并且在完全接收到来自客户端的数据之前不能执行任何操作。

为什么我们不能在只有确定套接字中的数据已准备好读取时,才执行系统调用嘞?

这就是 I/O 多路复用发挥作用的地方。

I/O 多路复用模块同时监视多个套接字,并且仅返回可读的套接字。

准备读取的套接字被推送到单线程事件循环,并由相应的处理程序使用响应式模型进行处理。

总之,

  • 网络 I/O 速度很慢,因为其阻塞特性,
  • Redis 收到命令后可以快速执行,因为这在内存中执行,操作速度很快,

所以 Redis 做出了以下决定,

  • 使用 I/O 多路复用来缓解网络 I/O 缓慢问题
  • 使用单线程架构减少锁开销

结论

四个原因

综上所述,单线程架构是 Redis 团队经过深思熟虑的选择,并且经受住了时间的考验。

尽管是单线程,Redis 仍然是性能最高、最常用的内存数据存储之一。

关注公众号【waynblog】每周分享技术干货、开源项目、实战经验、高效开发工具等,您的关注将是我的更新动力!

与单线程 Redis 如此快的 4 个原因相似的内容:

单线程 Redis 如此快的 4 个原因

本文翻译自国外论坛 medium,原文地址:https://levelup.gitconnected.com/4-reasons-why-single-threaded-redis-is-so-fast-414e0106f921 作为内存数据存储,Redis 以其速度和性能而闻名,通常被用作大多数后

Redis最常见的5种应用场景

Redis作为当今最流行的内存数据库,已经成为服务端加速的必备工具之一。对于Redis为什么那么快?以及Redis采用单线程,但为什么反而获得更高的性能的疑问,在之前的Redis为什么那么快?一文中,已经有所介绍。 今天通过这篇,我们来了解一下Redis最常见的5种应用场景。您可以通过视频来学习,如

[转帖]Redis Scan 原理解析与踩坑

https://www.cnblogs.com/jelly12345/p/16424080.html 1. 概述由于 Redis 是单线程在处理用户的命令,而 Keys 命令会一次性遍历所有 Key,于是在 命令执行过程中,无法执行其他命令。这就导致如果 Redis 中的 key 比较多,那么 Ke

(三)Redis 线程与IO模型

1、Redis 单线程 通常说 Redis 是单线程,主要是指 Redis 的网络 IO 和键值对读写是由一个线程来完成的,其他功能,比如持久化、异步删除、集群数据同步等,是由额外的线程执行的,所以严格来说,Redis 并不是单线程。 多线程开发会不可避免的带来并发控制和资源开销的问题,如果没有良好

Docker中部署单机Redis详细教程

1、拉取Redis镜像 # 拉取redis镜像,不指定版本则默认是最新版本 docker pull redis 2、查看镜像 # 列出本地镜像 docker images 3、准备配置文件路径 # 创建redis配置文件目录 # -p 确保每一级目录都存在,如果不存在则会自动创建 mkdir -p

[转帖]redis集群批量删除模糊key shell脚本

1. 命令删除: 1. 1批量删除Key Redis 中有删除单个 Key 的指令 DEL,但好像没有批量删除 Key 的指令,不过我们可以借助 Linux 的 xargs 指令来完成这个动作 redis-cli keys "*" | xargs redis-cli del //如果redis-cl

云小课|云小课教您如何选择Redis实例类型

阅识风云是华为云信息大咖,擅长将复杂信息多元化呈现,其出品的一张图(云图说)、深入浅出的博文(云小课)或短视频(云视厅)总有一款能让您快速上手华为云。更多精彩内容请单击此处。 摘要:购买Redis实例时,实例类型有单机、主备、Proxy集群、Cluster集群和读写分离这么多种,该怎么选?别担心,本

[转帖]Redis-6.2.x版本官方发行说明(附谷歌翻译)【持续更新】

https://www.yii666.com/blog/12891.html 一、前言 本文只是单纯地翻译Redis官方的6.2.x版本的发行说明,不会对发行说明内容做任何改动,读者如果觉得有异议,可自行去Redis官网相关网页查阅。翻译工具翻译出来的不一定百分百准确,英语好的人别喷,大家都是英语差

文盘Rust -- r2d2 实现redis连接池

作者:贾世闻 我们在开发应用后端系统的时候经常要和各种数据库、缓存等资源打交道。这一期,我们聊聊如何访问redis 并将资源池化。 在一个应用后端程序访问redis主要要做的工作有两个,单例和池化。 在后端应用集成redis,我们主要用到以下几个crate:​ ​once_cell​​​、​ ​re

[转帖]高性能IO模型:为什么单线程Redis能那么快?

https://zhuanlan.zhihu.com/p/596170085 你好,我是蒋德钧。 今天,我们来探讨一个很多人都很关心的问题:“为什么单线程的Redis能那么快?” 首先,我要和你厘清一个事实,我们通常说,Redis是单线程,主要是指Redis的网络IO和键值对读写是由一个线程来完成的