iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >怎么解析Redis6中的单线程和多线程模型
  • 956
分享到

怎么解析Redis6中的单线程和多线程模型

2024-04-02 19:04:59 956人浏览 安东尼
摘要

这篇文章的内容主要围绕怎么解析Redis6中的单线程和多线程模型进行讲述,文章内容清晰易懂,条理清晰,非常适合新手学习,值得大家去阅读。感兴趣的朋友可以跟随小编一起阅读吧。希望大家通过这篇文章有所收获!1.

这篇文章的内容主要围绕怎么解析Redis6中的单线程多线程模型进行讲述,文章内容清晰易懂,条理清晰,非常适合新手学习,值得大家去阅读。感兴趣的朋友可以跟随小编一起阅读吧。希望大家通过这篇文章有所收获!

1. Redis演进史

如果单纯的说redis是单线程或多线程,这个回答肯定不严谨,不同版本使用的线程模型是不一样的。【相关推荐:Redis视频教程

怎么解析Redis6中的单线程和多线程模型

  • 版本3.x ,最早版本,也就是大家口口相传的redis是单线程。

  • 版本4.x,严格意义来说也不是单线程,而是负责处理客户端请求的线程是单线程,但是 开始加了点多线程的东西(异步删除)

  • 最新版本的6.0.x后, 告别了大家印象中的单线程,用一种全新的多线程来解决问题。

2. Redis单线程模型

2.1 单线程真实含义

主要是指Redis的网络io和键值对读写是由一个线程来完成的,Redis在处理客户端的请求时包括获取 (Socket 读)、解析、执行、内容返回 (socket 写) 等都由一个顺序串行的主线程处理,这就是所谓的“单线程”。这也是Redis对外提供键值存储服务的主要流程。

怎么解析Redis6中的单线程和多线程模型

但Redis的其他功能, 比如持久化、异步删除、集群数据同步等等,其实是由额外的线程执行的。 可以这么说,Redis工作线程是单线程的。但是,整个Redis来说,是多线程的

2.2 单线程性能快原因

Redis 3.x 单线程时代但是性能很快的主要原因

  • 基于内存操作:所有数据都存在内存中,因此所有的运算都是内存级别的

  • 数据结构简单:Redis的数据结构是专门设计的,而这些简单的数据结构的查找和操作的时间大部分复杂度都是o(1)

  • 多路复用和费阻塞IO:使用IO多路复用功能监听多个socket连接客户端,这样就可以使用一个线程连接处理多个请求,减少线程切换带来的开销,同时避免IO阻塞操作

  • 避免上下文切换:因为是单线程模型,就可以避免不必要的上先文切换和多线程竞争,这样可以省去多线程切换带来的时间和性能上的消耗,而且单线程不会导致死问题的发生

2.3 采用单线程原因

Redis 是基于内存操作的, 因此他的瓶颈可能是机器的内存或者网络带宽而并非 CPU ,既然 CPU 不是瓶颈,那么自然就采用单线程的解决方案了,况且使用多线程比较麻烦。 但是在 Redis 4.0 中开始支持多线程了,例如后台删除等功能
简单来说,Redis  4.0 之前一直采用单线程的主要原因有以下三个:

  • 使用单线程模型是 Redis 的开发和维护更简单,因为单线程模型方便开发和调试;多线程模型虽然在某些方面表现优异,但是它却引入了程序执行顺序的不确定性,带来了并发读写的一系列问题,增加了系统复杂度、同时可能存在线程切换、甚至加锁解锁、死锁造成的性能损耗。Redis通过AE事件模型以及IO多路复用等技术,处理性能非常高,因此没有必要使用多线程。单线程机制使得 Redis 内部实现的复杂度大大降低,Hash 的惰性 Rehash、Lpush 等等 “线程不安全” 的命令都可以无锁进行。

  • 即使使用单线程模型也并发的处理多客户端的请求,主要使用的是多路复用和非阻塞 IO;

  • 对于 Redis 系统来说, 主要的性能瓶颈是内存或者网络带宽而并非 CPU

3. Redis多线程模型

3.1 引入多线程原因

既然单线程那么好,为啥又要引入多线程?单线程也有自己的烦恼,比如大key删除问题: 正常情况下使用 del 指令可以很快的删除数据,而当被删除的 key 是一个非常大的对象时,例如时包含了成千上万个元素的 hash 集合时,那么 del 指令就会造成 Redis 主线程卡顿。

因此,在 Redis 4.0 中就新增了多线程的模块,当然此版本中的多线程主要是为了解决删除数据效率比较低的问题。可以通过惰性删除有效避免Redis卡顿问题(大key删除等问题),步骤如下:

  • unlink key : 与DEL一样删除key功能的lazy free实现,唯一不同是,UNLINK在删除集合类型键时,如果集合键的元素个数大于64个,主线程中只是把待删除键从数据库字典中摘除,会把真正的内存释放操作,给单独的bio来操作。如果元素个数较少(少于64个)或者是String类型,也会在主线程中直接删除。

  • flushall/flushdb async : 对于清空数据库命令flushall/flushdb,添加了async异步清理选项,使得redis在清空数据库时都是异步操作。实现逻辑是为数据库新建一个新的空的字典,把原有旧的数据库字典给后台线程来逐一删除其中的数据,释放内存。

  • 把删除工作交给了后台子进程异步删除数据

因为Redis是单个主线程处理,redis之父antirez一直强调"Lazy Redis is better Redis". 而lazy free的本质就是把某些cost(主要时间复制度,占用主线程cpu时间片)较高删除操作, 从redis主线程剥离让bio子线程来处理,极大地减少主线阻塞时间。从而减少删除导致性能和稳定性问题。

Redis 4.0 就引入了多个线程来实现数据的异步惰性删除等功能,但是其处理读写请求的仍然只有一个线程,所以仍然算是狭义上的单线程。

从上一小结分析:Redis的主要性能瓶颈是内存或网络带宽而并非CPU。内存问题比较好解决,因此Redis的瓶颈原因为网络IO。接下来,引入多线程模型。

3.2 多线程工作原理

I/O 的读和写本身是堵塞的,比如当 socket 中有数据时,Redis 会通过调用先将数据从内核态空间拷贝到用户态空间,再交给 Redis 调用,而这个拷贝的过程就是阻塞的,当数据量越大时拷贝所需要的时间就越多,而这些操作都是基于单线程完成的。

怎么解析Redis6中的单线程和多线程模型在 Redis 6.0 中新增了多线程的功能来提高 I/O 的读写性能,他的主要实现思路是将主线程的 IO 读写任务拆分给一组独立的线程去执行,这样就可以使多个 socket 的读写可以并行化了,采用多路 I/O 复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络IO的时间消耗),将最耗时的Socket的读取、请求解析、写入单独外包出去,剩下的命令执行仍然由主线程串行执行并和内存的数据交互。

怎么解析Redis6中的单线程和多线程模型

结合上图可知,将网络数据读写、请求协议解析通过多个IO线程的来处理,对于真正的命令执行来说,仍然使用主线程操作(线程安全),是个不错的折中办法。因此,对于整个Redis来说是多线程的,但是对于工作线程(命令执行)仍旧是单线程

3.3 工作流程

核心流程大概如下:怎么解析Redis6中的单线程和多线程模型

流程简述如下:

  • 主线程获取 socket 放入等待列表

  • 将 socket 分配给各个 IO 线程(并不会等列表满)

  • 主线程阻塞等待 IO 线程(多线程)读取 socket 完毕

  • 主线程执行命令 - 单线程(如果命令没有接收完毕,会等 IO 下次继续)

  • 主线程阻塞等待 IO 线程(多线程)将数据回写 socket 完毕(一次没写完,会等下次再写)

  • 解除绑定,清空等待队列

特点如下:

  • IO 线程要么同时在读 socket,要么同时在写,不会同时读或写

  • IO 线程只负责读写 socket 解析命令,不负责命令处理(主线程串行执行命令)

  • IO 线程数可自行配置(目前代码限制上限为 512,默认为 1(关闭此功能))

经过有心人士的压测,目前性能能提高 1 倍以上。

疑问1:等待列表不满 一直阻塞不处理吗?
回复:怎么解析Redis6中的单线程和多线程模型阻塞时检测的是,IO 线程是否还有任务。等处理完了才继续往下。这些任务是在执行时添加的,如果 任务数< 线程数,那有些线程就拿不到任务,它的待处理任务就是 0 。分配了任务的线程,在处理好 IO 事件后,pending 就会清零,没拿到任务的线程 pending 本来就是 0,所以不会阻塞。 这块还是有点疑问,哪位大佬可以解释下(评论哈)?

3.4 默认开启多线程吗?

在Redis6.0中, 多线程机制默认是关闭的 ,如果需要使用多线程功能,需要在redis.conf中完成两个设置。怎么解析Redis6中的单线程和多线程模型

  • 设置io-thread-do-reads配置项为yes,表示启动多线程。

  • 设置线程个数。关于线程数的设置,官方的建议是如果为 4 核的 CPU,建议线程数设置为 2 或 3, 如果为 8 核 CPU 建议线程数设置为 6 ,线程数一定要小于机器核数,线程数并不是越大越好。

4. 总结

Redis自身出道就是优秀,基于内存操作、数据结构简单、多路复用和非阻塞 I/O、避免了不必要的线程上下文切换等特性,在单线程的环境下依然很快;

但对于大数据的 key 删除还是卡顿厉害,因此在 Redis 4.0 引入了多线程unlink key/flushall async 等命令,主要用于 Redis 数据的异步删除;

而在 Redis 6.0 中引入了 I/O 多线程的读写,这样就可以更加高效的处理更多的任务了, Redis 只是将 I/O 读写变成了多线程 ,而 命令的执行依旧是由主线程串行执行的 ,因此在多线程下操作 Redis 不会出现线程安全的问题

Redis 无论是当初的单线程设计,还是如今与当初设计相背的多线程,目的只有一个:让 Redis 变得越来越快。

感谢你的阅读,相信你对“怎么解析Redis6中的单线程和多线程模型”这一问题有一定的了解,快去动手实践吧,如果想了解更多相关知识点,可以关注编程网网站!小编会继续为大家带来更好的文章!

您可能感兴趣的文档:

--结束END--

本文标题: 怎么解析Redis6中的单线程和多线程模型

本文链接: https://www.lsjlt.com/news/72045.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 怎么解析Redis6中的单线程和多线程模型
    这篇文章的内容主要围绕怎么解析Redis6中的单线程和多线程模型进行讲述,文章内容清晰易懂,条理清晰,非常适合新手学习,值得大家去阅读。感兴趣的朋友可以跟随小编一起阅读吧。希望大家通过这篇文章有所收获!1....
    99+
    2024-04-02
  • spring scheduled单线程和多线程使用的坑怎么解决
    本篇内容介绍了“spring scheduled单线程和多线程使用的坑怎么解决”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!公司在...
    99+
    2023-06-29
  • Node.js中的单线程模型是什么
    这期内容当中小编将会给大家带来有关Node.js中的单线程模型是什么,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。1、高并发一般来说,高并发的解决方案就是多线程模型,服务...
    99+
    2024-04-02
  • Android中的单线程模型是什么
    这篇文章给大家介绍Android中的单线程模型是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。Android 单线程模型详解及实例当第一次启动一个Android程序时,Android会自动创建一个称为“main”主...
    99+
    2023-05-31
    android 单线 roi
  • springscheduled单线程和多线程使用过程中的大坑
    公司在使用定时任务的时候,使用的是spring scheduled。 代码如下: @EnableScheduling public class TaskFileScheduleSer...
    99+
    2024-04-02
  • 聊聊Redis的单线程模型
    目录开篇正文文件事件处理器redis 事件处理伪代码redis 源码总结开篇 本文主要来探讨一下 redis 的单线程模型,文章前半部分会先引用某网络课程讲解的内容(图片+语言描述)...
    99+
    2022-12-19
    Redis单线程 Redis单线程模型
  • Python中线程池模块之多线程的示例分析
    这篇文章将为大家详细讲解有关Python中线程池模块之多线程的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1、线程池模块引入from concurrent.futures i...
    99+
    2023-06-15
  • C#中单例模式与多线程怎么用
    这篇文章给大家分享的是有关C#中单例模式与多线程怎么用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、单例模式我们先来看看两种创建单例模式的示例代码。1、饿汉式 饿汉式创建单例模式是在程序里面直接初始...
    99+
    2023-06-29
  • WPF线程模型和Dispatcher怎么用
    这篇文章将为大家详细讲解有关WPF线程模型和Dispatcher怎么用,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。WPF线程模型是从WPF的两个线程:一个用于处理呈现和一个用于管理UI开始。并展开同时讨...
    99+
    2023-06-17
  • C#单线程和多线程端口扫描器详解
    目录一、项目创建以及页面设计(一)项目新建(二)页面设计二、单线程实现端口扫描(一)代码实现(二)运行结果三、多线程实现端口扫描(一)程序实现(二)运行结果四、总结五、参考资料本文为...
    99+
    2024-04-02
  • Java中单例模式与多线程的示例分析
    这篇文章主要介绍了Java中单例模式与多线程的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。单例模式与多线程单例模式就是全局唯一但是所有程序都可以使用的对象写单例模式...
    99+
    2023-06-20
  • Redis单线程的reactor模型是怎样的
    这篇文章主要讲解了“Redis单线程的reactor模型是怎样的”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Redis单线程的reactor模型是怎样的”...
    99+
    2024-04-02
  • Redis的单线程模型怎么保证高性能
    Redis的单线程模型通过以下几种方式保证高性能: 非阻塞I/O:Redis使用非阻塞I/O模型,可以在一个线程中同时处理多个客...
    99+
    2024-05-07
    Redis
  • Redis线程模型的原理分析
    目录一、概述二、网络IO模型发展史2.1 阻塞IO2.2 非阻塞2.3 IO多路复用三、NIO线程模型解释3.1 单Reactor单线程模型3.2 单Reactor多线程模型3.3 ...
    99+
    2024-04-02
  • Node.js中的多进程和多线程实例分析
    本篇内容主要讲解“Node.js中的多进程和多线程实例分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Node.js中的多进程和多线程实例分析”吧!我们都知道...
    99+
    2024-04-02
  • Python中多线程和多处理的分析
    本篇内容主要讲解“Python中多线程和多处理的分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Python中多线程和多处理的分析”吧!多线程简单地说,线程允许您并行地运行程序。花费大量时间等...
    99+
    2023-06-16
  • 怎么解析Java多线程程序设计
    小编今天带大家了解怎么解析Java多线程程序设计,文中知识点介绍的非常详细。觉得有帮助的朋友可以跟着小编一起浏览文章的内容,希望能够帮助更多想解决这个问题的朋友找到问题的答案,下面跟着小编一起深入学习“怎么解析Java多线程程序设计”的知识...
    99+
    2023-06-03
  • java中多线程和线程安全是什么
    这篇文章给大家分享的是有关java中多线程和线程安全是什么的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。什么是进程?电脑中时会有很多单独运行的程序,每个程序有一个独立的进程,而进程之间是相互独立存在的。比如下图中...
    99+
    2023-06-25
  • Java多线程中的Balking模式详解
    目录1.场景2.详细说明3.Balking模式的本质:停止并返回源代码如下:总结1.场景 自动保存功能: 为防止电脑死机,而定期将数据内容保存到文件中的功能。 2.详细说明 当数据内...
    99+
    2024-04-02
  • C#多线程中线程同步的示例分析
    这篇文章将为大家详细讲解有关C#多线程中线程同步的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、前言我们先来看下面一个例子:using System;using Syste...
    99+
    2023-06-29
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作