Mysql的IO介绍及原因详解

article/2025/4/27 0:31:18
有输入输出类型的交互系统都可以认为是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的要求就可以了。

返回顶部目录

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


http://chatgpt.dhexx.cn/article/RcaVvIxF.shtml

相关文章

IO概念

IO概念和五种IO模型 一、什么是IO? 我们都知道unix世界里、一切皆文件、而文件是什么呢?文件就是一串二进制流而已、不管socket、还是FIFO、管道、终端、对我们来说、一切都是文件、一切都是流、在信息交换的过程中、我们都是对这些流进行数据的收发操…

顺序IO和随机IO

顺序IO和随机IO 什么是顺序IO和随机IO如何解决随机IO造成的性能损失?问题什么是IOPS?机械硬盘和固态硬盘在随机IO上性能的影响因素?SSD作为随机存储设备,其访问任意一块的时间应该是相等的,为什么顺序IO还是快于随机IO? 什么是顺…

绘图工具-draw.io

draw.io是一个可配置的图表/白板可视化应用程序。draw.io 由英国软件公司JGraph Ltd拥有和开发。这是一个开源项目(但对贡献是封闭的),github链接:https://github.com/jgraph,可以绘制流程图、UML、类图、组织结构图、…

什么是IO Pad?

1.什么是IO pad? IO pad是一个芯片管脚处理模块,即可以将芯片管脚的信号经过处理送给芯片内部,又可以将芯片内部输出的信号经过处理送到芯片管脚。输入信号处理包含时钟信号,复位信号等,输出信号包含观察时钟、中断等…

Drawio使用简介(慢慢更新中)

drawio是一款强大、免费的绘图工具(基本可以替代收费的visio等),使用起来非常方便。支持网页版使用(网页版可以自己部署一套)以及客户端使用(支持windows,MacOS以及Linux)。 该项目…

计算机io接口主要功能,io接口的功能是什么

IO接口又称为输入输出接口,是信息处理系统与外部世界之间的通信。输入是系统接收的信号或数据,输出是从其发送的信号或数据。该术语也可以用作行动的一部分; 到“执行I / O”是执行输入或输出操作。 IO 接口,又称为输入输出接口,是信息处理系统(例如计算机)与外部世界(可能是人…

到底什么是IO

IO 作为操作系统的核心知识之一, 无论是在本机、传统的单体应用、还是分布式系统中,都有非常重要的地位. 今天就和大家系统地聊一聊 IO 相关的东西. IO IO,Input/Output 简写,是指内存和外设之间的数据复制的过程. 输入是指数据从外设复制到内存中, 输…

一文掌握 IO 基础知识与概念

💞哈喽!大家好,我是HappyGirl快乐女孩💞 😜是一位爱好技术的【技术Fans】!😜 💞💞💞 如果有对技术感兴趣的宅友,欢迎关注💞&#x1f4…

韦东山freeRTOS系列教程之【第三章】任务管理

文章目录 系列教程总目录概述3.1 基本概念3.2 任务创建与删除3.2.1 什么是任务3.2.2 创建任务3.2.3 示例1: 创建任务3.2.4 示例2: 使用任务参数3.2.5 任务的删除3.2.6 示例3: 删除任务 3.3 任务优先级和Tick3.3.1 任务优先级3.3.2 Tick3.3.3 示例4: 优先级实验3.3.4 示例5: 修改…

FreeRTOS教程——定时器(二)

Free RTOS定时器 一、概念 一、概论 软件定时器允许设置一段时间,当设置的时间到达之后就执行指定的功能函数,被定时器 调用的这个功能函数叫做定时器的回调函数。回调函数的两次执行间隔叫做定时器的定时周期, 简而言之,当定时…

韦东山freeRTOS系列教程之【第二章】内存管理

文章目录 教程目录2.1 为什么要自己实现内存管理2.2 FreeRTOS的5种内存管理方法2.2.1 Heap_12.2.2 Heap_22.2.3 Heap_32.2.4 Heap_42.2.5 Heap_5 2.3 Heap相关的函数2.3.1 pvPortMalloc/vPortFree2.3.2 xPortGetFreeHeapSize2.3.3 xPortGetMinimumEverFreeHeapSize2.3.4 malloc…

FreeRTOS学习记录(安富莱FreeRTOS教程摘录)

FreeRTOS学习资料: 安富莱论坛FreeRTOS教程 FreeRTOS源码下载链接 第1章 为什么选用FreeRTOS 1.1 FreeRTOS优势 FreeRTOS优势 最大的优势就是开源免费,商业使用的话不需要用户公开源代码,也不存在任何版权问题,是当前小型嵌入…

STM32 FreeRTOS系列教程(一)FreeRTOS简介

参考资料:《正点原子STM32F4 FreeRTOS开发手册_V1.1》《野火FreeRTOS 内核实现与应用开发实战—基于STM32》 学习RTOS的意义 当我们进入嵌入式这个领域的时候,往往首先接触的都是单片机编程,单片机编程又 首选51 单片机来入门。这里面说的单…

FreeRTOS使用教程(配合CubeMX)

FreeRTOS使用教程(配合CubeMX) 一、CubeMX配置 在选择后单片机芯片后,在Middleware中选择FREERTOS的CMSIS_V1版本即可在工程开启FreeRTOS。 关于FreeRTOS的具体配置一般集中在Kernel Setting中。具体参数一般可以默认,有特殊需求…

【STM32】STM32CubeMX使用FreeRTOS教程1----定时器学习

【STM32】STM32CubeMX使用FreeRTOS教程1----定时器学习 前言 本教程将对应外设原理,HAL库、STM32CubeMX和FreeRTOS结合在一起讲解,分析学习过程中遇到的问题和一些注意事项。 知识概括: SMT32定时器原理 STM32CubeMX创建定时器例程 HAL库…

[FreeRTOS系列教程]学习FreeRTOS前的准备工作-----初学者必看

转自:http://bbs.armfly.com/read.php?tid1552 转载说明:本文仅为转载,下面有几位同学询问对应的教程,教程请参考下面的链接,是以帖子的形式分章节说明。 http://bbs.armfly.com/thread.php?fid14&type29&…

FreeRTOS基本教程零:STM32 FReeRTOS 移植流程

一、资料准备 FreeRTOS源码下载地址: https://github.com/FreeRTOS/FreeRTOShttps://github.com/FreeRTOS/FreeRTOS我移植的是FreeRTOSv9.0.0 stm32裸机程序: 二、FreeRTOS目录 一共有三个文件夹 其中Demo文件夹中是FreeRTOS的例程,Licen…

基于STM32的实时操作系统FreeRTOS移植教程(手动移植)

前言:此文为笔者FreeRTOS专栏下的第一篇基础性教学文章,其主要目的为:帮助读者朋友快速搭建出属于自己的公版FreeRTOS系统,实现后续在实时操作系统FreeRTOS上的开发与运用。操作系统的学习与运用可以说是每位嵌入式开发工程师必须…

STM32F103--移植FreeRTOS完整教程

最近按照正点原子教程开始学习FreeRTOS,发现其手册的移植教程中有些地方可能不是那么详细,在此基于正点原子做一期最完整的FreeRTOS移植教程给大家。 小b将本次教程整理的资料放在网盘,以下链接供各位小伙伴下载和学习: 链接&…

FreeRTOS 正点原子教程学习笔记

正点原子视频教程 FreeRTOS(教程非常详细) 小知识 如果创建了任务却完全空着,没有while(1){延时}的话,整个程序会卡住,其他正常的任务无法运行。如果任务里单单有赋值之类的操作也会卡死在这个任务&#…