O 那些事儿.docx
LinuxI/O那些事儿FilesystemSizeUsedAvailCapacityMountedontank/srev7.1G117K7.1G0%/mnt/srev创立了一个zfs挂载到了/mnt/srev这里没有指定zfs的quota创立的zfs大小即zpool大小对zfs设置quotaroot:#zfssetquota1Gtank/srevroot:#df-htank/srevFilesystemSizeUsedAvailCapacityMountedontank/srev1.0G118K1.0G0%/mnt/srevZFS特性Pool存储上面的层级图以及操作步骤可以看到zfs是基于zpool创立的zpool可以动态扩容意味着存储空间可以以动态扩容而且可以创立多个文件系统文件系统分享完好的zpool空间无需预分配。事务文件系统zfs的写操作是事务的意味着要么就没写要么就写成功了不会像其他文件系统那样应用翻开了文件写入还没保存的时候断电导致文件为空。zfs保证写操作事务采用的是copyonwrite的方式当blockB有修改变成B1的时候普通的文件系统会直接在blockB原地进展修改变成B1zfs那么会再另一个地方写B1然后再在后面平安的时候对原来的B进展回收这样结果就不会出现B被翻开而写失败的情况大不了就是B1没写成功这个特性让zfs在断电后不需要执行fsck来检查磁盘中是否存在写操作失败需要恢复的情况大大提升了应用的可用性。ARC缓存ZFS中的ARC(AdjustableReplacementCache)读缓存淘汰算法是基于IBM的ARP(AdaptiveReplacementCache)演化而来。在一些文件系统中实现的标准LRU算法其实是有缺陷的比方复制大文件之类的线性大量I/O操作导致缓存失效率猛增大量文件只读一次放到内存不会被再读坐等淘汰。另外缓存可以根据时间来进展优化LRU最近最多使用可以以根据频率进展优化LFU最近最常使用这两种方法各有优劣但是没方法适应所有场景。ARC的设计就是尝试在LRU以及LFU之间找到一个平衡根据当前的I/Oworkload来调整用LRU多一点还是LFU多一点。ARC定义了4个链表LRUlist最近最多使用的页面存详细数据LFUlist最近最常使用的页面存详细数据GhostlistforLRU最近从LRU表淘汰下来的页面信息不存详细数据只存页面信息GhostlistforLFU最近从LFU表淘汰下来的页面信息不存详细数据只存页面信息ARC工作流程大致如下LRUlist以及LFUlist填充以及淘汰经过以及标准算法一样当一个页面从LRUlist淘汰下来时这个页面的信息会放到LRUghost表中假如这个页面一直没被再次引用到那么这个页面的信息最终也会在LRUghost表中被淘汰掉假如这个页面在LRUghost表中未被淘汰的时候被再一次访问了这时候会引起一次幽灵phantom命中phantom命中的时候事实上还是要把数据从磁盘第一次放缓存但是这时候系统知道刚刚被LRU表淘汰的页面又被访问到了讲明LRUlist太小了这时它会把LRUlist长度加一LFU长度减一对于LFU的经过也与上述经过类似ZFS参考资料关于ZFS详细介绍可以参考这篇磁盘类型磁盘根据不同的分类方式有各种不一样的类型。磁盘的存储介质根据磁盘的存储介质可以分两类大众都很熟悉HDD机械硬盘SSD固态硬盘磁盘的接口根据磁盘接口分类IDE(IntegratedDriveElectronics)SCSI(SmallComputerSystemInterface)SAS(SerialAttachedSCSI)SATA(SerialATA).不同的接口往往分配不同的设备名称。比方IDE设备会分配一个hd前缀的设备名SCSI以及SATA设备会分配一个sd前缀的设备名。假如是多块同类型的磁盘就会按照a、b、c等的字母顺序来编号。Linux对磁盘的管理其实在Linux中磁盘实际上是作为一个块设备来管理的也就是以块为单位读写数据并且支持随机读写。每个块设备都会被赋予两个设备号分别是主、次设备号。主设备号用在驱动程序中用来区分设备类型而次设备号那么是用来给多个同类设备编号。g18-299on#ls-l/dev/sda*brw-rw-1rootdisk8,0Apr2515:53/dev/sdabrw-rw-1rootdisk8,1Apr2515:53/dev/sda1brw-rw-1rootdisk8,10Apr2515:53/dev/sda10brw-rw-1rootdisk8,2Apr2515:53/dev/sda2brw-rw-1rootdisk8,5Apr2515:53/dev/sda5brw-rw-1rootdisk8,6Apr2515:53/dev/sda6brw-rw-1rootdisk8,7Apr2515:53/dev/sda7brw-rw-1rootdisk8,8Apr2515:53/dev/sda8brw-rw-1rootdisk8,9Apr2515:53/dev/sda9这些sda磁盘主设备号都是8表示它是一个sd类型的块设备次设备号0-10表示这些不同sd块设备的编号GenericBlockLayer以及VFS类似为了对上层屏蔽不同块设备的差异内核在文件系统以及块设备之前抽象了一个GenericBlockLayer通用块层有时候一些人也会把下面的I/O调度层并到通用块层里表述。这两层主要做两件事跟VFS的功能类似。向上为文件系统以及应用程序提供访问块设备的标准接口向下把各种异构的磁盘设备抽象为统一的块设备并提供统一框架来管理这些设备的驱动程序对I/O恳求进展调度通过重新排序、合并等方式进步磁盘读写效率下列图是一个完好的I/O栈全景图可以看到中间的BlockLayer其实就是GenericBlockLayer在图中可以看到BlockLayer的I/O调度分为两类分别表示单队列以及多队列的调度I/OschedulerblkmqI/O调度老版本的内核里只支持单队列的I/Oscheduler在3.16版本的内核开场支持多队列blkmq这里介绍几种经典的I/O调度策略。单队列I/OschedulerNOOP事实上是个FIFO的队列只做根本的恳求合并CFQCompletelyFairQueueing完全公平调度器给每个进程维护一个I/O调度队列按照时间片来均匀分布每个进程I/O恳求DeadLine为读以及写恳求创立不同的I/O队列确保到达deadline的恳求被优先处理多队列blkmqbfqBudgetFairQueueing也是公平调度器不过不是按时间片来分配而是按恳求的扇区数量带宽kyber维护两个队列同步/读、异步/写同时严格限制发到这两个队列的恳求数以保证相应时间mq-deadline多队列版本的deadline详细各种I/O调度策略可以参考关于blkmq可以参考多队列调度可以参考性能指标一般来讲I/O性能指标有这几个使用率ioutil指的是磁盘处理I/O的时间百分比ioutil只看有没有I/O恳求不看I/O恳求的大小。ioutil越高表示一直都有I/O恳求不代表磁盘无法响应新的I/O恳求IOPS每秒的I/O恳求数吞吐量/带宽每秒的I/O恳求大小通常是MB/s或GB/s为单位响应时间I/O恳求发出到收到响应的时间饱以及度指的是磁盘处理I/O的繁忙程度。这个指标比拟玄学没有直接的数据可以表示一般是根据平均队列恳求长度或响应时间跟基准测试的结果进展比照来估算在做基准测试时还会分顺序/随机、读/写进展排列组合分别去测IOPS以及带宽上面的指标除了饱以及度外其他都可以在监控系统中看到。Linux也提供了一些命令来输出不同维度的I/O状态iostat-d-x看各个设备的I/O状态数据来源/proc/diskstatspidstat-d看近处的I/Oiotop类似top按I/O大小对进程排序