有输入输出类型的交互系统都可以认为是I/O系统。

目录

一、IO操作

二、IO成本

三、IO分类

四、Mysql网络层IO(网络IO)

五、Mysql存储IO(磁盘IO)


一、IO操作

在计算机系统中I/O就是输入(Input)和输出(Output)的意思,针对不同的操作对象,可以划分为磁盘I/O模型,网络I/O模型,内存映射I/O, Direct I/O、数据库I/O等,只要具有输入输出类型的交互系统都可以认为是I/O系统,也可以说I/O是整个操作系统数据交换与人机交互的通道,这个概念与选用的开发语言没有关系,是一个通用的概念。

返回顶部目录


二 、IO成本

IO成本就是寻址时间和上下文切换所需要的时间,最主要是用户态和内核态的上下文切换。

  • 寻址时间(网络IO没有这一步)
    磁头从启动位置到达所要求的读/写位置所经历的全部时间,它包括寻道时间(Seektime)和平均等待时间(Rotationdelayorlatencytime)两部分。(读写时间很快,被忽略)

  • 上下文切换
    这里的上下文切换指的是同进程的线程上下文切换,所谓上下文就是线程运行需要的环境信息。

      用户态是无法直接访问磁盘等硬件上的数据的,只能通过操作系统去调内核态的接口,用内核态的线程去访问。
    

    1)首先,用户态线程需要一些中间计算结果保存CPU寄存器,保存CPU指令的地址到程序计数器(执行顺序保证),还要保存栈的信息等一些线程私有的信息。
    2)然后切换到内核态的线程执行,就需要把线程的私有信息从寄存器,程序计数器里读出来,然后执行读磁盘上的数据。读完后返回,又要把线程的信息写进寄存器和程序计数器。
    3)切换到用户态后,用户态线程又要读之前保存的线程执行的环境信息出来,恢复执行。

    这个过程是消耗时间的

返回顶部目录


三、IO分类

BIO (Blocking I/O):同步阻塞I/O模式,数据的读取写入必须阻塞在一个线程内等待其完成。这里使用那个经典的烧开水例子,这里假设一个烧开水的场景,有一排水壶在烧开水,BIO的工作模式就是, 叫一个线程停留在一个水壶那,直到这个水壶烧开,才去处理下一个水壶。但是实际上线程在等待水壶烧开的时间段什么都没有做。

NIO (New I/O):同时支持阻塞与非阻塞模式,但这里我们以其同步非阻塞I/O模式来说明,那么什么叫做同步非阻塞?如果还拿烧开水来说,NIO的做法是叫一个线程不断的轮询每个水壶的状态,看看是否有水壶的状态发生了改变,从而进行下一步的操作。

AIO ( Asynchronous I/O):异步非阻塞I/O模型。异步非阻塞与同步非阻塞的区别在哪里?异步非阻塞无需一个线程去轮询所有IO操作的状态改变,在相应的状态改变后,系统会通知对应的线程来处理。对应到烧开水中就是,为每个水壶上面装了一个开关,水烧开之后,水壶会自动通知我水烧开了。
返回顶部目录


四、Mysql网络层IO(网络IO)

在mysql的网络层,我们主要关注3个地方

1 》Poll、Select模型

2》 Max-connections

3》 connection复用

mysql在启动后,创建了socket server,绑定了3306端口,并对其进行监听。和java里的写法类似,用一个while循环来监听新来的connection,如果有了新连接,就创建一个新的连接线程去处理(不能超过max-connections)。

这种就是典型的BIO的模式,为每一个连接创建一个线程。并且,mysql在这里采用了IO多路复用,会有一个if语句来判断当前系统是否支持Poll模式,否则就走Select模型(各个系统默认都有实现)。

Poll模型和Select非常类似,只是少了1024个fd的限制,都是采用遍历数组轮询有没有新IO事件的方式,在连接数较少的情况下,性能优异,要好于epoll。

关于BIO和poll、select、epoll,如果不太了解,可以看这一篇。

mysql基于BIO,本质上是不接受大量的socket连接的,原因懂BIO的都知道,所以设置了max-connections这个限制,超过设置的max,那么新来的连接会被拒绝。那么,我们迎来了第一个问题,为什么是BIO,而不是可以承受更大连接数的NIO和AIO呢?是否用NIO就会更好呢?

为什么Mysql的网络层用的BIO

先来看看bio和nio的区别,在BIO模式下,调用read,如果发现没数据,就会Block住。在NIO模式下,调用read,如果发现没数据,就会立刻返回-1, 并且errno被设为EAGAIN。

做server开发的都知道,tomcat、netty之类的web服务器,都是基于NIO+IO多路复用的模式,来大幅提升性能,承载高并发访问的。但是到了DB层,就变成了hakiri、druid之类的线程池,开启10个线程去连接mysql,反复复用这个线程池。

首先要理解一个概念,NIO+IO多路复用并不是指多个用户socket共享一个IO,从而使得服务端的socket数量大减。而是把多个socket连接,归并到一个进程进行管理,譬如用一个大数组来聚合起来,然后循环遍历这个数组,来一次性把多个连接的事件通知业务代码进行处理。这个很好理解,之前是给每个孩子分配一个老师,孩子没事时,老师也跟着闲着等待。现在是,把一大堆孩子归一个老师管,老师每次都从头到尾问一遍,有没有事,有事了再处理。这样就大幅减少了server的压力,高效利用资源。

对mysql来说,一般都会有多个连接,毕竟并发肯定是要有的。不可能做个查询,也要大家一起排队等上一个人查询完。所以线程池和并发是一定的。

mysql和web Server有一个重大区别,一个Web请求,往往是无状态的,一问一答的时候居多,请求也往往比较短促,对于顺序性也不是十分严格,哪怕是后请求的响应比先请求的提前到,也是有可能的。而DB就不一样了,DB采用session作为一个连接会话,这一个session里,SQL的执行必须是串行、同步、有序的,而不能是异步乱序的。原因都明白,一个session内可能有多个操作,增删改查、事务隔离,必须保证顺序不能乱。DB维护这样一个session,是要花费远大于web Server处理一个请求的资源才能完成的。

那么对于DB来说,连接是非常耗资源的事情,限制连接数是非常有必要的。绝不是平时当你连接mysql出问题时,就听别人的,随便加大应用服务的连接池和增大mysql的max-connection。往往你做的这些,不能改善mysql的性能。后面会有例子,来讲当进行非常密集的数据库操作时,连接池的数量对性能产生的巨大影响。

扯了这么多,貌似没有讲为什么用BIO,而不是NIO。

原因很简单,JDBC不支持,JDBC出现了20年了,它是一个标准,在它被提出时,只有BIO模型一家,还没有别的IO呢,你用个毛线。各家数据库驱动对JDBC的实现都是BIO的形式,你的mysql驱动connector早早地实现了JDBC标准,就是采用阻塞的方式。当你进行一个select查询,在查询没有完成之前,整个调用线程会被卡住,等到天荒地老也要等下去,绝不是一请求立马收到返回,然后等mysql回调你结果。

民间也有人修改了mysql的协议,增加了NIO+多路复用的功能,但是本身形不成气候,根本原因还是mysql和web server功能意义都不一样,确切地说,90%的场景下,你不需要一个NIO的数据库。

BIO+连接池已经发展了很多年,大部分问题都已经解决,在目前的java环境中,是非常靠谱的方案。已经出现了很多优秀的连接池框架,你只需要配置好账号密码和连接池数量,就能很开心的使用mysql了。

而从mysql的角度来说,客户端多是一些IO密集型的应用,在一个线程里频繁做大量IO操作,而不是说有巨多的客户端来反复连接我。毕竟,mysql的用户是你写的几个程序应用,而web server的用户是千千万的吃瓜群众。

返回顶部目录


五、Mysql存储IO(磁盘IO)

InnoDB引擎的数据存储是基于磁盘的(为什么强调Innodb呢,因为还有memory是基于内存的),也就是说数据是存储在磁盘上的,但是我们都知道,CPU和磁盘之间不可逾越的速度鸿沟(至少目前是这样)。如果每次查询/修改数据,都同步地(或者说实时地)去查询磁盘/修改磁盘,那么数据库系统的性能,必然受到极大的负面影响。

IO有四种类型:连续读,随机读,随机写和连续写,连续读写的IO size通常比较大(128KB-1MB),主要衡量吞吐量,而随机读写的IO size比较小(小于8KB),主要衡量IOPS和响应时间。数据库中的全表扫描是连续读IO,索引访问则是典型的随机读IO,日志文件是连续写IO,而数据文件则是随机写IO。

数据库系统基于传统磁盘访问特性来设计,最大特点是日志文件采用sequential logging,数据库中的日志文件,要求必须在事务提交时写入到磁盘,对响应时间的要求很高,所以设计为顺序写入的方式,可以有效降低磁盘寻道花费的时间,减少延迟时间。日志文件的顺序写入,虽然是物理位置是连续的,但是并不同于传统的连续写类型,日志文件的IO size很小(通常小于4K),每个IO之间是独立的(磁头必须抬起来重新寻道,并等待磁盘转动到相应的位置),而且间隔很短,数据库通过log buffer(缓存)和group commit的方式(批量提交)来达到提高IO size的大小,并减少IO的次数,从而得到更小的响应延迟,所以日志文件的顺序写入可以被认为是“连续位置的随机写入”,更关注IOPS,而不是吞吐量。

数据文件采用in place uddate的方式,意思是数据文件的修改都是写入到原来的位置,数据文件不同于日志文件,并不会在事务commit时写入数据文件,只有当数据库发现dirty buffer过多或者需要做checkpoint动作时,才会刷新这些dirty buffer到相应的位置,这是一个异步的过程,通常情况下,数据文件的随机写入对IO的要求并不是特别高,只要满足checkpoint和dirty buffer的要求就可以了。

返回顶部目录

本文例子借鉴了网上的资源,如有侵权部分,请联系作者删除

Mysql的IO介绍及原因详解相关推荐

  1. wow mysql dbc_DBC中悲观锁介绍附案例详解

    DBC中悲观锁介绍附案例详解 了解下DBC中悲观锁: 代码如下: BDUtils 工具类: package JDBC; import java.sql.*; public class BDUtils ...

  2. mysql完全备份 二进制日志,MySQL二进制日志备份和恢复详解

    原文链接:http://www.showerlee.com/archives/681 ****经实践,该教程ok,特在此分享**** 基本概念 定义: 二进制日志包含了所有更新了数据或者已经潜在更新了 ...

  3. mysql语句性能开销检测profiling详解

    转载自 mysql语句性能开销检测profiling详解 之前我介绍过msyql查询优化explain检查命令的使用,explain主要是检查sql语句的基本性能,sql是否优秀,但不能查看具体的涉及 ...

  4. mysql启动参数(/etc/my.cnf)详解汇总

    mysql启动参数(/etc/my.cnf)详解汇总 MYSQL–my.cnf配置中文详解 basedir = path 使用给定目录作为根目录(安装目录). character-sets-dir = ...

  5. mysql dba系统学习-数据库事务详解

    mysql dba系统学习-数据库事务详解 上个星期去面试数据库管理员的工作,笔试通过之后就是直接的面试,他问了我一个问题,叫我介绍哈数据库的事务的看法和理解,但是不知所错的没有章法的乱答一气,唉唉, ...

  6. DL之ShuffleNetV2:ShuffleNetV2算法的简介(论文介绍)、架构详解、案例应用等配图集合之详细攻略

    DL之ShuffleNetV2:ShuffleNetV2算法的简介(论文介绍).架构详解.案例应用等配图集合之详细攻略 目录 ShuffleNetV2算法的简介(论文介绍) 1.论文特点 2.基于硬件 ...

  7. DL之ShuffleNet:ShuffleNet算法的简介(论文介绍)、架构详解、案例应用等配图集合之详细攻略

    DL之ShuffleNet:ShuffleNet算法的简介(论文介绍).架构详解.案例应用等配图集合之详细攻略 相关文章 DL之ShuffleNet:ShuffleNet算法的简介(论文介绍).架构详 ...

  8. DL之Xception:Xception算法的简介(论文介绍)、架构详解、案例应用等配图集合之详细攻略

    DL之Xception:Xception算法的简介(论文介绍).架构详解.案例应用等配图集合之详细攻略 目录 Xception算法的简介(论文介绍) 1.论文使用的数据集 Xception算法的架构详 ...

  9. DL之RetinaNet:RetinaNet算法的简介(论文介绍)、架构详解、案例应用等配图集合之详细攻略

    DL之RetinaNet:RetinaNet算法的简介(论文介绍).架构详解.案例应用等配图集合之详细攻略 目录 RetinaNet算法的简介(论文介绍) 0.实验结果 1.RetinaNet算法的特 ...

最新文章

  1. 0811-按钮操作(加法计算器)(拖控件找控件代码属性名称)(frame center bounds)(上下左右移动button图片)...
  2. 代理类Proxy------ WeakHashMap----ReferenceQueue---- Reference
  3. 饥荒进地洞服务器无响应,饥荒联机洞穴设置及常见问题的解决方法
  4. 【IoT最佳实践】设备获取实时天气信息
  5. (原创)面向对象的系统对接接口编写。第4篇
  6. Windows_cmd_命令
  7. 上传图片至fastdfs显示连接超时
  8. 二次元《尤里国简介》
  9. 0x0000006B蓝屏问题解决方法
  10. ABBYY教程—PDF识别模式如何使用?
  11. 校园网客户端不识别网卡
  12. 数据驱动测试一:使用TestNG进行数据驱动
  13. vue结合elementUI,MinUi
  14. 华为云桌面远程办公,真香!
  15. 流量卡官网源码 有后台带文章系统
  16. Java操作Word图表
  17. 自动气象站解决方案 案例分享
  18. Cause: java.sql.SQLException: SQL String cannot be empty 解决方案
  19. 2022 年山东省职业院校技能大赛“中职组” 网络搭建与应用赛项
  20. Delivering Smiles:亚马逊的温暖进行时

热门文章

  1. ios开发 静音键设置_iOS获取设备静音键的开关状态 误差优化
  2. (0014) H5-新闻网页案例
  3. Android中利用Application操作全局变量
  4. 引入antd组件样式_antd组件样式局部加载,用react-app-rewired插件应该怎么配置?...
  5. ubuntu搭建wordPress
  6. idea如何设置背景图
  7. 微信PC端第三方登录
  8. 手表的分针和时针怎么调啊?卡西欧G-SHOCK系列的问题
  9. kali使用msf简单制作木马
  10. 衣物洗涤领域,RFID技术前景广阔