Redis为什么这么快

Redis为什么这么快

说到redis第一个字绝对是快,但要是细说为什么这么快,绝大多数人的回答应该是redis基于内存操作,但真是这么简单吗?显然不是,我们常说redis是单线程的那为什么在持久化RDB时会fork子进程,redis的单线程到底是在哪些地方使用,redis为什么考虑使用单线程而不使用多线程呢?redis单线程为什么这么快呢?我们带着疑问可以往下面思考。

redis单线程在哪些地方使用

redis单线程并不是所有的操作都是单线程,例如持久化、集群数据同步、异步删除等等这些都是其它子线程操作,单线程只是指Redis的网络IO和键值对读写是由一个线程完成

redis为什么使用单线程

众所周知多线程能提高程序的吞吐量以及降低延迟,如果程序需要提升效率肯定会考虑引进多线程,但线程的数量并不是越多越好,线程数量增加CPU的上下文切换会带来资源的浪费,另外线程间会存在数据竞争为了保证数据的正确性需要添加互斥锁,互斥锁将有线程安全问题的数据串行执行保证线程安全,这也让程序的效率大打折扣。

redis为避免以上问题,索性只用单线程执行,redis官方解释如下

因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽。既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了

redis单线程为什么这么快

redis快的原因分析如下

  • 基于内存操作,其写入存储效率极佳。

  • 高效的数据类型如跳表、哈希表等。

  • redis采用多路复用IO模型,能够在网络IO操作中并发处理客户端请求。

那什么是多路复用IO模型呢?聊这个之前我们需要了解普通的网络IO模型。

普通网络IO模型

如果redis使用的是普通的IO模型,那么键值的读取get方法应该有如下执行过程

上图的网络模型存在阻塞的风险,主要是网络IO处理模块

  • accept:当网络IO开始监听但是一直没有和客户端建立正常连接会导致IO阻塞等待。

  • recv:redis通过recv从客户端读取请求,如果数据一直未到达那么将一直阻塞等待。

redis是单线程那么网络IO模型一旦发生阻塞,整个应用都将阻塞无法响应其它客户端请求,那如何解决这个问题呢?网络模型提供了非阻塞方法。

网络IO非阻塞模型

网络非阻塞模型主要依靠三个不同的方法,调用这些方法会返回不同类型的**套接字**。

什么是套接字呢?

TCP用主机的IP地址加上主机上的端口号作为TCP连接的端点,这种端点就叫做套接字(socket)或插口

这些套接字就可以实现网络IO的非阻塞模型,socket方法会返回主动套接字,接着调用listen方法会将主动套接字转换为监听套接字,这个套接字就可以监听客户端请求,调用accept方法接收到达的客户端请求,并且返回已连接套接字。

如果在普通IO模型中设置监听套接字非阻塞,那么在和客户端建立连接(调用网络IO处理的accept方法)后客户端一直未建立连接,redis线程可以返回执行其它操作,而不用一直等待,因为存在监听套接字,在客户端建立请求成功后会立即通知redis。

如果在普通IO模型中设置已连接套接字非阻塞,那么在等待客户端请求(调用网络IO处理的recv方法)已连接套接字一直未有数据返回,redis也不需要持续等待,可以立即返回,后续请求到达需要立即通知到redis。

多路复用IO模型

多路复用IO模型其实就是上述网络IO非阻塞模型的演化,Linux中的多路复用IO模型,指的是一个线程处理多个IO流,也就是我们常常听到的select/epoll机制,简单理解就是,redis在单线程下允许内核中存在多个监听套接字和已连接套接字,当套接字发现连接请求或者数据请求到达就会通知redis,redis立即处理,不需要redis阻塞等待请求到达,这样就实现了单个线程能处理多个网络IO请求。

多路复用IO模型结构图如下所示,多路复用IO模型让内核监听这些套接字,redis不再需要阻塞等待,所以redis才能实现一个线程处理多个客户端的请求。

为了在请求到达后即时通知redis,多路复用IO模型采用了事件回调函数,针对不同的事件调用不同的函数。

当内核监听到请求连接和读(写)数据请求时,监听套接字和已连接套接字会触发AcceptEvent事件和ReadEvent(WriteEvent)事件并且注册回调函数accept和get(put),产生的事件放入事件队列中,这样Redis就不用轮询查询是否有事件产生,节省CPU的资源消耗,直接由Redis在队列中出队事件,从而调用回调函数完成逻辑。

这种实现方式映射到现实中类似病人去医院看病,医生诊断前(Redis处理请求)都需要病人(请求)登记、排队、测量体温等流程,如果这些工作都由医生完成,那么医生的工作效率将非常低,所以医院设置分诊台,分诊台将看病前的工作(Linux内核监听)全部完成,然后转交给医生做诊断,这样即使是一个医生(单线程)效率也会很高。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值