我们通常说,Redis 是单线程,主要是指 Redis 的网络 IO 和键值对读写是由一个线程来完成的,这也是 Redis 对外提供键值存储服务的主要流程。但 Redis 的其他功能,比如持久化、异步删除、集群数据同步等,其实是由额外的线程执行的。

Redis 为什么用单线程?

多线程的开销

对于一个多线程的系统来说,在有合理的资源分配的情况下,可以增加系统中处理请求操作的资源实体,进而提升系统能够同时处理的请求数,即吞吐率。

线程数与系统吞吐率

  • 管理共享资源的开销

多线程并发访问Redis

采用多线程开发一般会引入同步原语来保护共享资源的并发访问,这也会降低系统代码的易调试性和可维护性。为了避免这些问题,Redis 直接采用了单线程模式。

单线程 Redis 为什么那么快?

  • Redis 的大部分操作在内存上完成
  • 采用了高效的数据结构
  • 采用了多路复用机制使其在网络 IO 操作中能并发处理大量的客户端请求,实现高吞吐率

基本 IO 模型与阻塞点

下图显示了这一过程,其中,bind/listen、accept、recv、parse 和 send 属于网络 IO 处理,而 get 属于键值数据操作。既然 Redis 是单线程,那么,最基本的一种实现是在一个线程中依次执行上面说的这些操作。

Redis基本IO模型

在这里的网络 IO 操作中,有潜在的阻塞点,分别是 accept()recv()。当 Redis 监听到一个客户端有连接请求,但一直未能成功建立起连接时,会阻塞在 accept() 函数这里,导致其他客户端无法和 Redis 建立连接。类似的,当 Redis 通过 recv() 从一个客户端读取数据时,如果数据一直没有到达,Redis 也会一直阻塞在 recv()

这就导致 Redis 整个线程阻塞,无法处理其他客户端请求,效率很低。不过,幸运的是,socket 网络模型本身支持非阻塞模式。

非阻塞模式

在 socket 模型中,不同操作调用后会返回不同的套接字类型。socket() 方法会返回主动套接字,然后调用 listen() 方法,将主动套接字转化为监听套接字,此时,可以监听来自客户端的连接请求。最后,调用 accept() 方法接收到达的客户端连接,并返回已连接套接字

Redis套接字类型与非阻塞设置

基于多路复用的高性能 I/O 模型

Linux 中的 IO 多路复用机制是指一个线程处理多个 IO 流,就是我们经常听到的 select/epoll 机制。简单来说,在 Redis 只运行单线程的情况下,该机制允许内核中,同时存在多个监听套接字和已连接套接字。内核会一直监听这些套接字上的连接请求或数据请求。一旦有请求到达,就会交给 Redis 线程处理,这就实现了一个 Redis 线程处理多个 IO 流的效果。

下图就是基于多路复用的 Redis IO 模型。图中的多个 FD 就是刚才所说的多个套接字。Redis 网络框架调用 epoll 机制,让内核监听这些套接字。此时,Redis 线程不会阻塞在某一个特定的监听或已连接套接字上,也就是说,不会阻塞在某一个特定的客户端请求处理上。正因为此,Redis 可以同时和多个客户端连接并处理请求,从而提升并发性。

基于多路复用的Redis高性能IO模型

为了在请求到达时能通知到 Redis 线程,select/epoll 提供了基于事件的回调机制,即针对不同事件的发生,调用相应的处理函数。

这些事件会被放进一个事件队列,Redis 单线程对该事件队列不断进行处理。这样一来,Redis 无需一直轮询是否有请求实际发生,这就可以避免造成 CPU 资源浪费。同时,Redis 在对事件队列中的事件进行处理时,会调用相应的处理函数,这就实现了基于事件的回调。因为 Redis 一直在对事件队列进行处理,所以能及时响应客户端请求,提升 Redis 的响应性能。

以连接请求和读数据请求为例,具体解释一下:

这两个请求分别对应 Accept 事件和 Read 事件,Redis 分别对这两个事件注册 accept 和 get 回调函数。当 Linux 内核监听到有连接请求或读数据请求时,就会触发 Accept 事件和 Read 事件,此时,内核就会回调 Redis 相应的 accept 和 get 函数进行处理

linux redis客户端_为什么单线程Redis能那么快?相关推荐

  1. linux redis客户端_你见过能把Redis的主从复制讲这么明白的吗?

    概念 1.Conception(概念) Redis的复制也就是我们所说的主从复制,主机数据更新后根据配置和策略,自动同步到备机的master/slaver机制,Master以写为主,Slave以读为主 ...

  2. redis 客户端_你在使用什么 Redis 客户端工具?

    今天发现一个不错的 Redis 客户端工具:AnotherRedisDesktopManager. 兼容 Windows Mac Linux,号称又快又稳定,加载大量 keys 时也不会崩溃. Git ...

  3. redis 客户端_赞!推荐一款神仙颜值的 Redis 客户端工具

    点击上方蓝色字体,选择"设为星标" 回复"666"获取面试宝典 日常开发过程中,项目常常都会使用Redis来做缓存或者Session服务器,为了更直观方便,开发 ...

  4. Redis基础_模拟使用redis是如何缓解数据库的压力

    让我们开始用Redis来缓存信息,缓解数据库的压力吧! 我们搭起了这样一个框架,一台客户端,一台Redis缓存服务器: 一开始风和日丽,系统运行良好. 后来,我们系统中使用Redis的客户端越来越多, ...

  5. php redis 投票_高可用Redis服务架构分析与搭建

    HorstXuhttps://www.cnblogs.com/xuning/p/8464625.html 基于内存的Redis应该是目前各种web开发业务中最为常用的key-value数据库了,我们经 ...

  6. 狂神redis笔记_狂神说redis笔记(三)

    八.Redis.conf 容量单位不区分大小写,G和GB有区别 可以使用 include 组合多个配置问题 网络配置 日志 # 日志 # Specify the server verbosity le ...

  7. mac redis 客户端_分享一个免费好用的Redis桌面客户端

    今天波波为做开发的朋友们分享一个免费好用的Redis桌面客户端.这个工具纯属机缘巧合下发现的,前几天波波在开发一个物联网平台,硬件通信部分用了Workman Gateway来负责通信和消息推送,结果因 ...

  8. Redis为什么使用单进程单线程方式也这么快

    [转] http://www.syyong.com/db/Redis-why-the-use-of-single-process-and-single-threaded-way-so-fast.htm ...

  9. redis 多线程_唬人的Redis多线程,也就那么回事

    不羡鸳鸯不羡仙,一行代码调半天.原创:小姐姐味道(微信公众号ID:xjjdog),欢迎分享,转载请保留出处. 周末被一位小同学憋的很窝火. 他要和我探讨一下,redis到底是多线程的还是单线程的.这个 ...

最新文章

  1. 【Python自动化测试】setuptools
  2. [RN] React Native 键盘管理 在Android TextInput遮盖,上移等问题解决办法
  3. IBATIS错误汇总
  4. java dayofweek_Java DayOfWeek getDisplayName()用法及代碼示例
  5. 53. Leetcode 112. 路径总和 (二叉树-二叉树路径和)
  6. Input.GetAxis 获取轴
  7. hdu 1115 计算多边形重心
  8. .NET 大会今日开幕 |这些白嫖福利不看肠子都悔青
  9. 快速搭建springmvc+spring data jpa工程
  10. springmvc怎么设置更改了界面不用重启_CentOS root登录密码忘记了 怎么办?
  11. [转载总结]Linux环境下C++运行时动态链接库加载要点总结
  12. 外星人bios按f2调风扇_外星人电脑上海维修站地址「上海市飞雕国际大厦2703室」...
  13. IIC软件模拟-读写EEPROM
  14. java程序中单方法接口通常是,Android面试题1--Java基础之线程(持续更新)
  15. C语言size_t类型
  16. 光驱是DVD,而系统却显示为CD驱动器的原因
  17. 计算机设备没有音频,计算机上没有音频设备是什么意思?
  18. 各位前辈请问你们的本科毕业论文的外文文献都是从哪里找的,我搜到的都是中国的翻译成英语的?...
  19. 项目管理网络图概念总结
  20. 有关“凸”方面的概念:凸(集/函数/优化/二次规划)

热门文章

  1. python数据分析神器_太香了!墙裂推荐6个Python数据分析神器!!
  2. 计算机工作原理 仿真,虚拟DCS仿真工作原理
  3. 计算机一级怎么描述,计算机一级「关于RGB正确的描述的是」相关单选题
  4. 自考18年4月计算机应用基础,2019年自学考试计算机应用基础试题(18)
  5. Bash脚本教程之目录堆栈
  6. 深入理解表单脚本系列第一篇——表单对象
  7. CSS 学习路线(一)元素
  8. nyoj 55 懒省事的小明 优先队列 multiset 还有暴力
  9. vue/cli3 配置vux
  10. hihocoder1543 SCI表示法