Redis单线程

Reids是单线程!
Reids是单线程!
Reids是单线程!

Redis架构模型:Redis 基于 Reactor 模式来设计开发了自己的一套高效的事件处理模型即文件事件处理器

文件事件处理器(file event handler)

主要是包含 4 个部分:

  • 多个 socket(客户端连接)
  • IO 多路复用程序(支持多个客户端连接的关键)
  • 文件事件分派器(将 socket 关联到相应的事件处理器)
  • 事件处理器(连接应答处理器、命令请求处理器、命令回复处理器)

IO 多路复用程序(非堵塞)

堵塞:一个线程一次只能处理一个。

select和poll和epoll同一时间一个线程可以处理多个,所以不是堵塞。

含义:I/O 指的是网络I/O。
  多路指的是多个TCP 连接(Socket 或Channel)。
“复用”指的是复用同一个线程 。

作用:Redis 通过IO 多路复用程序 来监听来自客户端的大量连接(或者说是监听多个 socket)

优点:I/O 多路复用技术的使用让 Redis 不需要额外创建多余的线程来监听客户端的大量连接,降低了资源的消耗(和 NIO 中的 Selector 组件很像)

过程

  • I/O多路复用程序,负责监听多个套接字,按照处理顺序,将套接字存放在一个队列中。
  • 套接字队列以有序(sequentially)、同步(synchronously)、每次一个套接字的方式向文件事件分派器传送套接字。
  • 当上一个套接字产生的事件被处理完毕之后, I/O 多路复用程序才会继续向文件事件分派器传送下一个套接字。

select(同步非堵塞)

数据类型: fd_set就是一个long int类型的数组。因为每一位可以代表一个文件描述符。所以fd_set最多表示1024个文件描述符

调用过程:

select 是操作系统提供的系统调用函数,select 只能监听 1024 个文件描述符,通过它,我们可以把一个文件描述符的数组发给操作系统, 让操作系统去遍历,确定哪个文件描述符可以读写, 然后告诉我们去处理,不过,当 select 函数返回后,用户依然需要遍历刚刚提交给操作系统的 list。

只不过,操作系统会将准备就绪的文件描述符做上标识,用户层将不会再有无意义的系统调用开销。

问题

  • 最多只能管理 1024 个fd(文件描述符)
  • 很多fd的没有就绪或超时,而且短时间内也完不成的话, 还是会不停的去遍历问询,影响效率。

poll(同步非堵塞)

数据结构: pollfd 结构

**作用:**它和 select 的主要区别就是,去掉了 select 只能监听 1024 个文件描述符的限制。

epoll(异步非堵塞)

数据结构:链表加红黑树

链表存储:活跃连接,红黑树存储:socket节点

链表中为活跃的链接,红黑树中放的是所有事件。这样一来,当收到内核的数据时,只需遍历链表中的数据就行了,而注册read事件或者write事件的时候,向红黑树中记录。

调用过程:

  • epoll_create() 系统启动时,在 Linux 内核里创建 epoll 实例(申请一个红黑树 rbTree 和就绪链表 readyList),以便存放 socket 节点;

  • epoll_ctl() 每新建一个连接,都通过该函数操作 epoll 对象,在这个对象的红黑树里增、删、改对应的 socket 节点,绑定一个回调函数;

  • epoll_wait() 阻塞唤醒,只遍历一次,之后等待事件异步唤醒数据传入,并完成对应的 IO 操作。相应分三步:

    • 阻塞线程
    • 传入数据,内核查找红黑树中准备好的 socket,放入就绪链表 rdlist(过程是异步io,当数据准备好之后,系统自动返回,而不是一遍一遍select轮询查看数据是否准备好)
    • 就绪列表中的内容复制到 events(从内核态复制到用户态),准备循环处理这些已就绪的 socket 节点

改进:

  1. 内核中保存一份文件描述符集合,无需用户每次都重新传入,只需告诉内核修改的部分即可。

  2. 内核不再通过轮询的方式找到就绪的文件描述符,而是通过异步 IO 事件唤醒。

  3. 内核仅会将有 IO 事件的文件描述符返回给用户,用户也无需遍历整个文件描述符集合。

在select/poll时代,服务器进程每次都把这100万个连接告诉操作系统(从用户态复制句柄数据结构到内核态),让操作系统内核去查询这些套接字上是否有事件发生,轮询完后,再将句柄数据复制到用户态,让服务器应用程序轮询处理已发生的网络事件,这一过程资源消耗较大,因此,select/poll一般只能处理几千的并发连接。

如果没有I/O事件产生,我们的程序就会阻塞在select处。有个问题,我们从select仅知道了有I/O事件发生了,但却不知是哪几个流,只能无差别轮询所有流,找出能读或写数据的流进行操作。

使用select,O(n)的无差别轮询复杂度,同时处理的流越多,每一次无差别轮询时间就越长。

Redis 为什么不使用多线程?

原因有下面 3 个:

  1. Redis 的性能瓶颈不再 CPU ,主要在内存和网络io;
  2. 单线程编程容易并且更容易维护;
  3. 多线程就会存在死锁、线程上下文切换等问题,甚至会影响性能。

Redis6.0之前的版本真的是单线程吗?

Redis在处理客户端的请求时,包括获取 (socket 读)、解析、执行、内容返回 (socket 写) 等都由一个顺序串行的主线程处理,这就是所谓的“单线程”。但如果严格来讲从Redis4.0之后并不是单线程,除了主线程外,它也有后台线程在处理一些较为缓慢的操作,例如清理脏数据、无用连接的释放、大 key 的删除等等。

Redis6.0 之后为何引入了多线程?

Redis6.0 引入多线程主要是为了提高网络 IO 读写性能,因为这个算是 Redis 中的一个性能瓶颈(Redis 的瓶颈主要受限于内存和网络)。

Redis将所有数据放在内存中,内存的响应时长大约为100纳秒,对于小数据包,Redis服务器可以处理80,000到100,000 QPS,这也是Redis处理的极限了,对于80%的公司来说,单线程的Redis已经足够使用了。

但随着越来越复杂的业务场景,有些公司动不动就上亿的交易量,因此需要更大的QPS。常见的解决方案是在分布式架构中对数据进行分区并采用多个服务器,但该方案有非常大的缺点,例如要管理的Redis服务器太多,维护代价大;某些适用于单个Redis服务器的命令不适用于数据分区;数据分区无法解决热点读/写问题;数据偏斜,重新分配和放大/缩小变得更加复杂等等。

从Redis自身角度来说,因为读写网络的read/write系统调用占用了Redis执行期间大部分CPU时间,瓶颈主要在于网络的 IO 消耗, 优化主要有两个方向:

• 提高网络 IO 性能,典型的实现比如使用 DPDK 来替代内核网络栈的方式

• 使用多线程充分利用多核,典型的实现比如 Memcached。

协议栈优化的这种方式跟 Redis 关系不大,支持多线程是一种最有效最便捷的操作方式。所以总结起来,redis支持多线程主要就是两个原因:

• 可以充分利用服务器 CPU 资源,目前主线程只能利用一个核

• 多线程任务可以分摊 Redis 同步 IO 读写负荷

Redis6.0默认是否开启了多线程?

Redis6.0的多线程默认是禁用的,只使用主线程。

Redis多线程参考:https://mp.weixin.qq.com/s/FZu3acwK6zrCBZQ_3HoUgw
参考:https://blog.csdn.net/weixin_35973945/article/details/124153253
https://blog.csdn.net/lmx125254/article/details/118935332

Redis单线程和多线程相关推荐

  1. Redis单线程还是多线程?IO多路复用原理

    目录 专栏导读 一.Redis版本迭代 二.Redis4.0之前为什么一直采用单线程? 三.Redis6.0引入多线程 四.Redis主线程和IO线程是如何完成请求的? 1.服务端和客户端建立sock ...

  2. redis 多线程_Java架构师Redis单线程?别逗了,Redis6.0多线程重磅来袭

    2019年的 RedisConf 比以往时候来的更早一些,今年会议时间是4月1-3号,仍然是在旧金山鱼人码头Pier 27.恰逢今年是 Redis 第10周年,规模也比以往大一些,注册人数超过1600 ...

  3. Redis 是属于多线程还是单线程?

    不同版本的Redis是不同的,在Redis4.0之前,Redis是单线程运行的,但单线程并不代表效率低,像Nginx.Nodejs也是单线程程序,但是它们的效率并不低. 原因是Redis是基于内存的, ...

  4. Redis 属于单线程还是多线程?不同的版本有什么区别?

    Redis 是普及率最高的技术之一,同时也是面试中必问的一个技术模块,所以从今天开始我们将从最热门的 Redis 面试题入手,更加深入的学习和了解一下 Redis. 我们本文的面试题是 Redis 属 ...

  5. 单线程多线程_面试系列 redis为什么快amp;单线程amp;多线程

    redis为什么这么快 C语言实现,执行速度快 纯内存操作,数据读写在内存中,异步持久化到磁盘 丰富和高效的数据结构 基于非阻塞的I/O多路复用机制 单线程避免了上下文切换 Redis单线程 redi ...

  6. Redis 5.0.8+常见面试题(单线程还是多线程、先更新缓存还是数据库、雪崩穿透击穿解决办法...)

    Redis 6.0 保姆级教程(含微服务案例与完整面试题):https://www.yuque.com/yuxuandmbjz/redis Redis是单线程还是多线程 ?为什么这么设计 ? Redi ...

  7. redis是单线程还是多线程?

    1.Redis单线程 在一开始的时候,Redis采用的是单线程模型,因为Redis是一个基于内存的数据库,将所有的数据放入内存,所以使用单线程的操作效率是最高的,多线程会上下文切换消耗大量时间,对于内 ...

  8. Redis是单线程还是多线程问题

    在学习redis的过程中,很多文章都说redis是单线程,但在官方给出的说明中显示,redis6.0已经引入了多线程,对此我找了许多文档,将学习过程整理记录下来. 1.Redis单线程 在一开始的时候 ...

  9. Redis新特性、剖析线程模型(单线程与多线程)

    一. Redis6.0 新特性 1. 多线程IO redis6.0引入多线程IO,只是用来处理网络数据的读写和协议的解析,而执行命令依旧是单线程,所以不需要去考虑set/get.事务.lua等的并发问 ...

最新文章

  1. Linux那些事儿 之 戏说USB(28)设备的生命线(十一)
  2. 第十四章:springboot 定时任务
  3. Ubuntu14.04 + Matlab2014a + caffe + cuda + cudnn环境搭建
  4. 采用UltraISO制作U盘启动盘
  5. 【bzoj2245】[SDOI2011]工作安排 费用流
  6. (转载)深入理解Linux中内存管理---分段与分页简介
  7. 系统架构工作笔记-数据展示进程与读取数据进程分离,实现低耦合(展示软件可适用任意厂家数据库)
  8. 区块链项目开发区块链应用场景需满足3个
  9. 营销再好终归还要产品说话,留给大神X7的时间不多了
  10. 心理学是怎样产生的?
  11. 立志高远;毕业后计划
  12. 爬虫07 爬取阿里旅行特价机票
  13. 美国旅游签证办理流程
  14. Google VP8 Code 首次深入技术分析 1
  15. Linux命令入门教程(三):文件基础篇
  16. java listbox_将数据从Listbox1复制到Listbox2
  17. 计算机的显卡设置方法,怎么看电脑显卡配置 电脑显卡配置查看方法【详细介绍】...
  18. 1998年全国大学生数学建模竞赛A题——投资的收益和风险数模P133|lingo,matlab
  19. 产品必备技能(十二):如何写竞品分析报告?附实竞品分析报告实例(网易云音乐和QQ音乐)
  20. 5GNR漫谈15:OFDM与IFFT

热门文章

  1. flutter 仿照 uiswitch
  2. 因为文件共享不安全,所以你不能连接到文件共享。此共享需要过时的SMB1协议
  3. 微博、微信上的假消息害苦了哥
  4. 搞笑生活短视频为何涨粉飞快?有三个原因,抓住用户心理是关键
  5. 飞腾PHYTIUM FT-1500a性能测试-内存-PCIe
  6. XTP中CXTPReportControl中合并单元格
  7. k8s+docker实战(长篇)
  8. 高漫数位板1060PRO 8192级的驱动下载与安装
  9. 用例执行一半总是报错“An unknown server-side error occurred ...Original error: Error: socket hang up”
  10. 数据禾|全国10米DEM数字高程数据