zoukankan      html  css  js  c++  java
  • 带着dd去探索Linux磁盘IO

    前言:Linux磁盘I/O是Linux内核的重要组成部分,是Linux开发工程师,特别是Linux存储开发工程师必须了解的一课。掌握了这一课,在遇到磁盘I/O相关问题时便会得心应手,缺席了这一课,遇到它时便会觉得云里雾里。dd是Linux的一款简单易用又功能强大的文件拷贝工具,大家再熟悉不过了,今天就带着它一起去探索Linux的磁盘I/O知识吧。

     

    dd测试

    首先看一下一份dd的测试数据,先感受下不同参数下dd的测试结果,然后带着疑问再去探索其中的原由。

     

    从上面的测试结果可以看到,没有oflag的时候,文件复制速度是oflag=direct的十几倍,oflag=direct的速度又比oflag=sync快了将近30%。dd使用oflag设置输出文件的标志位,oflag的标志位可以是direct、sync、dsync等等,造成它们处理速度如此巨大是什么原因呢,这就是我们今天要探究的知识,让我们开始吧。

     

    Linux磁盘I/0体系

    先看一张Linux的存储栈图:

     

    上面的存储栈图比较大而全,可以简略为以下的图片:

     

    Linux磁盘I/O可以分为以下层次:

    虚拟文件系统层

    文件系统层

    缓存层

    通用块层

    I/O调度层

    驱动层

    物理设备层

     

    虚拟文件系统层

    一般来说,应用程序不会直接跟物理设备直接打交道,基本上都是经过文件系统去操作设备。文件系统种类比较多,比如基于块设备的ext系列、xfs,网络文件系统nfs等等,各类文件系统的接口和实现各不相同,这就产生了一个问题,难道应用程序要为各种文件系统做特殊化处理吗?答案是不用的,因为有虚拟文件系统。虚拟文件系统层位于文件系统层之上,屏蔽了各种文件系统的差异,为应用层提供了一个统一的、虚拟的文件系统接口,也就是说应用程序使用一套统一的接口便可以操作所有的文件系统。

     

    文件系统层

    基于虚拟文件系统定义的统一接口,实现具体文件系统的功能,文件系统有三类:

    1.基于块设备的文件系统,如ext2、3、4,xfs;

    2.网络文件系统,如nfs、cifs;

    3.特殊文件系统,如/proc、裸设备文件。

     

    缓存层

    相比于CPU和内存,磁盘I/O属于慢速I/O,为了提高磁盘I/O的速度,Linux添加了缓存层。默认情况下,I/O数据先放到缓存中便返回上层,由内核再把数据写到设备,或者是上层把缓存数据读走。对于写操作,由于数据是放到缓存便返回了,上层认为I/O结束了,实际上数据还没落盘,如果这时候电脑异常掉电了,数据将会丢失。如果应用层要确保数据写到物理设备了,可以调用flush接口,缓存中的数据将会刷到物理设备中。Linux也提供了绕过缓存层的设置,打开文件的时候指定direct标识,数据将绕过缓存层继续执行。

    可通过free看到目前缓存的数据量,下图的buff/cache便是:

     

    通用块层

    由于设备种类繁多,接口也各不相同,为了屏蔽这些设备的差异,添加了通用块层。文件系统只需要跟统一的通用层打交道便可以跟设备通信,无需关心实际设备驱动的实现,简化了文件系统的实现。

     

    I/O调度层

    磁盘I/O请求是随机的,请求操作的磁盘位置也是随机的,为了减少磁盘I/O的磁盘,增大磁盘整体的吞吐量,Linux添加了I/O调度层。I/O调度层使用调度算法,更加合理的对I/O请求进行排序和合并,经典的是电梯算法。

    把磁盘I/O请求比作为乘坐电梯,分别有请求到3楼、到2楼、到6楼、到4楼,如果没有调度算法的处理,将会出现电梯从1楼到3楼,从3楼到2楼,从2楼到6楼,再从6楼到4楼,造成电梯资源的浪费;如果有了调度算法,对调度进行了合理的排序,将出现电梯先到2楼、3楼、4楼、6楼,一次从1楼到6楼便可以完成所有的请求。

     

    驱动层

    各类物理设备的驱动层,用于内核与物理设备通讯。内核会提供驱动的通用接口,设备商根据接口实现驱动程序并注册到内核便可实现内核与设备的通讯。

     

    物理设备层

    各种物理磁盘设备,提供实际的存储功能,慢速设备有传统的机械硬盘HDD、快速的有固态硬盘SSD和NVME。物理磁盘也会带有缓存,用于提供I/O速度,磁盘中带有电容,可保证哪怕掉电也能把缓存数据刷写到磁盘中。

     

    再看dd测试

    没oflag

    没有oflag时,dd按照默认的方式打开输出文件,默认是buffered I/O,数据写到缓存层便返回,所以速度最快。

    oflag=direct

    以该方式打开输出文件,数据写到磁盘缓存便返回,所以速度比上面的buffered I/O方式要慢。

    oflag=sync

    以该方式打开输出文件,数据全部落盘才返回,所以速度比上面的仅写到磁盘缓存要慢。

     

    结束语

    今天只是简浅的描述了Linux的磁盘I/O,能让我们对Linux的磁盘I/O有一个总体的认识,然后带着这个认识继续去探索更深更详细的知识,做到能在面对磁盘I/O相关问题时游刃有余。

  • 相关阅读:
    vue(七)--监听属性(watch)
    vue(六)--计算属性(computed)
    JVM参数配置&&命令工具
    GC回收算法&&GC回收器
    JVM宏观认知&&内存结构
    分布式配置中心Apollo——QuickStart
    了解敏捷开发
    服务链路跟踪 && 服务监控
    数据读写API——IO流
    Nginx+Zuul集群实现高可用网关
  • 原文地址:https://www.cnblogs.com/eflypro/p/14609738.html
Copyright © 2011-2022 走看看