版权所有,尊重他人劳动成果,转载时请注明作者和原始出处及本声明。
原文名称:《Linux Performance and Tuning Guidelines》
原文地址:http://www.redbooks.ibm.com/abstracts/redp4285.html
-------------------------------------------------------------------------------------------
1.4.1 I/O子系统架构1.4.2 缓存
1.4.3 块层
1.4.4 I/O设备驱动
1.4.5 RAID及存储系统
-------------------------------------------------------------------------------------------
在处理器解码和执行指令前,先从扇区中读取数据并将数据置于处理器的缓存和寄存器中。执行结果会被写回硬盘。
下面我们将简单地介绍一下Linux硬盘I/O子系统,来更好的认识这个可以对系统性能产生很大影响的组件。
1.4.1 I/O子系统架构
图1-18展示了I/O子系统架构的基本概念。
图1-18 I/O子系统架构
为了能快速的对I/O子系统运作有一个整体的认识,我们将举一个写数据到硬盘的例子。
下面的步骤概述了当一个硬盘写操作执行时的基本操作。
假设存储于硬盘片扇区上的数据已经被读取到分页缓存中。
1.进程使用write()系统调用发出写文件的请求。
2.内核更新映射此文件的分页缓存。
3.pdflush内核线程将分页缓存清空至硬盘。
4.文件系统层将多个块缓冲【block buffer】置于bio结构中(参见1.4.3,“块层”)并提交一个写请求给块设备层。
5.块设备层从上一层收到请求,执行一个I/O elevator操作并发出进入I/O请求队列的请求。
6.设备驱动如SCSI或其它设备的特定驱动来负责完成写操作。
7.硬盘设备韧体负责执行硬件操作像确定磁头、旋转和传输数据至磁盘片上的扇区。
1.4.2 缓存
在过去的20年里,处理器性能的提升已超过计算机中其它元件如处理器缓存、总线、RAM、硬盘等。
内存和硬盘较慢的访问速度限制了系统的整体性能,所以单单提高处理器速度并不能让系统性能提升。
缓存机制通过将常用数据缓存至快速内存中来解决此问题。它减少了访问较慢内存的机会。
目前计算机系统中几乎所有的I/O元件都是用了这项技术如硬盘驱动器缓存、硬盘控制器缓存、文件系统缓存、各种应用程序的缓存等等。
内存层级【Memory Hierarchy】
图1-19展示了内存层级的概念。
CPU寄存器和硬盘在访问速度上有着很大的差距,CPU需要花费更多的时间等待从缓慢硬盘上获取数据,这显然降低了一个快速CPU所带了的好处。
内存层级结构通过在CPU和硬盘间部署一级缓存、二级缓存、RAM和其他一些缓存可以减少这种速度上的失衡。
它能减少处理器访问较慢内存和硬盘的机会。靠近处理器的内存拥有更快的访问速度但容量却较小。
这种技术也可以利用局部性引用原则。快速内存中更高的缓存命中率就意味着更高的数据访问速度。
图1-19 内存层级
局部性引用【Locality of Reference】
正如我们前面在“内存层级”中所述,取得更高的缓存命中率是性能提升的关键。
为取得更高的缓存命中率,“局部性引用”技术被使用。这项技术是基于下面的原则:
▶ 最近使用过的数据非常有可能在近期被再次使用(时间局部性)
▶ 位于使用过数据相邻的数据非常有可能被使用(空间局部性)
图1-20说明了这个原则。
图1-20局部性引用
这个原则被应用于Linux的许多元件中如分页缓存、文件对象缓存(i-node缓存、目录项缓存等)、预读缓冲以及更多。
清空脏缓冲【Flushing a dirty buffer】
当进程从硬盘中读取数据时,数据被复制到内存。
此进程和其他进程都可以从缓存在内存中的副本取得相同数据。当有进程尝试变更数据,会先更改内存中数据。
此时,硬盘中数据和内存中数据发生不一致,内存中数据被称为脏缓冲。
赃缓冲会被尽快同步至硬盘,但如果系统突然崩溃内存中数据就会丢失。
同步脏数据的进程叫做flush。
在Linux2.6内核中,pdflush内核线程负责清空数据到硬盘。
此操作会定期(kupdate)执行或者当内存中脏缓冲比例超过临界值(bdflush)时执行。
此临界值配置在/proc/sys/vm/dirty_background_ratio文件中。
更多信息参见4.5.1“设置内核交换和pdflush行为”。
图1-21清空脏数据
1.4.3 块层
块层负责管理所有关于块设备操作的相关活动(参见图1-18)。
块层中的关键数据结构就是bio,bio结构是位于文件系统层和块层之间的一个接口。
当执行写操作时,文件系统层尝试向由块缓冲组成的分页缓存中写入。
将连续的块组成一个bio结构,然后将bio传送至块层。(参见图1-18)
块层获得bio请求并将其链接至I/O请求队列(I/O Request Queue)中。
这个链接操作叫做I/O调度器【原文中使用的单词为elevator】。
在Linux 2.6内核中,共有四种I/O调度器算法可以选择,他们是:
块的大小【Block Sizes】
块大小(读写硬盘数据的最小数量)能直接影响服务器的性能。
一个指导性方案是,如果你的服务器处理非常多的小文件,较小的块大小会更有效率。
如果你的服务器用于处理大文件,较大的块大小可以提升性能。
已有的文件系统是不能更改块大小的,只有在重新格式化时才能修改当前块大小。
I/O调度器
Linux 2.6内核的I/O调度器使用了新模式,而Linux 2.4内核中采用的是一种简单、通用的I/O调度器,而在2.6内核中有四种调度器可供选择。
因为Linux被用来执行各种各样的任务,对I/O设备和负载要求有显著的不同,一台笔记本电脑和一台有10000个用户的数据库对I/O的需求就有很大差别。
为满足这样的需求,Linux提供了四种I/O调度器。
▶ Anticipatory
Anticipatory I/O 调度器是基于假设块设备只有一个物理寻址磁头(例如一个单SATA驱动)。
Anticipatory 调度器使用了增加预测启发能力的Deadline机制(下面会详细介绍)。
正像名字所暗示的,Anticipatory I/O Anticipatory会“猜测”I/O并尝试使用单一较大的数据流写入硬盘代替多个小的随机硬盘访问。
这种预测启发能力会造成写入的延迟,但它可以提高一般用途系统如个人电脑的写入吞吐量。
在2.6.18内核中Anticipatory 调度器被作为标准的I/O调度器,然而大多数企业发行版默认使用CFQ 调度器。
▶ 完全公平队列(CFQ)
CFQ elevator通过为每个进程都维护单独的I/O队列来实现QoS(服务质量)策略。
CFQ调度器也适用于拥有许多互相竞争进程的多用户系统。它可以避免进程饿死并降低延迟。
自从2.6.18内核,CFQ调度器已被作为默认的I/O调度器。
依据系统设置和负载情况,CFQ调度器可以降低单一主应用程序的速度,例如使用其公平向导算法的大型数据库 。
默认配置进程组确保公平,进程组与其它进程竞争。
例如数据库所有写分页缓存(所有pdflush实例为一个群组)的操作被认为是一个应用程序与其它后台进程竞争。
在这样的情况下它对于测试I/O调度器配置或Deadline调度器也是非常有用的。
▶ Deadline
Deadline是个使用最后期限算法的轮询调度器(Round Robin),它提供I/O子系统接近实时的操作。
Deadline在维持满意的硬盘吞吐量的同时可以提供优秀的请求延迟。Deadline的算法能确保不会有进程被饿死。
▶ NOOP
NOOP代表不操作【No Operation】,名字就说明了其主要功能。
NOOP简单且直接,它只实现一个简单的FIFO队列并不对任何数据排序。
NOOP只是简单地合并数据请求,因此它增加非常低的处理器负载。
NOOP假设块设备拥有自己的调度器算法如SCSI的TCQ或没有寻道的延迟的块设备如闪存卡。
注释:在2.6.18内核中可以为每个硬盘子系统设定特定的I/O调度器,不需要在系统级上设定。
1.4.4 I/O设备驱动
Linux内核使用设备的驱动程序来控制设备。设备的驱动程序通常为独立的内核模组,它让操作系统中的每个设备都可以使用。
当设备驱动被加载后,它就作为内核的一部分运行并完全控制设备。
这里我们将介绍一下SCSI设备驱动。
SCSI
小型计算机系统接口(SCSI)是一种最常用的I/O设备技术,特别是在企业服务器环境中。
在Linux内核的实现中,SCSI设备由设备驱动模组控制。它们由下面几种模组构成。
▶ 上层驱动:sd_mod,sr_mod(SCSI-CDROM),st(SCSI Tape),sq(SCSI generic device)等。
提供支持几种SCSI设备的功能如SCSI-CDROM,SCSI磁带等。
▶ 中间层驱动:scsi_mod
实现SCSI协议和SCSI共有的功能。
▶ 底层驱动
提供设备的底层访问。底层驱动为每个设备提供特定的硬件驱动。
例如用于IBM ServeRAID控制器的ips、用于Qlogic HBA的qla2300、用于LSI Logic SCSI控制器的mptscsih等。
▶ 伪驱动:ide-scsi
用于模拟IDE-SCSI。
图1-22 SCSI驱动结构
如果要设备实现特殊的功能,它需要在设备韧体和底层设备驱动中实现。
支持什么功能取决于你使用什么设备和设备驱动的版本。设备自己也可以支持所希望的功能。
通过设定设备驱动参数可以调整特定的功能。你可以调整/etc/modules.conf测试某些性能。关于使用方法和技巧请参见设备和驱动相关文档。
1.4.5 RAID和存储系统
就系统效能而言存储系统的选择配置与RAID类型也是重要因素。
Linux支持软RAID,但此主题的详细内容已超出本文范畴,我将在4.6.1“安装Linux前硬件的选择”中介绍一些调优相关的内容。