本發(fā)明涉及計算機服務(wù)器技術(shù)領(lǐng)域,尤其涉及一種硬盤性能穩(wěn)定性的測試及展現(xiàn)方法。
背景技術(shù):
隨著it領(lǐng)域技術(shù)的不斷發(fā)展,傳統(tǒng)信息化服務(wù)以及日趨強大的云計算服務(wù)對服務(wù)器的存儲需求越來越高。硬盤的性能穩(wěn)定性作為服務(wù)器的一項重要指標(biāo),越來越被重視。這要求服務(wù)器在7*24小時的工作下,能夠保證硬盤的性能維持在滿足需求的位置,不能夠出現(xiàn)忽高忽低的現(xiàn)象,這將影響服務(wù)器上運行的業(yè)務(wù)的性能,也是不利于硬盤本身的健康的。所以在服務(wù)器測試階段,對硬盤的性能穩(wěn)定性的測試就是必須的了。
以前的測試只關(guān)注硬盤性能的均值滿足需求即可,沒有整個運行過程的實時值的監(jiān)控和處理、對比的測試。
技術(shù)實現(xiàn)要素:
為了解決以上技術(shù)問題,本發(fā)明提出了一種硬盤性能穩(wěn)定性的測試及展現(xiàn)方法。具體地說是一種實用性強,可以自動化進行硬盤性能穩(wěn)定性測試并將結(jié)果進行處理以便對比的方法。
本發(fā)明引入了一致性的測試概念:在性能均值的上下10%(此值可調(diào))范圍內(nèi)的運行時間占總運行時間的比例。使用一致性對測試結(jié)果進行處理能夠反映性能穩(wěn)定性的好壞。
本發(fā)明的技術(shù)方案是:
一種硬盤性能穩(wěn)定性的測試及展現(xiàn)方法,其具體實現(xiàn)過程為:
1、安裝配置測試所需要的工具(fio、python等)和文件。
2、根據(jù)輸入要測試的盤符,自動修改測試配置文件。
3、使用fio搭配預(yù)定的測試參數(shù)自動挨個對指定的硬盤進行性能測試,使用fio自帶的write_iops_log和write_bw_log參數(shù)實時輸出當(dāng)前的性能值到指定命名對應(yīng)的文件中存儲。
4、性能測試完成后,對測試結(jié)果文件中的結(jié)果進行處理。根據(jù)一致性的概念,需要計算出測試總時間內(nèi)性能的均值i,然后將每一個實時值j與計算出來的i進行比對,看是否超出了i±i*10%(此處的10%可調(diào),根據(jù)實際需求進行更改)。如果超出了標(biāo)準(zhǔn),則此實時值j算作不合格;如果沒超出標(biāo)準(zhǔn),則此實時值j算作合格。最后計算一下合格的總的數(shù)量,看占到總測試實時值的比例是多少(具體達標(biāo)的比例根據(jù)實際需要更改)。
5、將結(jié)果用圖表展現(xiàn)。獲取所有的實時值,將所有的值按照時間順序畫成一個折線圖。然后將前述計算得到的標(biāo)準(zhǔn)i±i*10%畫成兩條直線。這樣三條線在一個圖里面,就能夠清楚的看到在哪些時間點出現(xiàn)了不在兩條直線之間的值,即不符合標(biāo)準(zhǔn)的值。同時在圖上將最大值、最小值、平均值、一致性的值、上下限的值根據(jù)第四步算出來之后自動添加到圖片上顯示。
本發(fā)明借助fio和python能夠自動化的進行硬盤性能測試,并記錄實時的性能值,然后將生成的結(jié)果進行處理,以圖形化的方式展現(xiàn)出來。硬盤性能穩(wěn)定性是否滿足,一目了然。
附圖說明
圖1是本發(fā)明的流程示意圖;
圖2是最后生成的圖片樣例示意圖。
具體實施方式
下面對本發(fā)明的內(nèi)容進行更加詳細的闡述:
1、安裝測試所需要的python以及軟件包。借助pip工具將所需要的軟件包離線安裝,不需要連接網(wǎng)絡(luò)。
#!/bin/bash
root_dir=`pwd`
tar-zxfpython-2.7.12.tgz
tar-zxfsetuptools-28.8.0.tar.gz
tar-zxfpip-9.0.1.tar.gz
cdpython-2.7.12
./configure
make
makeinstall
cd$root_dir/setuptools-28.8.0
python2.7setup.pyinstall
cd$root_dir/pip-9.0.1
python2.7setup.pyinstall
cd$root_dir
pipinstall--no-index--find-links="offline/"-rrequirments.txt
echo"setenvironmentsuccefully!"
2、根據(jù)指定的盤符自動修改fio測試的配置文件。測試預(yù)設(shè)了六個配置文件,["seqprecondition.fio","seqwrite.fio","seqread.fio","randomprecondition.fio","randomwrite.fio","randomread.fio"],里面的filename=xxx為指定盤符測試參數(shù)。如下步驟自動去對這六個文件進行修改。
defchange_devicename(filename_test):
pattern=re.compile(r"filename=.*")
file_under_filter=open(filename_test,mode='r')
text_under_filter=file_under_filter.read()
file_under_filter.close()
new_text=re.sub(pattern=pattern,repl="filename=%s"%sys.argv[1],string=text_under_filter)
file_under_filter=open(filename_test,mode='w')
file_under_filter.write(new_text)
file_under_filter.close()
if__name__=='__main__':
filename_test_list=["seqprecondition.fio","seqwrite.fio","seqread.fio","randomprecondition.fio","randomwrite.fio","randomread.fio"]
foritem_change_devicenameinfilename_test_list:
change_devicename(item_change_devicename)
3、使用fio進行一致性測試,并保存測試結(jié)果。測試結(jié)果根據(jù)當(dāng)前測試項目的名字自動命名。如測試項目為seqread.fio,則結(jié)果文件為seqread.fio.result
defget_data(filename_test,filename_result):
filename_display="%s.result"%filename_test
fio_process=subprocess.call("./fio%s>>results/%s"%(filename_test,filename_display),shell=true)
iffio_process==0:
print"run%ssuccessfully!"%filename_test
else:
print"fiorunfail!pleasecheck!"
4、測試結(jié)束之后,對測試結(jié)果進行處理:
#將測試結(jié)果全部讀取入內(nèi)存列表
iffilename_result!="none":
data_list_temp=[]
data_time=[]
data_over_list=[]
filename_to_filter=os.path.join("results",filename_result)
file_data=open(filename_to_filter,mode='r')
foritem_file_datainfile_data:
ifitem_file_data!=os.linesep:
data_data=item_change_devicename.split(',')[1]
data_list_temp.append(int(data_data.strip()))
#獲取測試最后的2700個測試值
data_list_temp.reverse()
data_list=data_list_temp[:2700]
data_list.reverse()
length=len(data_list)
foriinrange(1,length+1):
data_time.append(i)
#計算平均值
average_data=float(sum(data_list))/float(len(data_list))
#計算一致性要求的±10%的上下限
data_high=average_data*1.1
data_low=average_data*0.9
#獲取最大值和最小值,以及其所在的時間點
data_higest=max(data_list)
index_higest=data_list.index(data_higest)
data_lowest=min(data_list)
index_lowest=data_list.index(data_lowest)
#獲取超出±10%的范圍的測試值,并計算其數(shù)量
foritem_dataindata_list:
ifitem_data<=data_loworitem_data>=data_high:
data_over_list.append(item_data)
#計算一致性,并保留3位小數(shù)。
data_yizhixing=1-round(float(len(data_over_list))/float(len(data_list)),3)
#開始畫圖
data_x=numpy.array(data_time)
data_y=numpy.array(data_list)
data_high_list=[]
data_low_list=[]
forcountinrange(len(data_list)):
data_high_list.append(data_high)
data_low_list.append(data_low)
filename_to_write=filename_test.split('.')[0]
figure_1=plyt.figure(filename_to_write)
figure=figure_1.add_subplot(111)
plyt.title(filename_to_write)
#將所有測試值依據(jù)時間順序畫折線圖
plyt.plot(data_x,data_y,color='red')
#畫出上限
plyt.plot(data_x,numpy.array(data_high_list),color='blue')
#畫出下限
plyt.plot(data_x,numpy.array(data_low_list),color='blue')
#添加上限注釋
figure.annotate('high=%s'%data_high,xy=(1000,data_high),xytext=(1500,data_high))
#添加下限注釋
figure.annotate('low=%s'%data_low,xy=(1000,data_low),xytext=(1500,data_low))
#添加平均值注釋
figure.annotate('average=%s'%average_data,xy=(1000,average_data),xytext=(1500,average_data))
#添加一致性注釋
figure.annotate('yizhixing=%s'%data_yizhixing,xy=(200,average_data),xytext=(300,average_data))
#添加最高點注釋
figure.annotate('highest(xy)=(%s,%s)'%(index_higest,data_higest),xy=(index_higest,data_higest),xytext=(index_higest,data_higest))
#添加最低點注釋
figure.annotate('lowest(xy)=(%s,%s)'%(index_lowest,data_lowest),xy=(index_lowest,data_lowest),xytext=(index_lowest,data_lowest))
time.sleep(1)
#將圖片保存到results文件夾中
filename_to_write_all=filename_to_write+'_image.png'
filename_to_save=os.path.join("results",filename_to_write_all)
figure_1.savefig(filename_to_save)
if__name__=='__main__':
iflen(sys.argv)!=2:
print"usage:python2.7filter_perf_ssd/dev/sdxor/dev/nvme0n1"
sys.exit(1)
devicename_to_test=sys.argv[1]
filename_test_list=["seqprecondition.fio","seqwrite.fio","seqread.fio","randomprecondition.fio","randomwrite.fio","randomread.fio"]
filename_result_list=["none","seqwrite_bw.1.log","seqread_bw.1.log","none","randomwrite_iops.1.log","randomread_iops.1.log"]
print"begintotest%s"%devicename_to_test
#記錄開始時間
print"begintimeis%s"%time.strftime('%y-%m-%d%h:%m:%s',time.localtime(time.time()))
ifos.path.exists("results")andos.path.isdir("results"):
shutil.rmtree("results")
os.mkdir("results")
forindex,iteminenumerate(filename_test_list):
print"begintotest%s"%item
get_data(item,filename_result_list[index])
#記錄結(jié)束時間
print"endtimeis%s"%time.strftime('%y-%m-%d%h:%m:%s',time.localtime(time.time()))。