本文翻译自国外论坛 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 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 速度很慢,因为其阻塞特性,
  • Redis 收到命令后可以快速执行,因为这在内存中执行,操作速度很快,

所以 Redis 做出了以下决定,

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

结论

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

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

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

单线程 Redis 如此快的 4 个原因的更多相关文章

  1. Redis为什么是单线程、及高并发快的3大原因详解

    Redis的高并发和快速原因 1.redis是基于内存的,内存的读写速度非常快: 2.redis是单线程的,省去了很多上下文切换线程的时间: 3.redis使用多路复用技术,可以处理并发的连接.非阻塞 ...

  2. 高并发架构系列:Redis为什么是单线程、及高并发快的3大原因详解

    Redis的高并发和快速原因 1.redis是基于内存的,内存的读写速度非常快: 2.redis是单线程的,省去了很多上下文切换线程的时间: 3.redis使用多路复用技术,可以处理并发的连接.非阻塞 ...

  3. Redis为什么是单线程,高并发快的3大原因详解

    出处知乎:https://zhuanlan.zhihu.com/p/58038188 Redis的高并发和快速原因 1.redis是基于内存的,内存的读写速度非常快: 2.redis是单线程的,省去了 ...

  4. Redis(1.16)Redis监控为什么是单线程?为什么快?

    [1]Redis的高并发和快速原因 1.redis是基于内存的,内存的读写速度非常快: 2.redis是单线程的,省去了很多上下文切换线程的时间: 3.redis使用多路复用技术,可以处理并发的连接. ...

  5. 单线程 Redis 为什么这么快,看看这篇就知道了

    Redis 作为一种 KV 缓存服务器,有着极高的性能,相对于 Memcache,Redis 支持更多种数据类型,因此在业界应用广泛. 记得刚毕业那会参加面试,面试官会问我 Redis 为什么快,由于 ...

  6. Redis高并发和快速的原因

    一.Redis的高并发和快速原因 1.redis是基于内存的,内存的读写速度非常快: 2.redis是单线程的,省去了很多上下文切换线程的时间:   3.redis使用多路复用技术,可以处理并发的连接 ...

  7. 比Redis更快:Berkeley DB面面观

    比Redis更快:Berkeley DB面面观 Redis很火,最近大家用的多.从两年前开始,Memcached转向Redis逐渐成为潮流:而Berkeley DB可能很多朋友还很陌生,首先,我们简单 ...

  8. 单线程Redis性能为何如此之高?

    文章原创于公众号:程序猿周先森.本平台不定时更新,喜欢我的文章,欢迎关注我的微信公众号. 实际项目开发中现在无法逃避的一个问题就是缓存问题,而缓存问题也是面试必问知识点之一,如果面试官好一点可能会简单 ...

  9. 03 高性能IO模型:采用多路复用机制的“单线程”Redis

    本篇重点 三个问题: "Redis真的只有单线程吗?""为什么用单线程?""单线程为什么这么快?" "Redis真的只有单线程吗? ...

  10. 单线程架构的Redis如此之快的 4 个原因

    前言 作为内存中数据存储,Redis 以其速度和性能着称,通常被用作大多数后端服务的缓存解决方案. 但是,在内部,Redis 采用单线程架构. 为什么单线程设计依然会有这么高的性能?如果利用多线程并发 ...

随机推荐

  1. 解决OpenCV编译时./bin: error while loading shared libraries: libopencv_highgui.so.3.2: cannot open的问题

    1.问题 安装好了opencv后,用其去检测是否可以使用时,出现了如下的问题: 2.解决 参考这篇博文点击 的配置环境即可解决

  2. 解决This application failed to start because cannot find or load the qt platform plugin 'xcb'

    问题描述: 在使用linux系统训练自己的数据集合时,出现了上述问题,首先第一个想法就是先Google,但是在看了一些国内外的文章后依然没有将问题解决 问题原因: 这是由于这几天我在安装cuda.cu ...

  3. C++ Qt开发:TabWidget实现多窗体功能

    Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍TabWidg ...

  4. 【C#】【IO】【实例】统计多个文件夹下的图片

    因工作需要繁琐的进行同一目录多个文件夹下的图片统计,便使用代码来解决. 需求:统计的是多少个文件夹包含了图片,并非是统计有多少张图. 我们先用Python来创建一个现场环境(巩固巩固py知识): 1 ...

  5. spring是否线程安全

    spring 管理的bean默认是单例的,可通过 scope 属性设置scope="singleton" 默认是单例,可修改为scope="prototype" ...

  6. ASR项目实战-任务队列在文件转写特性中的应用

    转写时长超出60秒的语音文件,业界的竞品通常会使用创建异步转写任务的方式来提供支持. 一个简单.直接的实现方案,即: 网关服务接收到来自客户的转写请求时,将任务信息持久化至任务队列中. 由算法服务的实 ...

  7. Python——第二章:替换和切割

    strip() 用法: .strip() 是字符串方法之一,在 Python 中用于移除字符串开头和结尾的空白字符(包括空格.制表符 \t.换行符\n等).这个方法返回一个新的字符串,原始字符串本身不 ...

  8. Linux:LVM磁盘扩容实战

    1.列出分区表 命令:fdisk -l 查看到目前挂载了 vda1.vda2.vda3,并且查看到还有vdb 100G没有挂载,以及现在的LV大小仅为29G root@JumpServer-DB-T0 ...

  9. Java的特性、内容和环境的配置

    Java的特性和优势 简单性 面向对象 可移植性 高性能 分布式 动态性 多线程 安全性 健壮性 JDK包含JRE包含JVM JDK:Java Development Kit JRE:Java Run ...

  10. 2022年发布jar到Maven公共仓库最全攻略

    2022年jar包发布到Maven公共仓库最全攻略 分几个步骤: 1.注册 issues.sonatype.org 账号 2.创建 issues 填写项目地址(github.gitee等) 3.验证域 ...