Frage

Ich war ein einfachen Python-Skript zu schreiben aus und reconstruct Daten von einem ausgefallenen RAID5-Array zu lesen, dass ich nicht in der Lage war auf anderer Weise neu zu erstellen. Mein Skript läuft, aber langsam. Meine ursprüngliche Skript läuft bei etwa 80 MB / min. Ich habe das Skript da verbessert und es bei 550MB / min läuft, aber das scheint immer noch ein wenig niedrig. Der Python-Skript wird bei 100% CPU sitzt, so dass es CPU zu sein scheint eher als Scheibe begrenzt, was bedeutet, dass ich Gelegenheit für die Optimierung. Da das Skript nicht sehr lange überhaupt nicht in der Lage bin ich es effektiv zu profilieren, so weiß ich nicht, was es alles zusammen isst. Hier ist mein Skript, wie es jetzt (oder zumindest die wichtigen Bits) steht

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]

Bolding die aktuellen Fragen in diesem riesigen Textblock bezeichnen:

Gibt es etwas, kann ich dies schneller / besser machen tun? Wenn nichts in den Sinn kommt, ist es etwas, was ich zu einer besseren Forschung tun kann in das, was diese langsam gehen macht? (Gibt es auch eine Möglichkeit zum Profil Python auf einer pro Zeile Ebene?) Bin ich dies auch Handhabung den richtigen Weg, oder gibt es einen besseren Weg, große Mengen von binären Daten zu handhaben?

Der Grund, warum ich frage ist, ich habe ein 3-TB-Laufwerk Wiederaufbau und obwohl es funktioniert richtig (ich kann die Bild ro montieren, Schleife und Browse-Dateien in Ordnung) es ist eine lange Zeit. Ich maß es wie mit dem alten Code bis Mitte Januar nehmen, jetzt ist es bis Weihnachten dauern wird (so ist es Weg besser, aber es ist immer noch langsamer als ich erwartete, dass es sein.)

Bevor Sie fragen, ist dies ein mdadm RAID5 (64kb Blockgröße, links symmetrisch), aber die mdadm Metadaten fehlt irgendwie und mdadm erlaubt Ihnen nicht, ein RAID5 neu zu konfigurieren, ohne die Metadaten auf dem Datenträger zu Umschreiben, was ich zu vermeiden versuche um jeden Preis, ich will nicht riskieren, etwas nach oben schrauben und Daten zu verlieren, aber Remote kann die Möglichkeit sein.

War es hilfreich?

Lösung

  1. map(takexor, magicpotato) - This is probably better done with direct iteration, map isn't efficient if it needs to call other python code AFAIK, it needs to construct and destroy 16384 frame objects to perform the call, etc.

  2. Use the array module instead of struct

  3. If it's still too slow compile it with cython and add some static types (that will probably make it 2-3 orders of magnitude faster)

Andere Tipps

Google for: widefinder python. Some of the techniques discussed in the Python entries might be of use, such as memory mapping IO.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top