2010-12-22 81 views
1

我正在寫一個簡單的python腳本來讀取和重建失敗的RAID5陣列中的數據,我無法以任何其他方式重建數據。我的腳本正在運行,但緩慢。我的原始腳本以約80MB /分鐘的速度運行。自從我改進了這個腳本後,它以550MB/min的速度運行,但仍然有點低。 python腳本處於100%CPU,因此它似乎是CPU而不是磁盤受限,這意味着我有機會進行優化。因爲腳本不是很長,所以我無法有效地分析它,所以我不知道什麼東西在吃。這裏是我的腳本,因爲它代表現在(或者至少,最重要的位)使用python處理大量磁盤數據的最有效方法是什麼?

disk0chunk = disk0.read(chunkSize) 
#disk1 is missing, bad firmware 
disk2chunk = disk2.read(chunkSize) 
disk3chunk = disk3.read(chunkSize) 
if (parityDisk % 4 == 1): #if the parity stripe is on the missing drive 
    output.write(disk0chunk + disk2chunk + disk3chunk) 
else: #we need to rebuild the data in disk1 
    # disk0num = map(ord, disk0chunk) #inefficient, old code 
    # disk2num = map(ord, disk2chunk) #inefficient, old code 
    # disk3num = map(ord, disk3chunk) #inefficient, old code 
    disk0num = struct.depack("16384l", disk0chunk) #more efficient new code 
    disk2num = struct.depack("16384l", disk2chunk) #more efficient new code 
    disk3num = struct.depack("16384l", disk3chunk) #more efficient new code 
    magicpotato = zip(disk0num,disk2num,disk3num) 
    disk1num = map(takexor, magicpotato) 
    # disk1bytes = map(chr, disk1num) #inefficient, old code 
    # disk1chunk = ''.join(disk1bytes) #inefficient, old code 
    disk1chunk = struct.pack("16384l", *disk1num) #more efficient new code 

    #output nonparity to based on parityDisk 

def takexor(magicpotato): 
    return magicpotato[0]^magicpotato[1]^magicpotato[2] 

加粗來表示文字的這個巨大的塊中的實際問題:

有什麼我可以做的到讓這個更快/更好?如果什麼都沒有想到,有什麼我可以做的,以更好地研究是什麼讓這個緩慢走向? (是否還有一種方法可以在每行級別上對python進行概要分析?)我甚至可以正確處理這種情況,還是有更好的方法來處理大量的二進制數據?

我問的原因是我有一個3TB驅動器重建,即使它工作正常(我可以掛載圖像ro,循環和瀏覽文件罰款)這需要很長時間。我測量到1月中旬與舊代碼,現在它將採取直到聖誕節(所以它的方式更好,但它仍然比我預期的要慢)。

在你問之前,這是一個mdadm RAID5(64kb塊大小,左對稱),但mdadm元數據以某種方式丟失,並且mdadm不允許您重新配置RAID5而不重寫元數據到磁盤,我試圖不惜一切代價避免這種情況,我不想冒險搞砸東西並丟失數據,然而遠程的可能性可能是。

+0

你是否分析你的代碼?我不知道每行分析,但你可以做每個功能分析。 – W55tKQbuRu28Q4xv 2010-12-22 09:10:23

+0

我只有兩個功能。 :)我還沒有分析它,因爲它似乎有點無用,我將有兩個數據點,主代碼和takexor中的代碼。當然,除非我誤解了Python的性能分析函數(這是可能的) – OmnipotentEntity 2010-12-22 09:15:29

回答

3
  1. 地圖(takexor,magicpotato) - 這可能是更好地與直接迭代完成,地圖不是有效的,如果它需要AFAIK調用其他Python代碼,需要構造和銷燬16384名的對象執行呼叫等

  2. 使用陣列模塊而不是結構

  3. 如果它還是太慢了與用Cython編譯它,並添加一些靜態類型(這可能會使其2-3個數量級更快)

0

Google for:widefinder python。在Python條目中討論的一些技術可能是有用的,比如內存映射IO。

相關問題