前言

在一定的策略下适度地初始化线程池的线程数有利于提高CPU的利用率,达到高效率地在同一段时间内处理多个任务,最佳的线程数量一般是

最佳线程数=(线程等待的时间与线程CPU执行时间之比+1)*CPU核数

像笔者电脑电脑的CPU为8核,假设DB操作、RPC操作、缓存操作等为900毫秒,CPU运行时间为100毫秒,那么以此公式要达到CPU利用率最高,合适的线程数应该为80个。

是不是线程数越多越好呢?

答案肯定是否定的,大名鼎鼎的redis就是单线程的,但它却非常地高效,基本操作都能达到十万量级每秒。

单线程的redis性能为何如此之高?

这段内容部分参考了《Redis开发与运维》,这本书笔者认为十分地实用,有兴趣的话可以买来一睹作者的妙笔。

一般来说单线程相较于多线程的处理能力要差,相当于吃麦麦,假设我是hx,在我面前有100个麦麦脆汁鸡,单线程就是要我自己一个人去消灭眼前的食物,多线程则是有多个hx去消灭麦麦脆汁鸡,其效率肯定是多线程的要高。redis使用单线程却能够达到每秒万级的处理能力主要归结于以下几点。

1.redis是纯内存访问,redis将所有的数据都放在内存中,内存的响应时间在100纳秒之内,它是redis达到每秒万级别访问的重要基础。

它不同于mysql这种关系型数据库的点在于,mysql在读写数据时都属于I/O操作,有学过计算机组成原理的都知道I/O设备和CPU之间的处理速度有着量级的差距,在早期CPU处理现行程序时,运行到I/O操作,往往需要中断现行程序,等待I/O操作完成,这使得CPU的利用率非常地低,到现在虽然有着I/O处理机的技术,但是与CPU相比还是天差地别。

虽然mysql支持多线程访问,在分库、分表以及优化sql语句的前提下,I/O操作带来的延迟依旧不可忽视,同时若不为sql语句上表级锁,行级锁在多线程条件下又会出现脏读,不可重复读,幻读等问题,上了锁,又会带来性能的下降。

相反,redis基于内存的、单线程的模式就不会有上诉的问题。

2. 单线程避免了线程切换和竞态产生的消耗。

现如今的操作系统都是抢占式的调度,多线程会使得CPU频繁地进行任务的切换,CPU执行任务的效率也就会降低,这也是在开发过程中,为什么要按照一定的策略来初始化线程池的线程数,对于服务端开发来说,锁和线程切换通常是性能杀手。

3. Redis采用了非阻塞的I/O,Redis使用epoll作为I/O多路复用技术的实现,再加上Redis自身的事件处理模型将epoll中的连接,读写,关闭都转换为事件,不在网络I/O上浪费过多的时间,这点又与mysql这种非关系型数据库不同。

什么是I/O多路复用技术?

多路指的是网络连接,复用指的是一个线程

  • I/O 多路复用是一种同步I/O,实现一个线程可以监视多个文件句柄
  • 一旦某个文件句柄就绪,就能够通知应用程序进行相应的读写操作
  • 没有文件句柄就绪就会阻塞应用程序,交出CPU

有关epoll的技术笔者能力有限,详情请看:https://juejin.cn/post/6882984260672847879

具体点就是:

用epoll技术创建多个网络连接到redis的单线程中,线程监控网络连接的活跃状态,一旦检测到便通知应用程序进行相应的读写操作,这里得益于epoll事件驱动的特点,网络连接多少是不限制的,线程检测到活跃的时间复杂度永远是O(1)。

结尾

每个数据库都有优缺点,mysql数据库有上述的缺点,它也有对现实关系抽象的优点。Redis有上述的优点,但它也怕命令执行过长而导致Redis服务端阻塞的缺点。非关系型数据库有其优缺点,关系型数据库有其优缺点,每个数据库的特点都还不一样,只能说是选择适合自己业务的数据库来使用。

在高并发开发,笔者更喜欢用Redis辅助mysql数据库,这里就涉及到Redis远程客户端操作服务端的技术了,在本篇不过多叙述。

Redis的单线程架构的更多相关文章

  1. 【Redis破障之路】三:Redis单线程架构

    众所周知,Redis是一个单线程架构的NoSQL数据库,但是是单线程模型的Redis为什么性能如此之高?这就是我们接下来要探究学习的内容. 1.Redis的单线程架构 1.1.Redis单线程简介 首 ...

  2. API的理解和使用——单线程架构

    核心知识点: 1.单线程机制:所有命令放在一个队列中 2.为什么Redis单线程这么快?内存中执行.非IO阻塞.避免线程切换和竞态产生的消耗. 3.单线程的问题?一个命令不能执行太长时间,不然会阻塞其 ...

  3. 高可用Redis(一):通用命令,数据结构和内部编码,单线程架构

    1.通用API 1.1 keys命令和dbsize命令 keys * 遍历所有key keys [pattern] 遍历模式下所有的key dbsize 计算Redis中所有key的总数 例子: 12 ...

  4. Redis单线程架构

    参考链接: http://blog.csdn.net/qqqqq1993qqqqq/article/details/77538202 单线程模型: redis中的数据结构并不全是简单的kv,还有lis ...

  5. Redis单线程架构以及工作方式

    一.单线程模型 Redis客户端对服务端的每次调用都经历了发送命令,执行命令,返回结果三个过程.其中执行命令阶段,由于Redis是单线程来处理命令的,所有每一条到达服务端的每一条到达服务端的命令都不会 ...

  6. 理解Redis的单线程模式

    0.概述 本文基于的Redis版本为4.0以下,在Redis更高版本中并不是完全的单线程了,增加了BIO线程,本文主要讲述主工作线程的单线程模式. 通过本文将了解到以下内容: Redis服务器采用单线 ...

  7. 《为什么说Redis是单线程的以及Redis为什么这么快!》

    为什么说Redis是单线程的以及Redis为什么这么快!   一.前言 近乎所有与Java相关的面试都会问到缓存的问题,基础一点的会问到什么是“二八定律”.什么是“热数据和冷数据”,复杂一点的会问到缓 ...

  8. 面试时说Redis是单线程的,被喷惨了!

    Redis是单线程的,这话搁以前,是横着走的,谁都知道的真理.现在不一样,Redis 变了.再说这句话,多少得有质疑的语气来跟你辩驳一番.意志不坚定的,可能就缴械投降,顺着别人走了. 到底是什么样的, ...

  9. 【原创】那些年用过的Redis集群架构(含面试解析)

    引言 今天是2019年2月12号,也就是大年初八,我接到了高中同学刘有码面试失利的消息. 他面试的时候,身份是某知名公司的小码农一枚,却因为不懂自己生产上Redis是如何部署的,导致面试失败! 人间惨 ...

随机推荐

  1. vue-bluJavascript - Vue - 插件(swiper、vue-preview)

    swiper swiper是一个支持滑动效果的js插件,它也支持在vue中使用,主要用于移动端的触摸滑动操作.Swiper中文网. 安装和导入插件 npm i vue-awesome-swiper - ...

  2. mzy,struts学习(二):struts.xml的配置

    <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "- ...

  3. 关于oracle样例数据库emp、dept、salgrade的mysql脚本复杂查询分析

    大家可以自行网上找资源(网上资源比较多,不建议下载我的),也可以在我这里下载: 1.取得每个部门最高薪水的人员名称:正确   一共有4个单位,要进行左外连接 其中一个单位没得员工 SELECT dep ...

  4. Promise.resolve()与Promise

    //Promise.resolve()和Promise.reject()常用来生成已经被决议为失败或者成功的promise案例 //Promise.reject()简单一些,不管传给它什么值,它决议为 ...

  5. HTTP系列之:HTTP缓存

    目录 简介 HTTP中的缓存种类 HTTP中缓存响应的状态 HTTP中的缓存控制 缓存刷新 revving 缓存校验 Vary响应 总结 简介 为了提高网站的访问速度和效率,我们需要设计各种各样的缓存 ...

  6. 从零开始实现简单 RPC 框架 8:网络通信之 Request-Response 模型

    Netty 在服务端与客户端的网络通信中,使用的是异步双向通信(双工)的方式,即客户端和服务端可以相互主动发请求给对方,发消息后不会同步等响应.这样就会有一下问题: 如何识别消息是请求还是响应? 请求 ...

  7. Zookeeper:进大厂不得不学的分布式协同利器!

    大家好,我是冰河~~ 最近,有很多小伙伴让我更新一些Zookeeper的文章,正好也趁着清明假期把之前自己工作过程当中总结的Zookeeper知识点梳理了一番,打算写一个[精通Zookeeper系列] ...

  8. .NET 5 支持 Azure Functions OpenAPI 扩展啦

    今年5月,在 Build大会上,Azure FunctionsOpenAPI的功能支持(预览版)正式宣布. 当时,它最高支持 v3 运行时--.NET Core 3.1 版本. 最近,它发布了 .NE ...

  9. springboot通过AOP和自定义注解实现权限校验

    自定义注解 PermissionCheck: package com.mgdd.sys.annotation; import java.lang.annotation.*; /** * @author ...

  10. EF Core性能优化(一)

    跟踪查询 返回实体类型的查询是默认会被跟踪的. 这表示可以更改这些实体实例,然后通过 SaveChanges() 持久化这些更改.非跟踪查询 在只读方案中使用结果时,非跟踪查询十分有用. 可以更快速地 ...