2010-12-22 83 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。

相关问题