精华内容
下载资源
问答
  • Redis单线程 Redis单线程模型,指的是执行 Redis 命令的核心模块是单线程的,而不是整个 Redis 实例就一个线程,Redis 其他模块还有各自模块的线程的。 Redis基于Reactor模式开发了网络事件处理器,这个...

    Redis 的单线程

    Redis 是单线程模型,指的是执行 Redis 命令的核心模块是单线程的,而不是整个 Redis 实例就一个线程,Redis 其他模块还有各自模块的线程的。

    Redis基于Reactor模式开发了网络事件处理器,这个处理器被称为文件事件处理器。它的组成结构为4部分:多个套接字、IO多路复用程序、文件事件分派器、事件处理器。因为文件事件分派器队列的消费是单线程的,所以Redis才叫单线程模型。

    Redis 不仅仅是单线程

    一般来说 Redis 的瓶颈并不在 CPU,而在内存和网络。如果要使用 CPU 多核,可以搭建多个 Redis 实例来解决。

    Redis 4.0 开始就有多线程的概念了,比如 Redis 通过多线程方式在后台删除对象、以及通过 Redis 模块实现的阻塞命令等。

    Redis 6.0 之后的版本抛弃了单线程模型这一设计,原本使用单线程运行的 Redis 也开始选择性使用多线程模型

    为什么引入多线程?

    因为读写网络的read/write系统调用在Redis执行期间占用了大部分CPU时间,如果把网络读写做成多线程的方式对性能会有很大提升。

    Redis 的多线程部分只是用来处理网络数据的读写和协议解析,执行命令仍然是单线程。之所以这么设计是不想 Redis 因为多线程而变得复杂,需要去控制 key、lua、事务,LPUSH/LPOP 等等的并发问题。

    Redis 在最新的几个版本中加入了一些可以被其他线程异步处理的删除操作(UNLINK、FLUSHALL ASYNC 和 FLUSHDB ASYNC)

    Redis可以使用del命令删除一个元素,如果这个元素非常大,可能占据了几十兆或者是几百兆,那么在短时间内是不能完成的,这样一来就需要多线程的异步支持。现在删除工作可以在后台进行。

    总结

    redis在4.0之前使用单线程是因为基于内存速度快,而且多路复用有多路复用的作用,足以支持正常使用。之所以引入多线程是因为要在某些操作要优化(删除操作等)。

    展开全文
  • redis单线程,线程安全 redis可以能够快速执行的原因: (1) 绝大部分请求是纯粹的内存操作(非常快速) (2) 采用单线程,避免了不必要的上下文切换和竞争条件 (3) 非阻塞IO - IO路复用(IO 路复用是什么意思...

    redis是单线程,线程安全

    redis可以能够快速执行的原因:

    (1) 绝大部分请求是纯粹的内存操作(非常快速)
    (2) 采用单线程,避免了不必要的上下文切换和竞争条件
    (3) 非阻塞IO - IO多路复用(IO 多路复用是什么意思?

    IO多路复用中有三种方式:select,poll,epoll。需要注意的是,select,poll是线程不安全的,epoll是线程安全的

    redis内部实现采用epoll,采用了epoll+自己实现的简单的事件框架。epoll中的读、写、关闭、连接都转化成了事件,然后利用epoll的多路复用特性,绝不在io上浪费一点时间 这3个条件不是相互独立的,特别是第一条,如果请求都是耗时的,采用单线程吞吐量及性能可想而知了。应该说redis为特殊的场景选择了合适的技术方案。

    展开全文
  • Redis 单线程还是多线程

    千次阅读 2019-09-18 09:51:27
    Redis 单线程还是多线程 前段时间无意间看到一篇博客,讲述了Redis6即将在年底发布的事情,好奇心驱动下搜索了官网,想看看新版Redis带来了什么新的功能,果然得到证实Redis在年底将发布新的版本:6.0,并且Redis...

    Redis 单线程还是多线程

    前段时间无意间看到一篇博客,讲述了Redis6即将在年底发布的事情,好奇心驱动下搜索了官网,想看看新版Redis带来了什么新的功能,果然得到证实Redis在年底将发布新的版本:6.0,并且Redis创始人兼核心开发者 antirez 在博客也介绍了将在6.0所提供的新功能

    ACL用户权限控制功能
    RESP3:新的 Redis 通信协议
    Cluster 管理工具
    SSL 支持
    IO多线程支持
    新的Module API
    新的 Expire 算法等

    具体可以参考相关资料(http://antirez.com/latest/0)

    这里只是大致说一下自身比较感兴趣的功能

    IO多线程

    刚开始看到Redis支持多线程的时候,其实自身心里挺疑惑的,Redis难道是单线程?为什么单线程响应能够那么快?带着这些疑问翻阅了相关资料。官方FAQ表示,因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽。既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案。
    那既然是单线程那为什么会那么快呢?原来Redis使用了单线程架构和I/O多路复用模型来实现高性能的内存数据库服务,只所以快可归结一下几点:
    1、完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1);

    2、数据结构简单,对数据操作也简单,Redis中的数据结构是专门进行设计的;

    3、采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;

    4、使用多路I/O复用模型,非阻塞IO;

    5、使用底层模型不同,它们之间底层实现方式以及与客户端之间通信的应用协议不一样,Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求

    在这里插入图片描述

    以上几点都比较好理解,下边我们针对多路 I/O 复用模型进行简单的探讨:
    首先,Redis 是跑在单线程中的,所有的操作都是按照顺序线性执行的,但是由于读写操作等待用户输入或输出都是阻塞的,所以 I/O 操作在一般情况下往往不能直接返回,这会导致某一文件的 I/O 阻塞导致整个进程无法对其它客户提供服务,而 I/O 多路复用就是为了解决这个问题而出现的.
    多路I/O复用模型是利用 select、poll、epoll 可以同时监察多个流的 I/O 事件的能力,在空闲的时候,会把当前线程阻塞掉,当有一个或多个流有 I/O 事件时,就从阻塞态中唤醒,于是程序就会轮询一遍所有的流(epoll 是只轮询那些真正发出了事件的流),并且只依次顺序的处理就绪的流,这种做法就避免了大量的无用操作。

    这里“多路”指的是多个网络连接,“复用”指的是复用同一个线程。采用多路 I/O 复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络 IO 的时间消耗),且 Redis 在内存中操作数据的速度非常快,也就是说内存内的操作不会成为影响Redis性能的瓶颈,主要由以上几点造就了 Redis 具有很高的吞吐量
    在这里插入图片描述

    注意:上面说的都是单线程的优点,但单线程也有其缺点,对于每个命令的执行时间有要求,如果某个命令执行时间过长,会造成其他命令阻塞,对于Redis这种高性能的服务来说是致命的。

    既然单线程Redis这么优越,Redis 6.0引入的IO多线程岂不是多余?

    答案肯定是非也,目前对于单线程 Redis 来说,性能瓶颈主要在于网络的 IO 消耗,优化主要有两个方向:
    1、提高网络 IO 性能,典型的实现像使用 DPDK 来替代内核网络栈的方式
    2、使用多线程充分利用多核,典型的实现像 Memcached

    协议栈优化的这种方式跟 Redis 关系不大,多线程特性在社区也被反复提了很久后, Redis作者antirez终于在 Redis 6 加入多线程(据说多线程 IO 特性的引入对性能提升至少是一倍以上,http://antirez.com/news/126)。因为读写网络的read/write系统调用在Redis执行期间占用了大部分CPU时间,如果把网络读写做成多线程的方式对性能会有很大提升,这里所说的多线程,是通过系统调用写操作,将客户端的输入输出缓冲中的数据通过多线程IO与客户端交互。现在已经实现了第一版,write side即回复客户端这部分已经完成了,并且去掉了主线程和IO线程之间的互斥锁,采用busy loop的形式来等待io线程工作结束,这部分能够有50%的性能提升,架构图如下

    在这里插入图片描述

    但跟 Memcached 这种从 IO 处理到数据访问多线程的实现模式有些差异,Redis 的多线程部分只是用来处理网络数据的读写和协议解析,执行命令仍然是单线程。之所以这么设计是不想因为多线程而变得复杂,需要去控制 key、lua、事务,LPUSH/LPOP 等等的并发问题。整体的设计大体如下:

    在这里插入图片描述

    多线程 IO 的读(请求)和写(响应)在实现流程是一样的,只是执行读还是写操作的差异。同时这些 IO 线程在同一时刻全部是读或者写,不会部分读或部分写的情况,所以下面以读流程作为例子。分析过程中只会覆盖核心逻辑而不是全部细节。如果想完全理解细节,建议看完之后再次看一次源码实现。

    加入多线程 IO 之后,整体的读流程如下:

    1、主线程负责接收建连请求,读事件到来(收到请求)则放到一个全局等待读处理队列
    2、主线程处理完读事件之后,通过 RR(Round Robin) 将这些连接分配给这些 IO 线程,然后主线程忙等待(spinlock 的效果)状态
    3、IO 线程将请求数据读取并解析完成(这里只是读数据和解析并不执行)
    4、主线程执行所有命令并清空整个请求等待读处理队列(执行部分串行)

    上面的这个过程是完全无锁的,因为在 IO 线程处理的时主线程会等待全部的 IO 线程完成,所以不会出现data race的场景。

    总结
    不管单线程还是多少线程,其实对应Redis不同模块而已。对于Redis 6.0 2019 年底发布,其将在性能、协议以及权限控制都会有很大的改进,还是值得期待的。
    最后在说一下,Redis 6.0将采用全新协议 RESP3,进而实现 Client side caching(客户端缓存)功能,可以说是在提升Redis作为缓存的读写能力有了质的飞跃,值得期待。有兴趣的可以看看RESP3 的设计稿:
    https://github.com/antirez/RESP3/blob/master/spec.md

    展开全文
  • 刚开始看到Redis支持多线程的时候,其实自身心里挺疑惑的,Redis难道是单线程?为什么单线程响应能够那么快?带着这些疑问翻阅了相关资料。官方FAQ表示,因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的...

    IO多线程

    刚开始看到Redis支持多线程的时候,其实自身心里挺疑惑的,Redis难道是单线程?为什么单线程响应能够那么快?带着这些疑问翻阅了相关资料。官方FAQ表示,因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽。既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案。
    那既然是单线程那为什么会那么快呢?原来Redis使用了单线程架构和I/O多路复用模型来实现高性能的内存数据库服务,只所以快可归结一下几点:
    1、完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1);

    2、数据结构简单,对数据操作也简单,Redis中的数据结构是专门进行设计的;

    3、采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;

    4、使用多路I/O复用模型,非阻塞IO;

    5、使用底层模型不同,它们之间底层实现方式以及与客户端之间通信的应用协议不一样,Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求

    在这里插入图片描述

    以上几点都比较好理解,下边我们针对多路 I/O 复用模型进行简单的探讨:
    首先,Redis 是跑在单线程中的,所有的操作都是按照顺序线性执行的,但是由于读写操作等待用户输入或输出都是阻塞的,所以 I/O 操作在一般情况下往往不能直接返回,这会导致某一文件的 I/O 阻塞导致整个进程无法对其它客户提供服务,而 I/O 多路复用就是为了解决这个问题而出现的.
    多路I/O复用模型是利用 select、poll、epoll 可以同时监察多个流的 I/O 事件的能力,在空闲的时候,会把当前线程阻塞掉,当有一个或多个流有 I/O 事件时,就从阻塞态中唤醒,于是程序就会轮询一遍所有的流(epoll 是只轮询那些真正发出了事件的流),并且只依次顺序的处理就绪的流,这种做法就避免了大量的无用操作。

    这里“多路”指的是多个网络连接,“复用”指的是复用同一个线程。采用多路 I/O 复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络 IO 的时间消耗),且 Redis 在内存中操作数据的速度非常快,也就是说内存内的操作不会成为影响Redis性能的瓶颈,主要由以上几点造就了 Redis 具有很高的吞吐量
    在这里插入图片描述

    注意:上面说的都是单线程的优点,但单线程也有其缺点,对于每个命令的执行时间有要求,如果某个命令执行时间过长,会造成其他命令阻塞,对于Redis这种高性能的服务来说是致命的。

    既然单线程Redis这么优越,Redis 6.0引入的IO多线程岂不是多余?

    答案肯定是非也,目前对于单线程 Redis 来说,性能瓶颈主要在于网络的 IO 消耗,优化主要有两个方向:
    1、提高网络 IO 性能,典型的实现像使用 DPDK 来替代内核网络栈的方式
    2、使用多线程充分利用多核,典型的实现像 Memcached

    协议栈优化的这种方式跟 Redis 关系不大,多线程特性在社区也被反复提了很久后, Redis作者antirez终于在 Redis 6 加入多线程(据说多线程 IO 特性的引入对性能提升至少是一倍以上,http://antirez.com/news/126)。因为读写网络的read/write系统调用在Redis执行期间占用了大部分CPU时间,如果把网络读写做成多线程的方式对性能会有很大提升,这里所说的多线程,是通过系统调用写操作,将客户端的输入输出缓冲中的数据通过多线程IO与客户端交互。现在已经实现了第一版,write side即回复客户端这部分已经完成了,并且去掉了主线程和IO线程之间的互斥锁,采用busy loop的形式来等待io线程工作结束,这部分能够有50%的性能提升,架构图如下

    在这里插入图片描述

    但跟 Memcached 这种从 IO 处理到数据访问多线程的实现模式有些差异,Redis 的多线程部分只是用来处理网络数据的读写和协议解析,执行命令仍然是单线程。之所以这么设计是不想因为多线程而变得复杂,需要去控制 key、lua、事务,LPUSH/LPOP 等等的并发问题。整体的设计大体如下:

    在这里插入图片描述

    多线程 IO 的读(请求)和写(响应)在实现流程是一样的,只是执行读还是写操作的差异。同时这些 IO 线程在同一时刻全部是读或者写,不会部分读或部分写的情况,所以下面以读流程作为例子。分析过程中只会覆盖核心逻辑而不是全部细节。如果想完全理解细节,建议看完之后再次看一次源码实现。

    加入多线程 IO 之后,整体的读流程如下:

    1、主线程负责接收建连请求,读事件到来(收到请求)则放到一个全局等待读处理队列
    2、主线程处理完读事件之后,通过 RR(Round Robin) 将这些连接分配给这些 IO 线程,然后主线程忙等待(spinlock 的效果)状态
    3、IO 线程将请求数据读取并解析完成(这里只是读数据和解析并不执行)
    4、主线程执行所有命令并清空整个请求等待读处理队列(执行部分串行)

    上面的这个过程是完全无锁的,因为在 IO 线程处理的时主线程会等待全部的 IO 线程完成,所以不会出现data race的场景。

    总结
    不管单线程还是多少线程,其实对应Redis不同模块而已。对于Redis 6.0 2019 年底发布,其将在性能、协议以及权限控制都会有很大的改进,还是值得期待的。
    最后在说一下,Redis 6.0将采用全新协议 RESP3,进而实现 Client side caching(客户端缓存)功能,可以说是在提升Redis作为缓存的读写能力有了质的飞跃,值得期待。有兴趣的可以看看RESP3 的设计稿:
    https://github.com/antirez/RESP3/blob/master/spec.md

    展开全文
  • 其中执行命令阶段,由于Redis单线程来处理命令的,所有到达服务端的命令都不会立刻执行,所有的命令都会进入一个队列中,然后逐个执行,并且个客户端发送的命令的执行顺序是不确定的,但是可以确定的是不会有两...
  • redis为什么可以支持高并发和它内部的工作模式有不可分割的关系: - 绝大部分请求是纯粹的内存操作(非常快速) - 采用单线程,避免了不必要的上下文切换和竞争条件 - 非阻塞IO - IO路复用Redis客户端对服务端的...
  • Redis是单线程还是多线程问题 在学习redis的过程中,很多文章都说redis是单线程,但在官方给出的说明中显示,redis6.0已经引入了多线程,对此我找了许多文档,将学习过程整理记录下来。 1、Redis单线程 在一开始的...
  • 我们所知的内存型的存储数据库,除了Redis外还有Memcache。两者的共同点就是存储时都是K-V存储的,而本质区别就是Redis的value是有类型的。但是,类型丰富不是重点,最大的优点是,因为有类型,而每种类型是有各自的...
  • Redis4以前是单线程的,Redis6 IO是多线程Redis6命令还是单线程的。 Redis采用单线程的原因:性能很高!性能很高!性能很高! 单线程Redis为什么性能还这么高? 1. 基于内存的操作 2. 数据结构简单:查找和...
  • Redis是单线程还是多线程?为何速度快?单线程还是多线程?速度快的原因Redis单线程模型是怎样的? 单线程还是多线程? Redis是单线程操作,采用非阻塞IO多路复用单线程,长期持有IO连接,减少了网络IO的时间。 速度...
  • Redis单线程还是多线程?以及处理模型。 线程:单线程 处理模型:参考书《Redis 设计与实现》P151-152 ![](https://ws1.sinaimg.cn/large/b35c33e9ly1g1p4dzlbukj20jq08twhg.jpg) ![]...
  • 单线程满足redis的串行原子,IO多线程,把输入/输出进行多线程并行,这样可以缩短执行时间,更好的压缩系统和硬件资源(网卡的利用率更高)。 多线程并行的顺序,在一个连接中通过socket保证。 单线程 IO多线程 ...
  • 一、什么是Redisredis是一个高性能的key-value数据库,它是完全开源免费的,而且redis是一个NOSQL类型数据库,是为了解决高并发、高扩展,大数据存储等一系列的问题而产生的数据库解决方案,是一个非关系型的数据库...
  • 面试官:redis单线程还是多线程的 我:单线程 面试官:出门左转 问题分析 首先从不同的方面去分析这个问题 redis的单线程理解 redis的单线程指的是:redis客户端与服务端的交互,分为三个阶段,发送请求,执行命令...
  • 近乎所有与Java相关的面试都会问到缓存的问题,基础一点的会...一般常用的缓存服务器有Redis、Memcached等,就redis单线程,这篇文章做一个简单介绍Redis采用的是基于内存的采用的是单进程单线程模型的KV 数据库,由...
  • 先赞后看,干货都是你哒1.redis单线程问题单线程指的是网络请求模块使用了一个线程(所以不需考虑并发安全性),即一个线程处理所有网络请求,其他模块仍用了个线程。1. 为什么说redis能够快速执行(1) 绝大部分请求...
  • 我们本文的面试题是 Redis 属于单线程还是多线程? 典型回答 本文的问题在不同的 Redis 版本下答案是不同的,在 Redis 4.0 之前,Redis 是单线程运行的,但单线程并不意味着性能低,类似单线程的程序还有 Nginx...
  • Redis单线程解读

    2019-02-25 20:27:41
    之前面试时被面试官问了一个问题,Redis多线程还是单线程的?依稀记得Redis单线程,其更深层次的技术原理完全懵逼。所以此篇文章旨在解读Redis为什么为单线程。 1、基本原理 采用路 I/O 复用技术可以...
  • 不同版本的Redis是不同的,在Redis4.0之前,Redis单线程运行的,但单线程并不代表效率低,像Nginx、Nodejs也是单线程程序,但是它们的效率并不低。原因是Redis是基于内存的,它的瓶颈在于机器的内存、网络带宽,而...
  • 相对于多线程而言,可以说 Redis单线程,但是这种说法也是不太准确的。为什么呢?下面来分析一下: 一、Redis 单线程到底指什么? 没错,大家所熟知的 Redis 确实是单线程模型,指的是执行 Redis 命令的核心...
  • 1、Redis 单线程到底指什么? 没错,大家所熟知的 Redis 确实是单线程模型,指的是执行 Redis 命令的核心模块是单线程的,而不是整个 Redis 实例就一个线程,Redis 其他模块还有各自模块的线程的。 下面这个解释比较...
  • Redis多线程还是单线程? 这个问题你要从个方面回答,如果你仅仅只回答 “单线程” 肯定是说不过去的。原因往下看。 1、Redis 单线程到底指什么? 没错,大家所熟知的 Redis 确实是单线程模型,指的是 执行 ...
  • Redis多线程还是单线程?(回答单线程的请回吧,为什么请回,请往下看) 好些粉丝在后台问我:为什么请回,Redis不是单线程吗? 大家注意审题:Redis多线程还是单线程? 这个问题你要从个方面回答,如果你...
  • 几种 I/O 模型Blocking I/OI/O 路复用Reactor 设计模式I/O 路复用模块封装 select 函数封装 epoll 函数子模块的选择总结Reference最近在看 UNIX 网络编程并研究了一下 Redis 的实现,感觉 Redis 的源代码十分...

空空如也

空空如也

1 2 3 4 5 ... 19
收藏数 365
精华内容 146
关键字:

redis单线程还是多线程

redis 订阅