当前位置: 首页 > 科技观察

如何使用dd检查存储性能

时间:2023-03-21 18:20:45 科技观察

本文包含一些示例命令,向您展示如何使用dd命令粗略估计硬盘驱动器和RAID阵列的性能。准确的测量必须考虑写入放大和系统调用开销等因素,本指南不会考虑这些因素。对于可能提供更准确结果的工具,您可能需要考虑hdparm。为了解决与文件系统相关的性能问题,这些示例展示了如何通过直接读取和写入块设备来测试块级别的驱动器和阵列的性能。警告:编写测试将破坏用于运行测试的块设备上的所有数据。不要在任何包含您要保留的数据的设备上运行这些测试!四个测试以下是可用于测试块设备性能的四个示例dd命令:1.从$MY_DISK读取的进程:#ddif=$MY_DISKof=/dev/nullbs=1MiBcount=200iflag=nocache2,one写入$MY_DISK的进程:#ddif=/dev/zeroof=$MY_DISKbs=1MiBcount=200oflag=direct3,两个进程同时从$MY_DISK读取:#(ddif=$MY_DISKof=/dev/nullbs=1MiB计数=200iflag=nocache&);(ddif=$MY_DISKof=/dev/nullbs=1MiBcount=200iflag=nocacheskip=200&)4.并发写入两个进程到$MY_DISK:#(ddif=/dev/zeroof=$MY_DISKbs=1MiBcount=200oflag=direct&);(ddif=/dev/zeroof=$MY_DISKbs=1MiBcount=200oflag=directskip=200&)在进行读写测试时,对应的iflag=nocache和oflag=direct参数很重要,因为没有它们,dd命令有时会显示从内存而不是硬盘传输数据的结果速度。bs和count参数的值有些随意,我选择的值足够大,可以在大多数情况下为当前硬件提供不错的平均值。空设备和零设备分别用于读取和写入测试中的目标和源,因为它们足够快,不会成为性能测试中的限制因素。并发读写测试中第二个dd命令的skip=200参数是为了保证dd的两个副本运行在硬盘的不同区域。16示例下面是一个演示,显示了针对以下四个块设备之一运行上述四个测试中的每一个的结果:MY_DISK=/dev/sda2(用于示例1-X)MY_DISK=/dev/sdb2(用于Example2-X)MY_DISK=/dev/md/stripped(用在Example3-X)MY_DISK=/dev/md/mirrored(用在Example4-X)首先把电脑置于rescue模式以减少disk的可能性来自后台服务的I/O随机影响测试结果。警告:这将关闭所有非必要的程序和服务。请务必在运行这些命令之前保存您的工作。您需要知道root密码才能进入救援模式。当以root身份运行时,passwd命令将提示您(重新)设置root帐户密码。$sudo-i#passwd#setenforce0#systemctlrescue您可能还想暂时禁用日志记录到磁盘:#sed-r-i.bak's/^#?Storage=.*/Storage=none/'/etc/systemd/journald.conf#systemctlrestartsystemd-journald.service如果你有交换工具,你可以暂时禁用它并在以后的测试中使用它:#swapoff-a#MY_DEVS=$(mdadm--detail/dev/md/swap|grepactive|grep-o"/dev/sd.*")#mdadm--stop/dev/md/swap#mdadm--zero-superblock$MY_DEVS示例1-1(从sda读取)#MY_DISK=$(echo$MY_DEVS|cut-d''-f1)#ddif=$MY_DISKof=/dev/nullbs=1MiBcount=200iflag=nocache200+0记录in200+0记录out209715200字节(210MB,200MiB)已复制,1.7003秒,123MB/s示例1-2(写入sda)#MY_DISK=$(echo$MY_DEVS|cut-d''-f1)#ddif=/dev/zeroof=$MY_DISKbs=1MiBcount=200oflag=direct200+0recordsin200+0recordsout209715200bytes(210MB,200MiB)copied,1.67117s,125MB/sex??ample1-3(concurrentreadfromsda)#MY_DISK=$(echo$MY_DEVS|剪切-d''-f1)#(ddif=$MY_DISKof=/dev/nullbs=1MiBcount=200iflag=nocache&);(ddif=$MY_DISKof=/dev/nullbs=1MiBcount=200iflag=nocacheskip=200&)200+0recordsin200+0recordsout209715200bytes(210MB,200MiB)copied,3.42875s,61.2MB/s200+0recordsin200+0recordsout209715200bytes(210MB,200MiB)复制,3.52614s,59.5MB/s示例1-4(并发写入到sda)#MY_DISK=$(echo$MY_DEVS|cut-d''-f1)#(ddif=/dev/zeroof=$MY_DISKbs=1MiBcount=200oflag=direct&);(ddif=/dev/zeroof=$MY_DISKbs=1MiBcount=200oflag=directskip=200&)200+0记录out209715200bytes(210MB,200MiB)copied,3.2435s,64.7MB/s200+0recordsin200+0recordsout209715200bytes(210MB,200MiB)copied,3.60872s,58.1MB/s示例2-1(从sdb读取)#MY_DISK=$(echo$MY_DEVS|cut-d''-f2)#ddif=$MY_DISKof=/dev/nullbs=1MiBcount=200iflag=nocache200+0recordsin200+0recordsout209715200bytes(210MB,200MiB)copied,1.67285s,125MB/s示例2-2(写入sdb)#MY_DISK=$(echo$MY_DEVS|cut-d''-f2)#ddif=/dev/zeroof=$MY_DISKbs=1MiBcount=200oflag=direct200+0recordsin200+0recordsout209715200bytes(210MB,200MiB)复制,1.67198s,125MB/s示例2-3(从sdb并发读取)#MY_DISK=$(echo$MY_DEVS|cut-d''-f2)#(ddif=$MY_DISKof=/dev/nullbs=1MiBcount=200iflag=nocache&);(ddif=$MY_DISKof=/dev/nullbs=1MiBcount=200iflag=nocacheskip=200&)200+0recordsin200+0recordsout209715200bytes(210MB,200MiB)copied,3.52808s,59.4MB/s200+0recordsin200+0recordsout209715200bytes(210MB,200MiB7,33.s)5copyed,58.6MB/s示例2-4(并发写入sdb)#MY_DISK=$(echo$MY_DEVS|cut-d''-f2)#(ddif=/dev/zeroof=$MY_DISKbs=1MiBcount=200oflag=direct&);(ddif=/dev/zeroof=$MY_DISKbs=1MiBcount=200oflag=directskip=200&)200+0recordsin200+0recordsout209715200bytes(210MB,200MiB)copied,3.7841s,55.4MB/s200+0recordsin200+0recordsout209715200bytes(210MB,200MiB)copied,3.81475s,55.0MB/sExample3-1(readfromRAID0)#mdadm--create/dev/md/stripped--homehost=任何--元data=1.0--level=0--raid-devices=2$MY_DEVS#MY_DISK=/dev/md/stripped#ddif=$MY_DISKof=/dev/nullbs=1MiBcount=200iflag=nocache200+0记录in200+0recordsout209715200bytes(210MB,200MiB)copied,0.837419s,250MB/s示例3-2(写入到RAID0)#MY_DISK=/dev/md/stripped#ddif=/dev/zeroof=$MY_DISKbs=1MiBcount=200oflag=direct200+0recordsin200+0recordsout209715200bytes(210MB,200MiB)copyed,0.823648s,255MB/s示例3-3(从RAID0并发读取)#MY_DISK=/dev/md/stripped#(ddif=$MY_DISKof=/dev/nullbs=1MiBcount=200iflag=nocache&);(ddif=$MY_DISKof=/dev/nullbs=1MiBcount=200iflag=nocacheskip=200&)200+0recordsin200+0recordsout209715200bytes(210MB,200MiB)copied,1.31025s,160MB/s200+0recordsin200+0recordsout209715200bytes(210MB,200MiB)copied,1.80016s,116MB/s示例3-4(并发写入到RAID0)#MY_DISK=/dev/md/stripped#(ddif=/dev/zeroof=$MY_DISKbs=1MiBcount=200oflag=direct&);(ddif=/dev/zeroof=$MY_DISKbs=1MiBcount=200oflag=directskip=200&)200+0recordsin200+0recordsout209715200bytes(210MB,200MiB)复制,1.65026s,127MB/s200+0recordsin200+0recordsout209715200bytes(210MB,210MB,200MiB)copied,1.81323s,116MB/s示例4-1(从RAID1读取)#mdadm--stop/dev/md/stripped#mdadm--create/dev/md/mirrored--homehost=any--metadata=1.0--level=1--raid-devices=2--assume-clean$MY_DEVS#MY_DISK=/dev/md/mirrored#ddif=$MY_DISKof=/dev/nullbs=1MiBcount=200iflag=nocache200+0recordsin200+0recordsout209715200bytes(210MB,200MiB)copied,1.74963s,120MB/s示例4-2(写入到RAID1)#MY_DISK=/dev/md/mirrored#ddif=/dev/zeroof=$MY_DISKbs=1MiBcount=200oflag=direct200+0recordsin200+0recordsout209715200bytes(210MB,200MiB)copied,1.74625s,120MB/s示例4-3(从RAID1并发读取)#MY_DISK=/dev/md/mirrored#(ddif=$MY_DISKof=/dev/nullbs=1MiBcount=200iflag=nocache&);(ddif=$MY_DISKof=/dev/nullbs=1MiBcount=200iflag=nocacheskip=200&)200+0条记录,200+0条记录,复制209715200字节(210MB,200MiB),1.67171秒,125MB/s200+0条记录,200+0条记录,复制209715200字节(210MB,200MiB),5.125MB/s示例4-4(并发写入RAID1)#MY_DISK=/dev/md/mirrored#(ddif=/dev/zeroof=$MY_DISKbs=1MiBcount=200oflag=direct&);(ddif=/dev/zeroof=$MY_DISKbs=1MiBcount=200oflag=directskip=200&)200+0recordsin200+0recordsout209715200bytes(210MB,200MiB)copied,4.09666s,51.2MB/s200+0recordsin200+0recordsout209715200bytes(210MB,200MiB)copyed,4.1067s,51.1MB/s恢复交换设备和日志配置#mdadm--stop/dev/md/stripped/dev/md/mirrored#mdadm--create/dev/md/swap--homehost=any--metadata=1.0--level=1--raid-devices=2$MY_DEVS#mkswap/dev/md/swap#swapon-a#mv/etc/systemd/journald.conf.bak/etc/systemd/journald.conf#systemctlrestartsystemd-journald.service#reboot结果解释示例1-1、1-2、2-1和2-2显示我的每个驱动器以大约125MB/s的读写速度开始示例1-3、1-4、2-3和2-4表明,当在同一驱动器上并行执行两个读取或写入操作时,每个进程具有大约一半的驱动器带宽(60MB/s)。3-X示例显示了将两个驱动器放置在RAID0(数据条带化)阵列中的性能优势。在所有情况下,这些数字都表明RAID0阵列的执行速度是任何一个驱动器自身所能提供的速度的两倍。相应地,您丢失所有内容的可能性是原来的两倍,因为每个驱动器只包含一半数据。三驱动器阵列的执行速度是单个驱动器(所有相同大小的驱动器)的三倍,但发生灾难性故障的可能性也高出三倍。4-X示例表明,RAID1(数据镜像)阵列的性能与单个磁盘的性能相似,但多个进程同时读取的情况除外(示例4-3)。在多进程读的情况下,RAID1阵列的性能与RAID0阵列相似。这意味着您将看到RAID1的性能优势,但仅限于进程并发读取时。例如,当您在前台使用Web浏览器或电子邮件客户端时,该进程会尝试在后台访问大量文件。RAID1的主要好处是,如果驱动器出现故障,您的数据不太可能丢失。故障排除如果上述测试未按预期执行,则驱动器可能损坏或出现故障。大多数现代硬盘驱动器都内置了自我监控、分析和报告技术(SMART)。如果您的驱动器支持它,可以使用smartctl命令查询硬盘驱动器的内部统计信息:#smartctl--health/dev/sda#smartctl--log=error/dev/sda#smartctl-x/dev/sdaelse调整PC以获得更好性能的一种方法是更改??I/O调度程序。Linux系统支持多个I/O调度器,而Fedora系统当前的默认设置是deadline调度器的多队列变体。默认情况下,它总体上表现非常好,并且对于具有许多处理器和大型磁盘阵列的大型服务器来说,它的扩展性非常好。但是,有更多专门的调度程序可以在某些条件下执行得更好。要查看驱动器正在使用哪个I/O调度程序,请运行以下命令:$foriin/sys/block/sd?/queue/scheduler;做echo"$i:$(<$i)";done您可以通过将所需调度程序的名称写入/sys/block//queue/scheduler文件来更改驱动器的调度程序:#echobfq>/sys/block/sda/queue/scheduler创建一个udev规则永久更改此设置。以下示例显示如何创建一个udev规则,将所有旋转驱动器设置为使用BFQI/O调度程序:#cat</etc/udev/rules.d/60-ioscheduler-rotational.rulesACTION==”add|change",KERNEL=="sd[a-z]",ATTR{queue/rotational}=="1",ATTR{queue/scheduler}="bfq"END这是所有固态硬盘使用NOOPI的另一个设置/O调度程序示例:#cat</etc/udev/rules.d/60-ioscheduler-solid-state.rulesACTION=="add|change",KERNEL="sd[a-z]",ATTR{queue/rotational}=="0",ATTR{queue/scheduler}="none"END更改I/O调度程序不会影响设备的原始吞吐量,但通过为后台任务确定带宽优先级或消除不必要的块重新排序可能会使您的PC似乎更灵敏。