当前位置: 首页 > news >正文

Linux下Python脚本的编写解析fio(minimal格式)(三)

在服务器测试(storage)过程中,会看到很多人写跑fio的脚本用minimal格式来解析,因为这种格式返回的结果对与脚本(shell,python)解析log非常方便.下面介绍一下这种方式下,用Python来解析log
1 一般客户会要求结果中出现一下参数的值:
bandwidth
iops
clat_p99
clat_p999
clat_p9999
lat_max
lat_avg
那么就要知道这些参数的下标:

7  read_bandwidth_kb   带宽值8  read_iops                     IOPS值
30  read_clat_pct13    p99的值
32  read_clat_pct15  p999的值
34  read_clat_pct17   p9999的值
39  read_lat_max_us       lat  max值
40  read_lat_mean_us    lat平均值48  write_bandwidth_kb   带宽值
49  write_iops                     IOPS值
71  write_clat_pct13      p99值
73  write_clat_pct15      p999的值
75  write_clat_pct17       p9999的值
80  write_lat_max_us     lat最大值
81  write_lat_mean_us   lat平均值

2 先写一个跑fio的脚本,以HDD为例子吧

#!/bin/bash
if [ $# != 2 ]; thenecho "You must input  the time of each testcase (unit is second)"exit -1
fi
hdd=$1
time=$2
date
echo " sequential random  write  test start"
for ioengine in libaio sync
do
for rw  in   write  randwrite
dofor bs in 128k  
dofor iodepth in 16 
dofor jobs in 1  
do	    date  echo "$hdd $rw $bs iodepth=$iodepth numjobs=$jobs  test satrt"job_name="${ioengine}_${bs}B_${rw}_${jobs}job_${iodepth}QD"fio  --name=$job_name  --filename=/dev/$hdd --ioengine=${ioengine} --direct=1 --thread=1 --numjobs=${jobs} --iodepth=${iodepth} --rw=${rw} --bs=${bs} --runtime=$time --time_based=1  --size=100% --group_reporting  --minimal  >>${hdd}_write.log        
done        
done
done
done
done
echo " sequential  randrom read  test start"
for ioengine in libaio sync
do
for rw  in   read  randread
dofor bs in 128k  
dofor iodepth in 16 
dofor jobs in 1  
do	    date  echo "$hdd $rw $bs iodepth=$iodepth numjobs=$jobs  test satrt"job_name="${ioengine}_${bs}B_${rw}_${jobs}job_${iodepth}QD"fio  --name=$job_name  --filename=/dev/$hdd --ioengine=${ioengine} --direct=1 --thread=1 --numjobs=${jobs} --iodepth=${iodepth} --rw=${rw} --bs=${bs} --runtime=$time --time_based=1  --size=100% --group_reporting  --minimal  >>${hdd}_read.log        
done        
done
done
done
done
echo " sequential randmon  mix  test"
date
for ioengine in libaio sync
do
for rw in rw randrw
do
for mixread in 80  
do
for blk_size in 1024k  
do
for jobs in 1 
do
for queue_depth in  16 
do      job_name="${ioengine}_${rw}_${blk_size}B_mix_read${mixread}_${jobs}job_QD${queue_depth}"echo "$hdd $job_name  test satrt"fio --name=${job_name} --filename=/dev/$hdd --ioengine=libaio --direct=1 --thread=1 --numjobs=${jobs} --iodepth=${queue_depth} --rw=${rw} --bs=${blk_size} --rwmixread=$mixread --runtime=$time --time_based=1 --size=100% --group_reporting  --minimal >> "$hdd"_mix_data.log
done
done
done
done
done
done
mkdir $hdd
mkdir $hdd/test_data
mkdir $hdd/test_log
mv $hdd*.log   $hdd/test_log
mv $hdd*.csv    $hdd/test_data
echo "test has been finsished"

执行一下这脚本如下:
bash hdd-single-fio.sh sdb 1
以混合mix的log为例,先看下这个log

[root@dhcp-10-131-201-78 test_log]# cat sdb_mix_data.log
3;fio-3.19;libaio_rw_1024kB_mix_read80_1job_QD16;0;0;221184;141512;138;1563;8;215;20.126759;15.524727;7460;70547;30223.547625;18514.367104;1.000000%=7766;5.000000%=7766;10.000000%=11468;20.000000%=15138;30.000000%=15663;40.000000%=19005;50.000000%=23199;60.000000%=29491;70.000000%=39583;80.000000%=50069;90.000000%=60555;95.000000%=67633;99.000000%=70778;99.500000%=70778;99.900000%=70778;99.950000%=70778;99.990000%=70778;0%=0;0%=0;0%=0;7477;70557;30243.804338;18512.970716;147456;230400;100.000000%;188928.000000;58650.264859;59392;37998;37;1563;17;70;43.056138;10.402632;10657;1018269;309182.507707;302540.018880;1.000000%=10682;5.000000%=22151;10.000000%=30015;20.000000%=61603;30.000000%=93847;40.000000%=125304;50.000000%=152043;60.000000%=183500;70.000000%=396361;80.000000%=641728;90.000000%=775946;95.000000%=943718;99.000000%=1019215;99.500000%=1019215;99.900000%=1019215;99.950000%=1019215;99.990000%=1019215;0%=0;0%=0;0%=0;10698;1018299;309225.685569;302542.033998;18432;54400;95.836623%;36416.000000;25433.216706;0.128041%;0.320102%;276;0;1;0.4%;0.7%;1.5%;2.9%;94.5%;0.0%;0.0%;0.00%;0.00%;0.00%;0.00%;0.00%;0.00%;0.00%;0.00%;0.00%;0.00%;0.00%;0.00%;4.74%;32.48%;28.10%;20.07%;6.57%;2.55%;3.28%;1.46%;0.73%;0.00%;sdb;297;60;0;0;8639;12462;21101;95.45%
3;fio-3.19;libaio_randrw_1024kB_mix_read80_1job_QD16;0;0;73728;55226;53;1335;14;60;25.792681;5.446517;10041;908942;180405.286694;196438.088237;1.000000%=10027;5.000000%=21364;10.000000%=29753;20.000000%=49545;30.000000%=66846;40.000000%=80216;50.000000%=112721;60.000000%=145752;70.000000%=191889;80.000000%=256901;90.000000%=375390;95.000000%=666894;99.000000%=910163;99.500000%=910163;99.900000%=910163;99.950000%=910163;99.990000%=910163;0%=0;0%=0;0%=0;10062;908956;180431.227708;196437.318347;43008;75911;100.000000%;59459.500000;23265.934421;24576;18408;17;1335;29;52;45.625042;5.136300;2266;913806;334865.698542;330929.496869;1.000000%=2277;5.000000%=2342;10.000000%=2375;20.000000%=2375;30.000000%=4227;40.000000%=11730;50.000000%=212860;60.000000%=492830;70.000000%=549453;80.000000%=700448;90.000000%=759169;95.000000%=851443;99.000000%=910163;99.500000%=910163;99.900000%=910163;99.950000%=910163;99.990000%=910163;0%=0;0%=0;0%=0;2296;913852;334911.450250;330931.072562;2048;19381;58.205671%;10714.500000;12256.281838;0.074963%;0.149925%;97;0;1;1.0%;2.1%;4.2%;8.3%;84.4%;0.0%;0.0%;0.00%;0.00%;0.00%;0.00%;0.00%;0.00%;0.00%;0.00%;0.00%;0.00%;0.00%;7.29%;2.08%;4.17%;12.50%;18.75%;26.04%;12.50%;11.46%;5.21%;0.00%;0.00%;sdb;119;19;0;0;11431;4186;15616;91.45%
3;fio-3.19;sync_rw_1024kB_mix_read80_1job_QD16;0;0;247808;237591;232;1043;13;46;23.595277;5.565957;5485;234301;37825.893731;26041.930279;1.000000%=9633;5.000000%=14614;10.000000%=18743;20.000000%=22675;30.000000%=24248;40.000000%=28180;50.000000%=34865;60.000000%=41680;70.000000%=45350;80.000000%=49020;90.000000%=53739;95.000000%=58458;99.000000%=233832;99.500000%=233832;99.900000%=233832;99.950000%=233832;99.990000%=233832;0%=0;0%=0;0%=0;5532;234314;37849.606860;26040.562642;238664;238664;100.000000%;238664.000000;0.000000;63488;60870;59;1043;14;57;37.554565;10.139959;4380;356638;120652.004097;97710.572417;1.000000%=4358;5.000000%=5472;10.000000%=10682;20.000000%=25821;30.000000%=56360;40.000000%=78118;50.000000%=101187;60.000000%=135266;70.000000%=166723;80.000000%=189792;90.000000%=295698;95.000000%=308281;99.000000%=358612;99.500000%=358612;99.900000%=358612;99.950000%=358612;99.990000%=358612;0%=0;0%=0;0%=0;4409;356674;120689.674952;97710.473096;58053;58053;95.372104%;58053.000000;0.000000;0.000000%;0.767018%;305;0;1;0.3%;0.7%;1.3%;2.6%;95.1%;0.0%;0.0%;0.00%;0.00%;0.00%;0.00%;0.00%;0.00%;0.00%;0.00%;0.00%;0.00%;0.00%;0.00%;2.96%;11.18%;56.91%;17.43%;9.21%;2.30%;0.00%;0.00%;0.00%;0.00%;sdb;255;53;0;0;7514;6259;13773;90.30%
3;fio-3.19;sync_randrw_1024kB_mix_read80_1job_QD16;0;0;103424;86619;84;1194;13;54;25.225010;5.761086;11167;897215;186167.299069;170611.347990;1.000000%=16908;5.000000%=21626;10.000000%=23986;20.000000%=38535;30.000000%=65798;40.000000%=94896;50.000000%=147849;60.000000%=200278;70.000000%=244318;80.000000%=283115;90.000000%=383778;95.000000%=488636;99.000000%=876609;99.500000%=893386;99.900000%=893386;99.950000%=893386;99.990000%=893386;0%=0;0%=0;0%=0;11192;897239;186192.659624;170611.730086;63488;88832;87.925282%;76160.000000;17920.914262;33792;28301;27;1194;27;63;41.979727;7.398398;2228;8460;2903.612667;1232.327555;1.000000%=2244;5.000000%=2277;10.000000%=2342;20.000000%=2342;30.000000%=2375;40.000000%=2506;50.000000%=2539;60.000000%=2572;70.000000%=2637;80.000000%=2899;90.000000%=3260;95.000000%=6127;99.000000%=8454;99.500000%=8454;99.900000%=8454;99.950000%=8454;99.990000%=8454;0%=0;0%=0;0%=0;2262;8488;2945.728455;1229.188149;20480;37148;100.000000%;28814.000000;11786.055829;0.000000%;0.419111%;135;0;1;0.7%;1.5%;3.0%;6.0%;88.8%;0.0%;0.0%;0.00%;0.00%;0.00%;0.00%;0.00%;0.00%;0.00%;0.00%;0.00%;0.00%;0.00%;22.39%;2.24%;2.99%;17.16%;10.45%;23.88%;17.91%;1.49%;1.49%;0.00%;0.00%;sdb;152;35;0;0;16193;101;16295;91.85%

3 下面开始用Python来解析这个log,我们需要用到Python中文件函数open,调用两个模块sys和argparse模块 如下:

#!/usr/bin/python
import argparse
import sys
inputfile = sys.argv[1]   
resultfile = sys.argv[2] 
rwm = sys.argv[3] 

sys.argv[n]是传递Python脚本的第几个参数,这里我主要用到三个参数:
inputfile :代表要打开的fio log文件
resultfile:代表要输出的解析结果
rwm: 代表read.write,mix三种读写模式
(1)下面用open函数来处理一下sdb_mix_data.log
先用换行符进行分割,因为总共有4个workload,也就是4个换行,分割之后,列表里就会有5个元素第5个元素为空,需要用函数pop(-1)去掉最后一个元素空

#!/usr/bin/python
import argparse
import sys   
inputfile = "sdb_mix_data.log"  
resultfile = "sdb_mix.csv" 
rwm = "read" 
datastr = open(inputfile).read()
data = datastr.split('\n')
data.pop(-1)
print "len(data)"

执行结果:
在这里插入图片描述
(2) 第二步就是用open函数write一个输出表格 如下:

#!/usr/bin/python
import argparse
import sys    
inputfile = "sdb_mix_data.log"  
resultfile = "sdb_mix.csv" 
rwm = "read" 
datastr = open(inputfile).read()
data = datastr.split('\n')
data.pop(-1)
if rwm == "read":f=open(resultfile,"a")f.write("workload,bandwith(kb/s),IOPS,lat-avg(us),Qos(us) 99%,Qos(us) 99_9%, Qos(us) 99_99%,lat-max(us)\n")f.close()

生成表格如下:
在这里插入图片描述
(3)第三步 就是把log的数据追加到CSV里

#!/usr/bin/python
import argparse
import sys    
inputfile = "sdb_mix_data.log"  
resultfile = "sdb_mix.csv" 
rwm = "read" 
datastr = open(inputfile).read()
data = datastr.split('\n')
data.pop(-1)
if rwm == "read":f=open(resultfile,"a")f.write("workload,bandwith(kb/s),IOPS,lat-avg(us),Qos(us) 99%,Qos(us) 99_9%, Qos(us) 99_99%,lat-max(us)\n")f.close()for i in data:oneCaseList = i.split(";")caseName = oneCaseList[2]oneCaseRes = caseName +  "," + oneCaseList[6] + "," + oneCaseList[7] + "," + oneCaseList[39].split(".")[0] + "," + oneCaseList[29].split("=")[1] + "," + oneCaseList[31].split("=")[1] + "," + oneCaseList[33].split("=")[1] + "," +  oneCaseList[38].split(".")[0] + "\n"f = open(resultfile,"a")f.write(oneCaseRes)f.close()

结果如下图:
在这里插入图片描述
(4)这个是read的数据,下面看看write的数据

#!/usr/bin/python
import argparse
import sys    
inputfile = "sdb_mix_data.log"  
resultfile = "sdb_mix.csv" 
rwm = "write" 
datastr = open(inputfile).read()
data = datastr.split('\n')
data.pop(-1)
if rwm == "read":f=open(resultfile,"a")f.write("workload,bandwith(kb/s),IOPS,lat-avg(us),Qos(us) 99%,Qos(us) 99_9%, Qos(us) 99_99%,lat-max(us)\n")f.close()for i in data:oneCaseList = i.split(";")caseName = oneCaseList[2]oneCaseRes = caseName +  "," + oneCaseList[6] + "," + oneCaseList[7] + "," + oneCaseList[39].split(".")[0] + "," + oneCaseList[29].split("=")[1] + "," + oneCaseList[31].split("=")[1] + "," + oneCaseList[33].split("=")[1] + "," +  oneCaseList[38].split(".")[0] + "\n"f = open(resultfile,"a")f.write(oneCaseRes)f.close()
if rwm == "write":f=open(resultfile,"a")f.write("workload,bandwith(kb/s),IOPS,lat-avg(us),Qos(us) 99%,Qos(us) 99_9%, Qos(us) 99_99%,lat-max(us)\n")f.close()for i in data:oneCaseList = i.split(";")caseName = oneCaseList[2]oneCaseRes = caseName +  ","  + oneCaseList[47] + "," + oneCaseList[48] + "," + oneCaseList[80] + "," + oneCaseList[70].split(".")[0] + "," + oneCaseList[72].split("=")[1] + "," + oneCaseList[74].split("=")[1]  + "," +  oneCaseList[79].split(".")[0] + "\n"f = open(resultfile,"a")f.write(oneCaseRes)f.close()

结果如下:
在这里插入图片描述
(5) 因为是读写混合数据,是要把read和write的数据放在同一个CSV里边的 如下:

#!/usr/bin/python
import argparse
import sys    
inputfile = "sdb_mix_data.log"  
resultfile = "sdb_mix.csv" 
rwm = "mix" 
datastr = open(inputfile).read()
data = datastr.split('\n')
data.pop(-1)
if rwm == "read":f=open(resultfile,"a")f.write("workload,bandwith(kb/s),IOPS,lat-avg(us),Qos(us) 99%,Qos(us) 99_9%, Qos(us) 99_99%,lat-max(us)\n")f.close()for i in data:oneCaseList = i.split(";")caseName = oneCaseList[2]oneCaseRes = caseName +  "," + oneCaseList[6] + "," + oneCaseList[7] + "," + oneCaseList[39].split(".")[0] + "," + oneCaseList[29].split("=")[1] + "," + oneCaseList[31].split("=")[1] + "," + oneCaseList[33].split("=")[1] + "," +  oneCaseList[38].split(".")[0] + "\n"f = open(resultfile,"a")f.write(oneCaseRes)f.close()
if rwm == "write":f=open(resultfile,"a")f.write("workload,bandwith(kb/s),IOPS,lat-avg(us),Qos(us) 99%,Qos(us) 99_9%, Qos(us) 99_99%,lat-max(us)\n")f.close()for i in data:oneCaseList = i.split(";")caseName = oneCaseList[2]oneCaseRes = caseName +  ","  + oneCaseList[47] + "," + oneCaseList[48] + "," + oneCaseList[80] + "," + oneCaseList[70].split(".")[0] + "," + oneCaseList[72].split("=")[1] + "," + oneCaseList[74].split("=")[1]  + "," +  oneCaseList[79].split(".")[0] + "\n"f = open(resultfile,"a")f.write(oneCaseRes)f.close()
if rwm == "mix":f=open(resultfile,"a")f.write("workload,read,bandwith(kb/s),IOPS,Lantency(us),Qos(us) 99%,Qos(us) 99_9%, Qos(us) 99_99%,write,bandwith(kb/s),IOPS,Lantency(us),Qos(us) 99%,Qos(us) 99_9%, Qos(us) 99_99%\n")f.close()for i in data:oneCaseList = i.split(";")caseName = oneCaseList[2]oneCaseRes = caseName +  "," + "read" + "," + oneCaseList[47] + "," + oneCaseList[48] + "," + oneCaseList[80] + "," + oneCaseList[70].split(".")[0] + "," + oneCaseList[72].split("=")[1] + "," + oneCaseList[74].split("=")[1]  + "," +  oneCaseList[79].split(".")[0] + "," + "write" + "," + oneCaseList[47] + "," + oneCaseList[48] + "," + oneCaseList[80] + "," + oneCaseList[70].split(".")[0] + "," + oneCaseList[72].split("=")[1] + "," + oneCaseList[74].split("=")[1]  + "," +  oneCaseList[79].split(".")[0] + "\n"f = open(resultfile,"a")f.write(oneCaseRes)f.close()

结果如下图:
在这里插入图片描述
(6) 把三个参数(inputfile , resultfile ,rwm )写进函数里 最终的Python脚本如下:

#!/usr/bin/python
import argparse
import sys
def fiodata(inputFile, resultFile,rwm):datastr = open(inputfile).read()data = datastr.split('\n')data.pop(-1)if rwm == "read":f=open(resultfile,"a")f.write("workload,bandwith(kb/s),IOPS,lat-avg(us),Qos(us) 99%,Qos(us) 99_9%, Qos(us) 99_99%,lat-max(us)\n")f.close()for i in data:oneCaseList = i.split(";")caseName = oneCaseList[2]oneCaseRes = caseName +  "," + oneCaseList[6] + "," + oneCaseList[7] + "," + oneCaseList[39].split(".")[0] + "," + oneCaseList[29].split("=")[1] + "," + oneCaseList[31].split("=")[1] + "," + oneCaseList[33].split("=")[1] + "," +  oneCaseList[38].split(".")[0] + "\n"f = open(resultfile,"a")f.write(oneCaseRes)f.close()if rwm == "write":f=open(resultfile,"a")f.write("workload,bandwith(kb/s),IOPS,lat-avg(us),Qos(us) 99%,Qos(us) 99_9%, Qos(us) 99_99%,lat-max(us)\n")f.close()for i in data:oneCaseList = i.split(";")caseName = oneCaseList[2]oneCaseRes = caseName +  ","  + oneCaseList[47] + "," + oneCaseList[48] + "," + oneCaseList[80] + "," + oneCaseList[70].split(".")[0] + "," + oneCaseList[72].split("=")[1] + "," + oneCaseList[74].split("=")[1]  + "," +  oneCaseList[79].split(".")[0] + "\n"f = open(resultfile,"a")f.write(oneCaseRes)f.close()if rwm == "mix":f=open(resultfile,"a")f.write("workload,read,bandwith(kb/s),IOPS,Lantency(us),Qos(us) 99%,Qos(us) 99_9%, Qos(us) 99_99%,write,bandwith(kb/s),IOPS,Lantency(us),Qos(us) 99%,Qos(us) 99_9%, Qos(us) 99_99%\n")f.close()for i in data:oneCaseList = i.split(";")caseName = oneCaseList[2]oneCaseRes = caseName +  "," + "read" + "," + oneCaseList[47] + "," + oneCaseList[48] + "," + oneCaseList[80] + "," + oneCaseList[70].split(".")[0] + "," + oneCaseList[72].split("=")[1] + "," + oneCaseList[74].split("=")[1]  + "," +  oneCaseList[79].split(".")[0] + "," + "write" + "," + oneCaseList[47] + "," + oneCaseList[48] + "," + oneCaseList[80] + "," + oneCaseList[70].split(".")[0] + "," + oneCaseList[72].split("=")[1] + "," + oneCaseList[74].split("=")[1]  + "," +  oneCaseList[79].split(".")[0] + "\n" f = open(resultfile,"a")f.write(oneCaseRes)f.close()
inputfile = sys.argv[1]   
resultfile = sys.argv[2] 
rwm = sys.argv[3] 
fiodata(inputfile,resultfile,rwm)

运行:
python3 minmal.py sdb_mix_data.log result.csv mix
结果:
在这里插入图片描述
4 接下来需要在shell脚本里调用Python脚本 如下:

#!/bin/bash
if [ $# != 2 ]; thenecho "You must input  the time of each testcase (unit is second)"exit -1
fi
hdd=$1
time=$2
date
echo " sequential random  write  test start"
for ioengine in libaio sync
do
for rw  in   write  randwrite
dofor bs in 128k  
dofor iodepth in 16 
dofor jobs in 1  
do	    date  echo "$hdd $rw $bs iodepth=$iodepth numjobs=$jobs  test satrt"job_name="${ioengine}_${bs}B_${rw}_${jobs}job_${iodepth}QD"fio  --name=$job_name  --filename=/dev/$hdd --ioengine=${ioengine} --direct=1 --thread=1 --numjobs=${jobs} --iodepth=${iodepth} --rw=${rw} --bs=${bs} --runtime=$time --time_based=1  --size=100% --group_reporting  --minimal  >>${hdd}_write.log        
done        
done
done
done
done
python3 minimal.py ${hdd}_write.log  ${hdd}_rw_write.csv  write
echo " sequential  randrom read  test start"
for ioengine in libaio sync
do
for rw  in   read  randread
dofor bs in 128k  
dofor iodepth in 16 
dofor jobs in 1  
do	    date  echo "$hdd $rw $bs iodepth=$iodepth numjobs=$jobs  test satrt"job_name="${ioengine}_${bs}B_${rw}_${jobs}job_${iodepth}QD"fio  --name=$job_name  --filename=/dev/$hdd --ioengine=${ioengine} --direct=1 --thread=1 --numjobs=${jobs} --iodepth=${iodepth} --rw=${rw} --bs=${bs} --runtime=$time --time_based=1  --size=100% --group_reporting  --minimal  >>${hdd}_read.log        
done        
done
done
done
done
python3 minimal.py ${hdd}_read.log  ${hdd}_rw_read.csv  read
echo " sequential randmon  mix  test"
date
for ioengine in libaio sync
do
for rw in rw randrw
do
for mixread in 80  
do
for blk_size in 1024k  
do
for jobs in 1 
do
for queue_depth in  16 
do      job_name="${ioengine}_${rw}_${blk_size}B_mix_read${mixread}_${jobs}job_QD${queue_depth}"echo "$hdd $job_name  test satrt"fio --name=${job_name} --filename=/dev/$hdd --ioengine=libaio --direct=1 --thread=1 --numjobs=${jobs} --iodepth=${queue_depth} --rw=${rw} --bs=${blk_size} --rwmixread=$mixread --runtime=$time --time_based=1 --size=100% --group_reporting  --minimal >> "$hdd"_mix_data.log
done
done
done
done
done
done
python3 minimal.py ${hdd}_mix_data.log  ${hdd}_mix.csv  mix
mkdir $hdd
mkdir $hdd/test_data
mkdir $hdd/test_log
mv $hdd*.log   $hdd/test_log
mv $hdd*.csv    $hdd/test_data
echo "test has been finsished"

5 OK 到这里测试脚本已经完成,测试一下:
bash hdd-single-fio.sh sdk 1 (跑一个HDD 1秒钟)
结果如下:
read的结果
在这里插入图片描述 write的结果在这里插入图片描述
混合结果在这里插入图片描述

相关文章:

Linux下Python脚本的编写解析fio(minimal格式)(三)

在服务器测试(storage)过程中,会看到很多人写跑fio的脚本用minimal格式来解析,因为这种格式返回的结果对与脚本(shell,python)解析log非常方便.下面介绍一下这种方式下,用Python来解析log 1 一般客户会要求结果中出现一下参数的值: bandwidth…...

【实战场景二】如何设计一个分布式锁?

如何优雅的设计一个分布式锁?如何设计一个分布式锁?1、什么是分布式锁2、那么分布式锁,具备什么条件呢?3、设计分布式锁有哪些方式?3.1 利用redis实现分布式锁原理3.2 基于数据库做分布式锁3.3 基于zookeeper实现分布式…...

Java中ThreadLocal类详解

ThreadLocal从名字上我们看出,它叫做本地线程变量,每个线程都有各自的的变量,而不再是我们之前的两个线程共用同一个变量;以这个类创建的变量,在多个线程都用到这个变量时,可以为每一个线程创建一个变量副本…...

从一致性角度考虑推荐冷启动长尾推荐问题(一)

前言:目前中长尾推荐的方法有很多,主流的方法有几类比如:1)在没有项目ID嵌入的情况下提高推荐模型的鲁棒性,2)利用有限的交互数据提高学习效率,如使用元学习方法;3)利用物品侧面信息,便于物品ID嵌入的初始化&#xff0…...

电脑(Windows)常用快捷键

简述:实用的键盘快捷键是一个程序员的必备技能,下面给大家整理了一下常用的键盘快捷键; ⭐CtrlP 打开“打印机”对话框; ⭐CtrlW 关闭当前网页; ⭐CtrlF 查找(网页内查找); ⭐…...

Java类加载器

1 类加载器 1.1 类加载 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过类的加载,类的连接,类的初始化这三个步骤来对类进行初始化。如果不出现意外情况,JVM将会连续完成这三个步骤,所以有时也把这三个步骤统称为…...

信号完整性设计规则之单根信号失真最小化

本文内容从《信号完整性与电源完整性分析》整理而来,加入了自己的理解,如有错误,欢迎批评指正。 1. 通常采用所能容许的最长上升边。 上升边越短,带宽越大,信号完整性问题越严重。 2. 使用可控阻抗走线。 可控阻抗…...

Python3 数据结构

列表 Python中列表是可变的,这是它区别于字符串和元组的最重要的特点,一句话概括即:列表可以修改,而字符串和元组不能。 以下是 Python 中列表的方法: 方法 描述 list.append(x) 把一个元素添加到列表的结尾&#xf…...

Compose-Navigation带参传递

带参传递 目前 compose 还不支持传入对象作为参数! 简单双参数 根目录下新建文件夹 entity,新建单例类 ContentType 作为数据类存储位置 新增数据类 DemoContent,这表示我们需要传入的两个参数,后面带问号判空 object ContentT…...

【函数栈帧的创建和销毁】 -- 神仙级别底层原理,你学会了吗?

文章目录1.函数的调用方式 2.函数在栈区上的动作 1.函数的调用方式 相信你对调用函数一点都不陌生,但是在调用函数的过程中,却存在着很多你无法见到的东西,这是底层信息,想要理解透彻,就得深入底层去观察。 本文以…...

Promise的使用及原理

此文章主要讲解核心思想和基本用法,想要了解更多细节全面的使用方式,请阅读官方API 这篇文章假定你具备最基本的异步编程知识,例如知道什么是回调,知道什么是链式调用,同时具备最基本的单词量,例如page、us…...

怎么拥有一个帅气的 CMD 命令窗口 ❓ - Windows

自从拥有这样一个炫酷的命令窗口,我都舍不得关掉它了 关于我为什么我要闲的去 “打扮” 一个命令窗口,这要从星期五下午的一场 摸鱼 🐠 开始,当时我要创建一个 vue ts vite 的项目练练手,为新项目开始做准备&#x…...

时隔多年再学习Vuex,什么?原来如此简单!

时隔多年再学习Vuex,什么?原来如此简单! start 写 Vue 写了好多年了,少不了和 Vuex 打交道。虽然使用它的次数非常频繁,但是潜意识里总觉得这东西很难,导致遇到与之相关的问题就容易慌张。时至今日,升级版…...

Linux笔记_gcc

Linux_gcc程序的翻译链接库make与makefile关于gcc的一些笔记。 程序的翻译 gcc/g是一个编译器。 预处理:头文件展开、条件编译、宏替换、去注释 编译:C语言汇编语言 汇编:汇编->可重定位目标二进制文件,不可以被执行&#xff0…...

2023美赛MCM A题 详细思路

2023美赛(MCM/ICM)如期开赛,为了尽早的帮大家确定选题。这里我们加急为大家编辑出A赛题详细思路,方便大家快速对A题目的难度有个大致的了解。同时,我们也给出了A题目简要的解题思路,以及该问题在实际解决中可能会遇到的难点。A题的…...

c#: NetTopologySuite凹凸多边形计算

环境: .net 6.0NetTopologySuite 2.5.0vs2022平面二维 一、夹角计算 1.1 计算向量与x轴正方向的夹角 方法: AngleUtility.Angle(Coordinate p) 下图上的t2即为p,之所以这么写是为了和AngleUtility.AngleBetweenOriented做比较 注意: 结果…...

NFT Insider #86:A16z 领投,YGG 获得 1380 万美元融资,The Sandbox与《北斗神拳》合作

引言:NFT Insider由NFT收藏组织WHALE Members、BeepCrypto联合出品,浓缩每周NFT新闻,为大家带来关于NFT最全面、最新鲜、最有价值的讯息。每期周报将从NFT市场数据,艺术新闻类,游戏新闻类,虚拟世界类&#…...

Sort_Algorithm

排序算法前言插入排序折半插入排序希尔排序冒泡排序快速排序选择排序堆排序归并排序前言 排序算法:将一堆数据元素按关键字递增或者递减的顺序,进行排序。 排序算法的评价指标:时间复杂度,空间复杂度,算法稳定性。 算…...

【初探人工智能】2、雏形开始长成

【初探人工智能】2、雏形开始长成【初探人工智能】2、雏形开始长成安装Flask封装Web接口雏形设置接收参数功能验证聊天写代码代码补全生成图片写在后面笔者初次接触人工智能领域,文章中错误的地方还望各位大佬指正! 【初探人工智能】2、雏形开始长成 在…...

【LeetCode】剑指 Offer(2)

目录 写在前面: 题目: 题目的接口: 解题思路: 代码: 过啦!!! 写在最后: 写在前面: 今天的每日一题好难,我不会dp啊啊啊啊啊啊。 所以&am…...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...

在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能

下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql

智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...

CentOS下的分布式内存计算Spark环境部署

一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享

文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互

引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

sqlserver 根据指定字符 解析拼接字符串

DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

Axios请求超时重发机制

Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式&#xff1a; 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...