Redis的单线程架构
前言
在一定的策略下适度地初始化线程池的线程数有利于提高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的单线程架构的更多相关文章
- 【Redis破障之路】三:Redis单线程架构
众所周知,Redis是一个单线程架构的NoSQL数据库,但是是单线程模型的Redis为什么性能如此之高?这就是我们接下来要探究学习的内容. 1.Redis的单线程架构 1.1.Redis单线程简介 首 ...
- API的理解和使用——单线程架构
核心知识点: 1.单线程机制:所有命令放在一个队列中 2.为什么Redis单线程这么快?内存中执行.非IO阻塞.避免线程切换和竞态产生的消耗. 3.单线程的问题?一个命令不能执行太长时间,不然会阻塞其 ...
- 高可用Redis(一):通用命令,数据结构和内部编码,单线程架构
1.通用API 1.1 keys命令和dbsize命令 keys * 遍历所有key keys [pattern] 遍历模式下所有的key dbsize 计算Redis中所有key的总数 例子: 12 ...
- Redis单线程架构
参考链接: http://blog.csdn.net/qqqqq1993qqqqq/article/details/77538202 单线程模型: redis中的数据结构并不全是简单的kv,还有lis ...
- Redis单线程架构以及工作方式
一.单线程模型 Redis客户端对服务端的每次调用都经历了发送命令,执行命令,返回结果三个过程.其中执行命令阶段,由于Redis是单线程来处理命令的,所有每一条到达服务端的每一条到达服务端的命令都不会 ...
- 理解Redis的单线程模式
0.概述 本文基于的Redis版本为4.0以下,在Redis更高版本中并不是完全的单线程了,增加了BIO线程,本文主要讲述主工作线程的单线程模式. 通过本文将了解到以下内容: Redis服务器采用单线 ...
- 《为什么说Redis是单线程的以及Redis为什么这么快!》
为什么说Redis是单线程的以及Redis为什么这么快! 一.前言 近乎所有与Java相关的面试都会问到缓存的问题,基础一点的会问到什么是“二八定律”.什么是“热数据和冷数据”,复杂一点的会问到缓 ...
- 面试时说Redis是单线程的,被喷惨了!
Redis是单线程的,这话搁以前,是横着走的,谁都知道的真理.现在不一样,Redis 变了.再说这句话,多少得有质疑的语气来跟你辩驳一番.意志不坚定的,可能就缴械投降,顺着别人走了. 到底是什么样的, ...
- 【原创】那些年用过的Redis集群架构(含面试解析)
引言 今天是2019年2月12号,也就是大年初八,我接到了高中同学刘有码面试失利的消息. 他面试的时候,身份是某知名公司的小码农一枚,却因为不懂自己生产上Redis是如何部署的,导致面试失败! 人间惨 ...
随机推荐
- MySQL时间戳、字符串、日期
1.时间转字符串:date_format(date, format) SELECT date_format(now(), '%Y-%m-%d') 2.时间转时间戳:unix_timestamp() S ...
- springmvc框架(Spring SpringMVC, Hibernate整合)
直接干货 model 考虑给用户展示什么.关注支撑业务的信息构成.构建成模型. control 调用业务逻辑产生合适的数据以及传递数据给视图用于呈献: view怎样对数据进行布局,以一种优美的方式展示 ...
- kubebuilder实战之七:webhook
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- CentOS 7.3安装Zabbix3.2
一.ZABBIX概述 Zabbix是一个基于Web界面的分布式系统监控的企业级开源软件.可以监视各种系统与设备的参数,保障服务器及设备的安全运营. Zabbix的功能和特性: 1.安装与配置简单: ...
- 第一次实战:XX漫画的XSS盲打
第一次实战:XX漫画的XSS盲打 XSS盲打 盲打是一种惯称的说法,就是不知道有没有XSS漏洞存在的情况下,不顾一切的输入XSS代码在留言啊投诉窗口啊之类的地方,尽可能多的尝试XSS的语句,就叫盲打. ...
- 痞子衡嵌入式:MCUXpresso Config Tools初体验(Pins, Clocks, Peripherals)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是MCUXpresso Config Tools三大件(Pins, Clocks, Peripherals). 不知道大家有没有这样的感受 ...
- Jenkins拉取Git远程仓库中指定目录至本地指定目录
Jenkins拉取源码是非常实用的操作,比如每天在跑自动化测试前,拉取Git远程仓库中最新的脚本至本地.那么,Jenkins如何拉取Git远程仓库中指定目录至本地指定目录呢?下面来看看具体的设置方法. ...
- GIS常用算法
目录 1.常用算法 1.1.计算两经纬度点之间的距离 1.2.根据已知线段以及到起点距离,求目标点坐标 1.3.已知点.线段,求垂足 1.4.线段上距离目标点最近的点 1.5.点缓冲 1.6.点和面关 ...
- tslib移植arm及使用
测试平台 宿主机平台:Ubuntu 12.04.4 LTS 目标机:Easy-ARM IMX283 目标机内核:Linux 2.6.35.3 tslib 1.4 下载 https://gitlab. ...
- Flask(4)- URL 组成部分详解
URL Uniform Resource Locator 的简写,中文名叫统一资源定位符 用于表示服务端的各种资源,例如网页 下面将讲解 Flask 中如何提取组成 URL 的各个部分 URL 组 ...