加入收藏 | 设为首页 | 会员中心 | 我要投稿 宜春站长网 (https://www.0795zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长资讯 > 动态 > 正文

如何写最少的代码

发布时间:2021-02-02 15:54:27 所属栏目:动态 来源:互联网
导读:整个流程中,读取解析redis客户端命令和返回客户端结果两个步骤分别对应网络数据的读取和写入,这两个步骤对于redis来说,占用了大部分cpu时间,所以redis6.0多线程机制是针对这两个步骤的。 为了直观的更好了解整个流程,一般分为以下几个步骤: 当客户端有

整个流程中,读取解析redis客户端命令和返回客户端结果两个步骤分别对应网络数据的读取和写入,这两个步骤对于redis来说,占用了大部分cpu时间,所以redis6.0多线程机制是针对这两个步骤的。

为了直观的更好了解整个流程,一般分为以下几个步骤:

  1. 当客户端有新的socket连接时,主线程会负责接收连接,并把socket放入全局的等待队列中,当主线程处理完读事件之后,通过轮训的方式将这些连接分配给IO线程。
  2. 主线程会一直阻塞到IO线程读取Socket并解析完毕,这个解析过程是多个IO线程并行处理的,所以会很快。
  3. 等到IO线程解析命令完成,主线程以单线程的方式来执行这些命令,并把执行结果写入缓冲区,然后阻塞的等待IO线程回写socket数据
  4. IO线程读取缓冲区结果数据,把这些数据回写socket,返回给客户端。这个过程也是多个IO线程并行处理的,所以也会很快。
  5. 当所有的IO线程回写socket完毕,主线程回清空全局队列,等待下次新的请求到来。

redis现在已经成为了面试官必问的知识点之一,尤其是当新版本加入了“多线程”概念之后,面试题又是增加了一道难题。

redis单线程

redis在6.0之前的版本,很多同学认为是单线程,其实这个说法严格意义上来讲不太准确。“单线程”是指客户端发送的命令的接收,解析,执行,结果返回这个过程是由一个线程处理,这个线程就是主线程,这也是redis素有“单线程”定义的来源。

但是,redis也有其他后台线程在处理其他操作,比如那些比较慢,不太适合放主线程执行的操作,例如大key的删除,AOF的重写,快照的生成,无用连接的释放等。

单线程机制使得redis内部代码实现的复杂度和难度大大降低,请求都是按照串行化的顺序来依次执行,这大大降低了由于线程切换带来的资源消耗,而且又可以避免锁带来的一系列问题。所以平时开发使用redis的时候,我们可以实现分布式锁等一系列骚操作,这和Actor模型中,单个Actor的行为十分类似,串行的操作使我们可以摆脱多线程带来的一系列执行顺序的痛苦。

至于redis为什么不使用多线程呢?官方曾经做过类似问题的回复,大体意思是,redis由于cpu成为瓶颈的几率几乎不存在,redis的性能主要受限于内存和网络,当然,我认为这个解释并非是绝对的。当redis开启持久化之后,吞吐量会大幅度下降,除非非常必要,不然在很多业务场景下尽量不要开启redis的持久化。

redis单线程瓶颈

redis将所有数据放在内存中,在充分利用pipelining技术的情况下,QPS可达百万,这个量级对于普通的中小公司已经足以,就算是再大一点的请求量,利用redis集群方式也能抗住。但是redis集群也是有缺陷的:

  • redis集群需要更多的服务器资源来支撑,这无疑加大了公司的支出费用和资源成本。
  • redis集群虽然可以通过增加副本的方式来解决热点key的读问题,但是热点key的写依然比较棘手

从redis自身的处理请求过程来看,对网络数据的读写以及对命令的解析占用了大部分cpu时间,瓶颈在于网络IO的消耗以及对CPU不能充分的利用。而要突破这个瓶颈呢,一般有两种解决方案:

网络请求的处理不再依靠内核,而在用户态处理。但是这种方式需要修改内核网络栈的实现方式,这会带来很多开发工作量,而且设计到核心代码修改,可能会引入新的bug,导致系统不稳定

利用多线程优势,充分利用服务器多核的特性,采用多个IO线程来并行处理网络请求。

很显然,redis6.0采用的是多线程的方式。

无论是针对redis集群,还是针对单体架构,提高单机redis的处理速度和吞吐量目前看百利而无一害。

redis多线程

无论redis采用单线程还是多线程,其实每个请求的整体处理流程是一致的。


(编辑:宜春站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读