Top
I/O 读写工具 --- FIO
FIO 下载地址
Github Download -- FIO
cgit/refs Download -- Fio
Kernel Download -- FIO
FIO 安装
./configure --enable-gfio
make fio
make gfio
make install
参数解析
文件系统类型:在测试文件系统性能时,可以选择不同的文件系统类型,如 ext4、xfs、btrfs 等。
文件大小:可以指定测试文件的大小,以便模拟不同大小文件的性能。
读写比例:可以调整读写比例,以模拟不同的工作负载。
数据块大小:可以指定数据块的大小,以便模拟不同大小的数据块操作。
操作类型:可以指定操作类型,如顺序读写、随机读写、混合读写等。
连续读写:可以指定连续读写操作的大小,以模拟不同的连续读写性能。
读写缓存:可以指定读写缓存的大小,以便调整读写缓存的影响。
并行度:可以指定并行度,以模拟不同的并发读写操作。
运行时间:可以指定测试运行时间,以评估长时间运行时的性能表现。
周期时间:可以指定周期时间,以便在测试过程中进行周期性操作。
预置操作:可以指定预置操作,以便在测试前进行预热操作。
延迟时间:可以指定延迟时间,以便在测试过程中引入延迟。
作业数:可以指定作业数,以模拟不同的作业数影响。
模式:可以指定模式,如同步模式、异步模式等。
持久化:可以指定持久化选项,以便将测试结果保存到文件中。
--bs=4k
--numjobs=16
--iodepth=64 ${PARA_LINE}
--runtime=300s
--filename=/dev/${DEV_LIST}
--name=${DEV_LIST}_${RW}_4k_16_64
--directory
--direct=1,
--ioengine=${IO_ENGINE}
--thread
--time_based
--group_reporting
-buffer_compress_percentage=0
-invalidate=1
--end_fsync=0
--norandommap=<0/1>
--randrepeat=<0/1>
-exitall
--size=${FILE_SIZE}
--offset_increment=100G
--loop
--ramp_time
--startdelay=int
与ramp_time的区别就是startdelay是job任务完全不运行,就是闲等,ramp_time是指job开始执行你指定的任务了,但是ramp_time时间内不会做记录
--output=txt,pdf,html
--output-format:
--rwmixwrite
--rwmixread
--lockmem
--hugepage-size=int
zero_buffers
nrfiles=8
nrfiles=8
-uid='int'
-gid='int'
--rate_iops=500
--rate=100m
percentile_list=1:5:10:25:50:75:90:95:99:99.5:99.9:99.99:99.999:99.9999:99.99999:99.999999
--verify=0
--bsrange=512-2048
--bssplit=4k/50:8k/20:16k/10:32k/20
若您希望工作负载具有50%的2k读取和50%的4k读取,同时具有90%的4k写入和10%的8k写,
比如: bssplit=2k/50:4k/50,4k/90:8k/10
--blocksize_range
-directory=
--bs=4k
--numjobs=2
--iodepth=32
-direct=1
--offset_increment=100G
-ioengine=libaio | psync
-thread
当 SSD 的 scheduler 为 mq-deadline 时, randread 的 IOPS 会高些
当 SSD 的 scheduler 为 none 时, randwrite 的 IOPS 会高些
--description=str
--bssplit
--bsrange
--lockmem
--zero_buffers
--nrfiles=int
--filesize=int
使用nrfiles和filesize这两个参数,可以使每个job(每个任务的每个线程或进程)生成指定数量特定大小的文件,这样对于后端是分布式的文件系统,模拟会更真实。(如果是通过size=int和filename=str两个参数,生成的会只有一个名为str,大小为size的文件)
注意此参数与bs参数的区别,bs是控制一次访问的块的大小的,而filesize是控制被访问的文件的大小的,例如bs=4K, fileszie=1M,fio则会以每次4K的请求大小来访问1M的文件
--create_only=bool
--unlink=bool
--showcmd=jobfile
--stonewall,wait_for_previous
这两个参数其实功能基本相同,只是使用的位置有所不同,stonewall一般放在一个job任务的末尾,wait_for_previous一般放在一个job任务的开头
--openfiles=int
--exec_postrun=str
--readonly
--max-jobs
--bandwidth-log
--client
--daemonize
--latency-log
--debug
--eta
测试模式配置
--readwrite=${RW}
1. 顺序读 -rw=read
2. 随机读 -rw=randread,
3. 顺序写 -rw=write
4. 随机写 -rw=randwrite
5. 混合随机读写模式 -rw=randrw
6. 顺序随机读写模式 --rw=rw
常用测试模型 6 要素配置
--bs=4k
--numjobs=2
--iodepth=32
-direct=1
-ioengine=libaio
-thread
绑核和内存相关配置
--cpumask=int
--cpus_allowed=0,5,8-15
--cpus_allowed_policy=split
--numa_cpu_nodes=0
--numa_mem_policy=str
测试日志输出配置
--log_avg_msec=1000
--iopsavgtime=1000
--bwavgtime=1000
--write_bw_log=str
--write_lat_log=str
--write_iops_log=str
--minimal
测试执行时间相关配置
--runtime=300s
--time_based
--ramp_time
--startdelay=int
与ramp_time的区别就是startdelay是job任务完全不运行,就是闲等,ramp_time是指job开始执行你指定的任务了,但是ramp_time时间内不会做记录
--loops=2
--size=${FILE_SIZE}
--offset_increment=100G
随机读、随机写 相关配置参数
Fio性能相关参数详解
结果分析
BW: 基于样本的带宽统计
IOPS :
lat
clat
slat
cpu
IO depths
util
自带图形化工具
yum install -y gnuplot
fio_generate_plots 接受的唯一参数就是这个日志文件名的prefix
单位换算
KB, MB, GB, TB 这几个单位是 10 进制,进位为 10^3 = 1000
例如:
KB = 10^3 = 1000
MB = 10^6 = 1000,000 = 1000 * 1000
GB = 10^9 = 1000,000,000 = 1000 * 1000 * 1000
TB = 10^12 = ...... 略
KiB, MiB, GiB, TiB 这几个单位是 2 进制,进位为 2^10 = 1024
例如:
KiB = 2^10 = 1024
MiB = 2^20 = 1048,576 = 1024 * 1024
GiB = 2^30 = 1073,741,824 = 1024 * 1024 * 1024
TiB = 2^40 = ......略
Mbit/s的意思是每秒中传输10^6 bit的数据,也写成 Mbps
MB/s的意思是每秒中传输10^6 byte的数据, 也写为 MBps, 等于 8 倍的 Mbps
MiB/s的意思是每秒中传输2^20 byte的数据
PS: 如果一个运营商声称自己的传输带宽是 1MBps, 若换算为 MiBps 的话,则等于 1 / 1.024 / 1.024 ~= 0.9537
PS: 如果一个硬盘厂商声称自己的盘的容量大小为 1TB, 若换算为 GiB 的话,则等于 1 * 1000 / 1.024 / 1.024 / 1.024 ~= 931.3 GiB
GiB = GB / 1.024 / 1.024 / 1.024 ~= GB / 0.9313
1GB = 0.9313225746 GiB
MB/s = MiB/s * 1.024 * 1.024 ~= MiB/s * 1.048
MB/s = Mbit/s * 8
Mbit/s = MiB/s * 1.024 * 1.024 * 8 ~= 8.389
系统下通过 nvme list 命令查看到盘的大小单位是: TB, GB,
而通过 lsblk 命令查看到的盘大小单位是: TiB, GiB
自定制绘图脚本
Fio 结合 SPDK 测试
1. 编译安装 Fio 和 SPDK (注意安装各个依赖包)
2. 执行SPDK 准备好的脚本: scripts/setup.sh , 进行配置 SPDK 环境
3. 开始执行 Fio 测试
LD_PRELOAD=/suosuo/spdk-home/spdk/build/fio/spdk_nvme /suosuo/spdk-home/fio/fio '--filename=trtype=PCIe traddr=0000.03.00.0 ns=1' --numa_cpu_nodes=0 --output=4K_8_256_randread.log spdk_nvme1.fio
[global]
ioengine=spdk
thread=1
group_reporting=1
direct=1
verify=0
time_based=1
ramp_time=0
[job]
rw=randread
bs=4k
numjobs=8
iodepth=256
runtime=300
相关命令
hdparm --user-master u --security-set-pass PASSWD /dev/sdx
hdparm --user-master u --security-erase PASSWD /dev/sdx
1. 关闭缓存
sdparm -s WCE=0 --save /dev/sd$i : 关闭SAS HDD 缓存
hdparm -W 0 /dev/sd$i : 关闭 SATA HDD 缓存
2. 修改算法
for i in {a..l};do echo mq-deadline > /sys/block/sd$i/queue/scheduler;done
3. 收集所有盘信息
4. 修改脚本,注意一下几点 :
threads = 2
iodepth : 32
--offset_increment=100G
5. 测试
nohup &>/dev/null bash run_parallel_hdd.sh &
sdparm -g WCE /dev/sda
hdparm -W 0 /dev/sd$i
lsscsi -g -s -k
lsblk -p
nvme list
结果格式化
awk '/IOPS/{split($2, iops_len, "=");split($4, bw_li, ")");split(bw_li[1], bw_li_li, "(");printf("%s,--- %s\n", bw_li_li[2], iops_len[2]); }' hdd_sda_read.log
awk '/IOPS/{
split($2, iops_li, "=")
split($4, bw_li, ")")
gsub(",", "", iops_li[2])
bw=substr(bw_li[1], 2)
printf("%s %s\n", iops_li[2], bw)
}' hdd_sda_read.log
awk '/IOPS/{split($2, iops_li, "=");split($4, bw_li, ")");gsub(",", "", iops_li[2]);bw=substr(bw_li[1], 2);printf("%-10s %-10s\n", iops_li[2], bw);}' hdd_sda_read.log
awk '/IOPS=/{split($2, iops_li, "=");split($4, bw_li, ")");gsub(",", "", iops_li[2]);bw=substr(bw_li[1], 2);end=match(bw, "kB/s|MB/s|GB/s", bws);bw_num=substr(bw, 1, end - 1);if (bws[0] == "kB/s"){bw_num/=1000;};if (bws[0] == "GB/s"){bw_num*=1000;};printf("%-10s %-10s\n", iops_li[2], bw_num"MB/s");}' hdd_sdm_randread.log
cat hdd_sda_read.log | grep pid= | awk '{print $1}' | sed 's/.$//g' | awk 'BEGIN{FS="_"}{printf("%-9s %-5s %-5s %-5s\n",$1,$2,$3,$4); }'
awk '/pid=/{ff=$1;gsub(":","",ff);split(ff,li,"_");printf("%-10s %-10s %-6s %-6s %-6s\n", li[1],li[2],li[3],li[4],li[5]);'} hdd_sda_read.log
for fff in `find ./hdd_fio_log_TOSHIBA_HDD_SATA_8T/*`; do echo $fff ; done
for fff in `find ./hdd_fio_log_TOSHIBA_HDD_SATA_8T/*`; do printf "%s\n" ${fff}; awk '/IOPS=/{split($2, iops_li, "=");split($4, bw_li, ")");gsub(",", "", iops_li[2]);bw=substr(bw_li[1], 2);end=match(bw, "kB/s|MB/s|GB/s", bws);bw_num=substr(bw, 1, end - 1);if (bws[0] == "kB/s"){bw_num/=1000;};if (bws[0] == "GB/s"){bw_num*=1000;};printf("%-10s %-10s\n", iops_li[2], bw_num"MB/s");}' $fff ; done
awk '/IOPS=|clat.*avg=/{if($0 ~ "IOPS=")ORS="";else ORS="\n"; print $0;}' hdd_sda_read.log
awk '/IOPS=|clat.*avg=/{
if($0 ~ "IOPS="){
ORS=""
split($2, iops_li, "=")
split($4, bw_li, ")")
gsub(",", "", iops_li[2])
bw=substr(bw_li[1], 2)
end=match(bw, "kB/s|MB/s|GB/s", bws)
bw_num=substr(bw, 1, end - 1)
if (bws[0] == "kB/s"){bw_num/=1000;}
if (bws[0] == "GB/s"){bw_num*=1000;}
printf("%-10s %-10s ", iops_li[2], bw_num"MB/s")}
else {
ORS="\n"
cunit=substr($2,2,4)
sub(",","",$5)
sub("avg=","",$5)
if (cunit == "usec"){$5/=1000}
printf("%-10s",$5)}
}' hdd_sda_read.log
==========================================
16.8k 68.0MB/s 3.79792
3734 245MB/s 17.14
946 248MB/s 67.62
253 266MB/s 126.23
242 254MB/s 263.88
awk '/IOPS=|clat.*avg=/{
if($0 ~ "IOPS="){
ORS=""
split($2, iops_li, "=")
split($4, bw_li, ")")
gsub(",", "", iops_li[2])
if(iops_li[2]~/k/){iops_li[2]*=1000}
bw=substr(bw_li[1], 2)
end=match(bw, "kB/s|MB/s|GB/s", bws)
bw_num=substr(bw, 1, end - 1)
if (bws[0] == "kB/s"){bw_num/=1000;}
if (bws[0] == "GB/s"){bw_num*=1000;}
printf("%-10s %-10s %4s ", iops_li[2], bw_num, "MB/s")}
else {
ORS="\n"
cunit=substr($2,2,4)
sub(",","",$5)
sub("avg=","",$5)
if (cunit == "msec"){$5*=1000}
if (cunit == "nsec"){$5/=1000}
printf("%-10s %4s\n",$5, "usec")}
}' $1
==========================================
205k 841 MB/s 37.2867 usec
82.0k 336 MB/s 10.816 usec
103k 843 MB/s 75.9789 usec
206k 842 MB/s 154.23 usec
207k 847 MB/s 4952.51 usec
206k 843 MB/s 620.07 usec
206k 846 MB/s 1238.31 usec
206k 845 MB/s 9926.19 usec
207k 846 MB/s 1237.85 usec
awk -F':' '/util=/{print $1}' hdd_sdd_randread.log | xargs
cat hdd_sdd_randwrite.log | grep rw= | sed '/rw=/s/.*rw=\(.*\), bs=.*/\1/g'
sed '/rw=/s/.*rw=\(.*\), bs=.*/\1/gp' -n ssd_nvme2n1_randread.log
awk -F'rw=' '/rw=/{split($2,li,",");print li[1];}' hdd_sdd_randread.log | xargs
awk -F'ioengine=' '/rw=/{split($2,li,",");print li[1];}' hdd_sdd_randread.log | xargs
awk -F'iodepth=' '/rw=/{split($2,li,",");print li[1];}' hdd_sdd_randread.log
awk -F'iodepth=' '/rw=/{printf("%s ",$2)}' hdd_sdd_randread.log | xargs
awk -F'jobs=' '/jobs=/{split($2, li, ")");printf("%s ",li[1])}' hdd_sdd_randread.log | xargs
awk -F'bs=' '/rw=/{split($2,li,"-");split(li[1],li02," ");if(li02[2] ~ "KiB"){gsub("KiB","",li02[2]);printf("%s ",int(li02[2]));}else{gsub("B","",li02[2]);bs=li02[2]/=1024;printf("%s ",bs);}}' hdd_sdd_randread.log | xargs
dmidecode -t bios | grep 'Version:' | sed '1p' -n | awk '{print $2}' | xargs
lscpu | awk '/^Model name:/{i=3;while (i<=NF) {print $i; i++} }' | xargs
lscpu | awk '/^Socket/{print $2}' | xargs
smartctl -i /dev/sda | awk '/^Firmware Version/{print $NF}' | xargs
smartctl -i /dev/sda | awk '/^Serial Number/{i=3;while (i<=NF) {print $i; i++}}' | xargs
lsblk -d -o 'SERIAL' /dev/sda | sed '$p' -n | xargs
smartctl -i /dev/sda | awk '/^Rotation Rate/{i=3;while (i<=NF) {print $i; i++}}' | xargs
smartctl -i /dev/sdb | awk '/^User Capacity|^Total NVM Capacity/{i=$(NF-1)$NF;gsub("\\[|\\]","",i);print i}' | xargs
smartctl -i /dev/sda | awk '/^Device Model|^Device Model/{i=3;while (i<=NF) {print $i; i++}}' | xargs
lsblk -d -o 'MODEL' /dev/sda | sed '$p' -n | xargs
smartctl -i /dev/sda | awk '/^Device Model|^Model Number|^Vendor/{if($0 ~ /Model/){print $3}else{print $2;}}' | xargs
cat /sys/block/sda/queue/scheduler | sed -e 's#.*\(\[.*\]\).*#\1#g' -e 's/^.//g' -e 's/.$//g'
lsblk -d -o 'SCHED' /dev/sda | sed '$p' -n | xargs
lspci | grep -i non-v | awk '{print $1}' | xargs -i lspci -vvv -s {} > nvme_AIC_lspci_info.log
storcli64 show | sed '/Ctl Model/,/Ctl=Controller/p' -n | sed -e '1,2d' -e '$d' -e '/^$/d' | sed '$d'
storcli64 show | sed '/Ctl Model/,/Ctl=Controller/p' -n | sed -e '1,2d' -e '$d' -e '/^$/d' | sed '$d' | head -1 | awk '{print $1}'
storcli64 /c0 show | sed '/EID:Slt/,$p' -n | sed '3p' -n | awk -F':' '{print $1}'
storcli64 /c0/e251/sall show | sed '/EID:Slt/,$p' -n | sed '/^-.*-$/,/^-.*-$/p' -n | sed -e '1d' -e '$d'
lspci | egrep -i 'raid.*broadcom|contro.*broadcom|contro.*storage'
smartpqi
aacraid
mpt3sas
megaraid_sas
arcconf list | sed '/Controller ID/,$p' -n | sed -e '/^$/d' -e '1,2d' -e '$d' | grep 'Controller'
arcconf list | sed '/Controller ID/,$p' -n | sed -e '/^$/d' -e '1,2d' -e '$d' | grep 'Controller' | awk '{print $2}' | cut -d':' -f1 | xargs
readlink -f /sys/block/nvme0n1 |cut -d '/' -f 6
iostat -xdm 1 3 > shi
https://blog.csdn.net/whatday/article/details/105184908
lsscsi -i | awk '{ii=1;while(ii<=NF){if(ii==(NF-1)){ii++;continue;};printf("%-20s",$ii); ii++; };print ""}'
lsblk -d -o 'HCTL,MODEL,SERIAL,SIZE,TYPE,VENDOR,MIN-IO'
lsblk -d -o 'HCTL,MODEL,SERIAL,SIZE,TYPE,VENDOR,MIN-IO,STATE'
lsblk -d -o 'HCTL,MODEL,SERIAL,SIZE,TYPE,VENDOR,MIN-IO,STATE' | sed -e '1d;/disk/p' -n | sort -t ':' -k 3 -n
lsscsi -i | awk '{ii=1;while(ii<=NF){if($ii ~ "^/dev/"){ii++;continue;};printf("%-20s",$ii); ii++; };print ""}'
lsscsi -i -N | awk '{ii=1;while(ii<=NF){if($ii ~ "^/dev/"){ii++;continue;};printf("%-20s",$ii); ii++; };print ""}'
cat dmesg_after | egrep 'scsi.*Direct-Access*'
cat err_env_2023.06.07.20.44.46/dmesg_after | egrep 'scsi.*Direct-Access*' | awk '{ii=6;while(ii<=NF){printf("%-s",$ii);ii++;}print ""}' > ff4
lsblk -d -l -n -o 'HCTL,MODEL,SERIAL,SIZE,TYPE,VENDOR,MIN-IO,STATE' | sed -e 's/INTEL //g' -e 's/^[0-9]*://gp' -n | sort -t ':' -k 2 -n | awk '{ii=1;while(ii<=NF){if(ii ~ /2|3/){printf("%-25s",$ii)}else{printf("%-12s",$ii);};ii++};print " "}'
lsblk -d -l -n -o 'HCTL,MODEL,SERIAL,SIZE,TYPE,VENDOR,MIN-IO,STATE' | sed -e 's/INTEL //g' -e 's/^[0-9]*://gp' -n | sort -t ':' -k 2 -n | xargs -n 8
storcli64 /c0/vall show | sed '/^DG\/VD/,/^VD=Virtual/p' -n | sed -e '/^$/d' -e '/Optl/p' -n | awk '{print $1}' | cut -d'/' -f2 | xargs
lspci -vvv -s 18:00.0 2> /dev/zero | egrep -i '[[:space:]]LnkCap:|[[:space:]]LnkSta:' | awk -F: '{print $2}' | sed 's/\t//gp' -n | awk -F',' '{ii=1;while(ii<=NF){if($ii ~ "Speed|Width")printf("%-16s",$ii);ii++}print " ";}'
lspci -vvv -s 18:00.0 2> /dev/zero | egrep -i '[[:space:]]LnkCap:|[[:space:]]LnkSta:' | awk -F: '{print $2}' | sed 's/[[:space:]]*//gp' -n | awk -F',' '{ii=1;while(ii<=NF){if($ii ~ "Speed|Width")printf("%-16s",$ii);ii++}print " ";}'
lshw -C network | awk 'BEGIN{RS="*-network[:0-9]*"; FS="\n"}{if ($0 ~ "logical name.*ens2np0\n"){printf $0"\n";}}'
cat lshw_info | awk 'BEGIN{RS="*-network[:0-9]*"; FS="\n"}{if ($0 ~ "logical name.*ens2np0\n"){printf $0"\n";}}' | egrep 'description|product|vendor|bus info|logical name|serial|width|capacity' | sed 's#^\s*##gp' -n
cat lshw_info | awk 'BEGIN{RS="*-network[:0-9]*"; FS="\n"}{if ($0 ~ "logical name.*ens2np0\n"){printf $0"\n";}}' | awk -F':' '/configuration/{print $2}' | awk '{ii=1;while(ii<=NF){print $ii;ii++}}' | egrep 'autone|driver|version|duplex|firm|link|port|multi'
cat lshw_info | awk -v ddd="ens2np0" 'BEGIN{RS="*-network[:0-9]*"; FS="\n"}{if ($0 ~ "logical name.*"ddd"\n"){printf $0"\n";}}' | awk -F':' '/configuration/{print $2}' | awk '{ii=1;while(ii<=NF){print $ii;ii++}}' | egrep 'autone|driver|version|duplex|firm|link|port|multi'
Fio 性能测试总结
1、请不要在系统盘或者数据盘上进行FIO测试,避免损坏系统文件或擦除数据
2、FIO测试硬盘性能时,推荐直接测试裸盘(如/dev/sdc);测试文件系统性能时,推荐指定具体文件测试比如(/mnt/data/file)
3、FIO测试时请注意磁盘尽量为空,磁盘在使用大部分容量的情况下,IO性能测试结果明显降低。
4、FIO测试时block = 128k iodepth=32 比较能反映磁盘IOPS性能,但不是很绝对。
5、阵列卡的电容是否存在以及状态是否正常直接影响阵列卡Cache是否能正常使用。
6、FIO测试建议使用官网兼容的系统。
7、FIO测试建议使用官网最新的固件与驱动。
8、FIO测试需要明确逻辑盘的Cache是否打开以及比例是否为10:90。
SCSI 子系统讲解
lsscsi
-s 显示容量大小。
-c 用全称显示默认的信息。
-d 显示设备主,次设备号。
-g 显示对应的sg设备名。
-H 显示主机控制器列表,-Hl,-Hlv。
-l 显示相关属性,-ll,-lll=-L。
-v 显示设备属性所在目录。
-x 以16进制显示lun号。
-p 输出DIF,DIX 保护类型。
-P 输出有效的保护模式信息。
-i 显示udev相关的属性-w 显示WWN
-t 显示相应传输信息(ATA,FC,SBP,ISCSI,SPI,SAS,SATA,USB),-Ht,-tl.(包括sas地址)<br><br>
列出SCSI设备(或主机)及它们的属性
第一列:SCSI设备id:host, channel,id,lun。
第二列:设备类型。
第3,4,5列:设备厂商,型号,版本信息。
最后一列:设备主节点名
从编号可以看出,第一级是host,第二级是channel,第三级是target编号,第四级是LUN号
h == hostadapter id (first one being 0)
c == SCSI channel on hostadapter (first one being 0)
t == ID
l == LUN (first one being 0)
一个主板可能接多个host,比如上面的服务器,在有多个sas芯片的情况下,肯定就有多个host。一个sas芯片又可以分割为多个通道,也就是channel,也叫bus。一个通道下多个target,一个target下多个lun。
如果一个硬盘支持双通道,那么在scsi层,就是展示为两个scsi标号。
注意channel编号和id编号是底层驱动自行管理的,而host编号(也就是前k)则是linux scsi子系统自行管理(参看static DEFINE_IDA(host_index_ida)(drivers/scsi/host.c))
引入target概念后,每个device内部可以看成被分为被多个target,每个target下面接着多个lun
lun是能够接收scsi命令的主体
echo "- - -" > /sys/class/scsi_host/host5/scan
hostX中"X"是是主机的序号, 如果/sys/class/scsi_host目录下有多个的话, 需要对每一目录都执行该操作
“- - -” 是通配符, 告诉SCSI总线需扫描所有的控制器、通道和;UN
echo “1” > /sys/class/block/sdX/device/rescan
sdX "X"是需要重新扫描的设备
“1” 是标志使SCSI重新扫描该设备,更新该设备的信息
echo "scsi remove-single-device 0 0 10 0 " > /proc/scsi/scsi
echo "scsi add-single-device 0 0 10 0 " > /proc/scsi/scsi
scsi_id –g –u –s /dev/sda
cat /sys/class/fc_host/host*/node_name
ls -l /dev/disk/by_id|grep -v part
先offlne
echo offline >/sys/block/device-name/device/state
然后remove
echo 1 >/sys/block/device-name/device/delete
主机识别存储设备标记主要有三个参数:
C — Controller
T — Target
D — Disk
主机识别存储上的设备就是依照这三个CTD的参数来识别的。
换言之, 如果CTD相同,并且磁盘的signature(label in unix/linux)信息也相同,主机就会认为是同一个LUN。
而CTD或是signature有任何一个参数发生变化, 操作系统就会认为是一个新的LUN。
SCSI(Small Computer System Interface)小型计算机系统接口
lun的全称是logical unit number,也就是逻辑单元号
HBA的全称为Host Bus Adapter,即主机总线适配器
SATA(Serial Advanced Technology Attachment)即(串行高级技术附件,一种基于行业标准的串行硬件驱动器接口)
SAS(Serial Attached SCSI),串行连接SCSI接口,串行连接小型计算机系统接口
FC(Fibre Channel)光纤通道。是一种跟SCSI 或IDE有很大不同的接
IDE(Integrated Drive Electronics)即“电子集成驱动器”,它的本意是指把“硬盘控制器”与“盘体”集成在一起的硬盘驱动器
SCSI 参考网址
https://blog.51cto.com/u_15080020/4221032
https://zhuanlan.zhihu.com/p/560321850
https://www.cnblogs.com/timlong/p/6096173.html
https://www.cnblogs.com/timlong/p/6096202.html
磁盘监控工具 --- iostat
其中,-c为汇报CPU的使用情况;-d为汇报磁盘的使用情况;-k表示每秒按kilobytes字节显示数据;-t为打印汇报的时间;-v表示打印出版本信息和用法;-x device指定要统计的设备名称,默认为所有的设备;interval指每次统计间隔的时间;count指按照这个时间间隔统计的次数。
[root@localhost small_fio]
Linux 4.19.90-2102.2.0.0062.ctl2.x86_64 (localhost.localdomain) 05/26/2023 _x86_64_ (64 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
0.38 0.00 1.37 0.00 0.00 98.25
Device tps kB_read/s kB_wrtn/s kB_dscd/s kB_read kB_wrtn kB_dscd
sda 0.46 3.76 2.55 0.00 275859 187497 0
sda1 0.01 0.09 0.00 0.00 6416 1 0
sda2 0.01 0.44 0.00 0.00 32653 32 0
sda3 0.45 3.19 2.55 0.00 234002 187464 0
硬盘SATA 1.0 的实际读写速率是150MB/s,带宽1.5Gb/s。
硬盘SATA 2.0的实际读写速率是300MB/s,带宽3Gb/s。
硬盘SATA 3.0的实际读写速率是600MB/s,带宽6Gb/s。
iostat 输出信息解析
rrqm/s:每秒这个设备相关的读取请求有多少被Merge了(当系统调用需要读取数据的时候,VFS将请求发到各个FS,如果FS发现不同的读取请求读取的是相同Block的数据,FS会将这个请求合并Merge);
wrqm/s:每秒这个设备相关的写入请求有多少被Merge了。
r/s: 该设备的每秒完成的读请求数(merge合并之后的)
w/s: 该设备的每秒完成的写请求数(merge合并之后的)
rsec/s:每秒读取的扇区数;
wsec/:每秒写入的扇区数。
rKB/s:每秒发送给该设备的总读请求数
wKB/s:每秒发送给该设备的总写请求数
avgrq-sz 平均请求扇区的大小
avgqu-sz 是平均请求队列的长度。毫无疑问,队列长度越短越好。
await: 每一个IO请求的处理的平均时间(单位是微秒毫秒)。这里可以理解为IO的响应时间,一般地系统IO响应时间应该低于5ms,如果大于10ms就比较大了。这个时间包括了队列时间和服务时间,也就是说,一般情况下,await大于svctm,它们的差值越小,则说明队列时间越短,反之差值越大,队列时间越长,说明系统出了问题。
svctm: 表示平均每次设备I/O操作的服务时间(以毫秒为单位)。如果svctm的值与await很接近,表示几乎没有I/O等待,磁盘性能很好,如果await的值远高于svctm的值,则表示I/O队列等待太长,系统上运行的应用程序将变慢。
%util: 在统计时间内所有处理IO时间,除以总共统计时间。例如,如果统计间隔1秒,该设备有0.8秒在处理IO,而0.2秒闲置,那么该设备的%util = 0.8/1 = 80%,所以该参数暗示了设备的繁忙程度。一般地,如果该参数是100%表示设备已经接近满负荷运行了(当然如果是多磁盘,即使%util是100%,因为磁盘的并发能力,所以磁盘使用未必就到了瓶颈)。
iostat 命令详解
磁盘监控工具 --- iotop
echo
性能调优
NVME
for i in {0..11};do nvme set-feature /dev/nvme${i}n1 -feature-id 0x08 -value 0x0109;done
echo 0 > /proc/sys/kernel/perf_cpu_time_max_percent
echo 10000 > /proc/sys/kernel/perf_event_max_sample_rate
FIO 调优网页参考
FIO 磁盘性能测试
FIO 配置文件压测
NUMA 配置详解
HDD -- 固件更新
通用方法 ---- hdparm
os_disk_symbol=$(echo $(lsblk |grep -B1 -E "part|boot" |grep -E "^sd[a-z]+|^nvme" |awk '{print $1}') |sed 's/ /|/')
hdds=`lsblk | grep disk | awk '{print $1}' | grep -v ${os_disk_symbol}`
fw_file="skybolt_512E_back_compatible_CCA8.txt"
for dddd in ${hdds}
do
echo "Starting FW Install Of: /dev/${dddd}"
hdparm --fwdownload ./7CV10111_7B1B0011_signed.bin --yes-i-know-what-i-am-doing --please-destroy-my-drive /dev/${dddd}
done
其他厂商工具
fw_file="V8GAW9G0.bin"
for dddd in `hugo s | awk '/Ready/{print $4}'`
do
echo "Starting FW Install Of: Serial: ${dddd}"
hugo update -f ${fw_file} -s ${dddd}
if [ $? -eq 0 ]; then
echo "Device fw install is Successful : ${dddd} --- ${fw_file}"
else
echo "Device fw install is Failed : ${dddd} --- ${fw_file}"
fi
done
fw_file="skybolt_512E_back_compatible_CCA8.txt"
for dddd in `lsblk | grep '1.7T' | awk '{print $1}'`
do
echo "Starting FW Install Of: /dev/${dddd}"
SeaChest_Lite_101_1183_64 --downloadFW ./${fw_file} -d ${dddd}
done
for dddd in ${nvmes}
do
echo "Starting FW Install Of: Serial: ${dddd}"
yes | umtool updatefw -d ${dddd} -f ${fw_file} -s 1 -a 1
if [ $? -eq 0 ]; then
echo "Device fw install is Successful : /dev/${dddd} --- ${fw_file}"
else
echo "Device fw install is Failed : /dev/${dddd} --- ${fw_file}"
fi
done
SAS/SATA 详解

NVME 工具详解 - - nvme

NVME Docu
ledctl locate=/dev/rsnvmeX
nvme id-ctrl /dev/nvme2 | grep -iE '^sn' | awk '{print $NF}'
nvme id-ctrl /dev/nvme2 | grep -iE '^mn' | awk '{print $NF}'
nvme id-ctrl /dev/nvme2 | grep -iE '^fr' | awk '{print $NF}'
nvme id-ctrl /dev/nvme6n1 | grep -E '^cntlid'
nvme get-ns-id /dev/nvme2n1 | cut -d':' -f3 | xargs
nvme list-ns /dev/nvme0
sh -c"echo 0 >/sys/block/nvmeX/device/delete"
nvme list --output-format=json | jq .Devices | jq '.[] | {name: ."DevicePath", lba: ."MaximumLBA"}' | grep "nvme3" -A 1 | grep lba | awk '{print $NF}'
nvme list
nvme smart-log <device>
nvme smart-log /dev/nvme3n1 | grep -E "temperature" | awk '{print $3}'
nvme error-log <device>
nvme get-log <device>
nvme fw-log <device>
nvme id-ctrl /dev/nvme0
nvme id-ns /dev/nvme0n1
nvme reset <device>
nvme get-feature -f 0x07 /dev/nvme0
nvme format <device> -s 0/1
nvme format <device> -n 1 -s 0/1
nvme fw-download /dev/nvme0n2 -f allBinary.bin
nvme fw-commit /dev/nvme0n2 -s 0 -a 1
nvme reset /dev/nvme0
[root@localhost tmp02]
get-feature:0x4 (Temperature Threshold), Current value:0x00015f
[root@localhost tmp02]
get-feature:0x7 (Number of Queues), Current value:0x7f007f
[root@localhost tmp02]
get-feature:0x8 (Interrupt Coalescing), Current value:00000000
[root@localhost tmp02]
get-feature:0xb (Async Event Configuration), Current value:0x000100
nvme id-ctrl /dev/nvme0n1 |grep tnvmcap
echo 1 > /sys/bus/pci/devices/${BDF}/remove
预留空间 -- OP

OP预留空间,英文名称Over-provisioning,是指固态硬盘内部存在的,由主控芯片控制的,用户不可操作的隐藏空间,这部分空间就是用于主控各种优化机制的操作,比如垃圾回收,磨损平衡、坏块管理等;
OP预留空间一共分为三层,第一层OP容量是由于单位换算问题产生的,标称容量是千进制的,即1GB=1000Mb,而NAND闪存颗粒是1024进制的,即1GiB=1024kib,其中相差的空间值就是第一层容量,此容量无法更改,也是固定不变的通行于所有品牌,这个差值约为固态硬盘标称容量的7%
第二层OP容量,则是取决于固态硬盘设计厂商以及主控厂商对于产品的定位了。
第三层OP容量,是用户可以自行选择自行设置的空间,其作用也同第二层OP空间一致
create-ns 使用提供的参数创建命名空间
delete-ns 从控制器中删除命名空间
attach-ns 将命名空间附加到请求的控制器上
detach-ns 从请求的控制器中删除命名空间
1. 将该盘的 namespace 与 控制器解绑
nvme detach -ns /dev/nvmeX(硬盘控制器)-n <命名空间ID> -c <控制器ID>
2. 删除该盘的 namespace
nvme delete-ns /dev/nvme1 –n 1
3. 设置该盘的 OP , 即重新创建该盘的 namespace
nvme create-ns /dev/nvme1 -s 15000000000 -c 15000000000 -f 0 -d 0 -m 0
-s
-c
-f
-d
-m
4. 将该盘的 namespace 与 控制器绑定
nvme attach-ns /dev/nvme1 -c 0 -n 1
5. 激活该盘
nvme reset /dev/nvme1
umtool capacity -d nvme6 -s 1000G
SSD --- 稳态配置(预写)
fio --readwrite=write --bs=128k --iodepth=128 --numjobs=4 --loop=2 -end_fsync=0 -group_reporting -direct=1 -ioengine=libaio -thread -buffer_compress_percentage=0 -invalidate=1 -norandommap -randrepeat=0 -exitall --name=nvme2n1_write_fragment1 --filename=/dev/nvme2n1
fio --readwrite=randwrite --bs=4k --iodepth=128 --numjobs=4 --loop=2 -end_fsync=0 -group_reporting -direct=1 -ioengine=libaio -thread -buffer_compress_percentage=0 -invalidate=1 -norandommap -randrepeat=0 -exitall --filename=/dev/nvme3n1 --name=nvme3n1_randwrite_fragment2
NVME --- LBA 配置
nvme id-ns /dev/nvme0n1 -n 1 -H | grep LBA
nvme format /dev/nvme0n1 -n 1 -l 3 -f

NVME 盘根据盘符查找 硬盘丝印

NVME 硬盘盘序信息获取流程图

Marvell 卡相关

Marvell RAID是一款使用M.2 NVMe SSD、支持有限级别且功能有限的存储控制器。也可以把它当成是一个转接卡来看待,只是这张转接卡不像 Retimer卡一样只实现转接的功能
不支持 Legacy Bios 配置
JBOD
RAID0
RAID1
Marvell 管理工具常用指令
mnv_cli info -o hba
mnv_cli info –o vd
mnv_cli info –o pd
mnv_cli ns --list
mnv_cli rebuild [-a <start|stop>] -i <vd_id> -d <pd_id>
mnv_cli mp [-a <start|stop >] -i <vd_id>
mnv_cli vd –a create –r <raid_level> -d <pd_id> [-b <128|256|512>]。
mnv_cli vd -a delete -i <vd_id>
./mnv_cli led -o rc -i 0/1 -a <on/off/sb/fb>
./mnv_cli log -a on/off
./mnv_cli log -a show/show --outputfile=log.txt
./mnv_cli event -c 0
./mnv_cli oemdata -s "SN" -m "Model Number"
nvme id-ctrl <Device>
./mnv_cli flash -o hba -f raw.bin -c 1 -s 1
./mnv_cli import -l <VD ID>
./mnv_cli led -o rc -i 0/1 -a <on/off/sb/fb>
mnv_cli attach –i <ns_id> -d <ctrl_id>
mnv_cli detach –i <ns_id> -d <ctrl_id>
Smartctl ------ 工具详解
"/dev/hd[a-t]"
"/dev/sd[a-z]"
选项及含义
选项 |
含义 |
-i |
打印基本信息 |
-a |
打印磁盘所有的SMART信息 |
-A |
显示磁盘支持的厂商指定SMART特性 |
-x |
|
-t |
自检 |
-s |
smartctl 功能开关 |
-H |
显示磁盘是否健康 |
--scan |
|
-d |
指定盘的类型 |
参考命令
smartctl --attributes --log=selftest --quietmode=errorsonly /dev/sda
smartctl --smart=on --offlineauto=on --saveauto=on /dev/sda
smartctl -i /dev/sda
smartctl -a /dev/sda
smartctl -A /dev/sda
smartctl -H /dev/nvme0n1
smartctl -l error /dev/nvme0n1
error 只显示error log。
selftest 只显示selftest log
selective 只显示selective self-test log
directory 只显示Log Directory
background
scttemp
smartctl --scan
smartctl --scan -d nvme
ata, scsi[+TYPE], nvme[,NSID], sat[,auto][,N][+TYPE], usbcypress[,X], usbjmicron[,p][,x][,N], usbprolific, usbsunplus, sntjmicron[,NSID], intelliprop,N[+TYPE], jmb39x,N[,sLBA][,force][+TYPE], marvell, areca,N/E, 3ware,N, hpt,L/M/N, megaraid,N, aacraid,H,L,ID, cciss,N, auto, test
网页参考
smartctl 输出详解
smartctl 命令解释
显示磁盘和分区信息 --- lsblk
选项及含义
选项 |
含义 |
-d |
只显示设备,不显示分区等 |
-p |
显示完整路径 |
-l |
以列表形式显示 |
-o |
以指定格式输出设备和分区信息 |
-n |
不打印表格标题 |
-x |
指定表格中指定列进行排序 |
-t |
以树形结构显示信息 |
-f |
显示文件系统类型 |
-e |
按照主要设备编号,排除指定类型设备,默认为 ram disk |
-s |
反向依赖输出,把树形结构倒过来 |
-S |
只打印有关 scsi 设备的信息 |
-r |
使用原始输出格式,非表格格式 |
-p |
打印有关权限的信息 |
-I(大写的 i) |
仅显示具有主要编号的设备 |
|
|
lsblk -pf
for f in `lsblk -n -d -o 'NAME,MODEL,SERIAL' | grep MZ7L3480 | awk '{print $1}'`; do printf "${f}";printf " `smartctl -a /dev/$f|grep Fir|cut -d':' -f2 | xargs`\n"; done
lsblk -o 'NAME,MODEL' | grep -i samsung | awk '{print $1}' | xargs -i smartctl -a /dev/{} | grep -i firmware
lsblk -d -o 'NAME,MODEL,SERIAL,SIZE'
lsblk -l -d -o 'NAME,MODEL,SERIAL,SIZE,HCTL,UUID,STATE,ROTA,SCHED,RQ-SIZE,WWN,VENDOR,REV' -x HCTL
NAME
MODEL
SERIAL
SIZE
HCTL
UUID
STATE
ROTA
SCHED
RQ-SIZE
WWN
VENDOR
REV
MAJ:MIN
MOUNTPOINT
FSTYPE
lsblk -d -o +rota
lsblk /dev/sda
lsblk -I 8
lsblk -o TRAN,NAME -d -n | awk '/^nvme /{print $2}' | xargs
lsblk -I 259 -d -n -o NAME
lsblk -e 11 -e 259 -d -n
lsblk -o ROTA,NAME -d -n | awk '{if($1 == "1"){print $2}}' | xargs
lsblk -d -I 8 -o NAME -n | xargs
lsblk -I 11
lsblk -s -I 253 -p -d -n -o NAME
lsblk -m
lsblk -P -p -o NAME,MOUNTPOINT | awk '/MOUNTPOINT="\/"$/{print $0}' | cut -d'"' -f2
lsblk -n -l -o MOUNTPOINTS,MAJ:MIN | awk '/^\/|\/boot/{print $2}' | xargs
lsblk /dev/nvme1n1 /dev/nvme2n1 /dev/nvme3n1 /dev/nvme4n1 /dev/sda
lsblk /dev/nvme1n1 /dev/nvme2n1 /dev/nvme3n1 /dev/nvme4n1 /dev/sda -p -l -n -x "NAME" | grep part | sed 'N;P' -n | awk '{print $1}' | xargs
Linux命令之lsblk命令
关于major、minor的解释
其他
sftp指定端口连接:
sftp -oPort=10022 HA@10.1.2.3:/HA
ftp方式连接:
ftp 10.1.2.3 21
zip带密码解压缩到指定目录:
unzip -P passwd123 -o aaa.zip -d /data/
linux 乱码后解码:
echo -e '\xf'
查看占用端口:
netstat -anp |grep 9200
查看主机硬件时间:
hwclock -r
查看cpu核数:
nproc (或 cat /proc/cpuinfo|grep processor|wc -l)
https://blog.csdn.net/qq_53169429/article/details/121296269
HGST(日立) 被 西数 收购了
Solidgm 被 SK Hynix(海力士) 收购了
U.2 也叫 SFF-8639
U.2 按照接口形态可区分为 B-key, M-key ;
在速率方面 B-key 支持 PCI * 2 ,而 M-key 支持 PCI * 4
参考网址
常用硬盘一览 之《协议、总线、接口》
PCIE2.0/PCIE3.0/PCIE4.0/PCIE5.0接口的带宽、速率计算
存储接口:SATA PCIE USB速率小结
图解 M.2、M.2(NVMe)
SATA、PCIe和M.2——主板上的各种插槽解析
sata协议传输速率(sata的数据传输速率)
相关技术文档
自动化脚本
性能测试脚本
Fio 数据自动解析脚本
Question &&& Solution
通过 DD 打 阵列卡驱动
8.3 OS安装过程中驱动更新方法
(1) 上述更新方法为常规OS下,如果在安装过程中无法识别阵列卡,需要先安装驱动,请按以下操作进行。
(2) 当前驱动文件夹中提供对应OS的dd.iso,将其挂载在KVM中。
(3) 开始OS引导,以RHEL7.6为例,进入选择菜单时,按e进入grub。
(4) 在linuxefi …行最后添加“linux dd”,按ctrl + x开始引导。
(5) 进入后会先选择驱动所在路径,选择挂载介质菜单选项,按空格选择,按c继续,根据提示继续操作,进入后即可安装OS。
或者用这个方法用dd包更新我放在100盘里的驱动试试
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 推荐几款开源且免费的 .NET MAUI 组件库
· 实操Deepseek接入个人知识库
· 易语言 —— 开山篇
· 【全网最全教程】使用最强DeepSeekR1+联网的火山引擎,没有生成长度限制,DeepSeek本体
2019-11-13 变量管理 dotenv 的 使用