Denkanstoss für Dateikopiertool

  • Hallo,

    vorab muss ich sagen, dass ich mich erst seit ein paar Tagen mit AutoIt auseinandersetze und daher ein absoluter Anfänger bin.
    Dank der Hilfe dieses Forums bin ich aber schon mal sehr gut vorangekommen.

    Ich bin mir darüber bewusst, dass AutoIt für mein Vorhaben vielleicht nicht ganz so die richtige Wahl ist, allerdings programmiere ich sonst nur in Objective-C und muss mich in C++ unter Windows noch mal einarbeiten.


    Ausgangssituation

    Wir haben bei uns in der Firma diverse Spezialserver, welche als Zuspieler für Videomaterial genutzt werden.
    Die Filme liegen als Einzelbilder (z.B. als TIFF) vor. Somit liegen auf einem Server diverse Verzeichnisse mit jeweils mehreren tausend Bilddateien.
    Die
    Dateinamen enthalten alle immer eine fortlaufende Zahl, wobei es
    ansonsten kein festes Format gibt.

    In einem Verzeichnis gibt es z.B. Dateien mit dem Namen Main_#####.tif,
    also z.B. Main_00000.tif bis Main_10000.tif), im nächsten Verzeichnis
    sind die Dateinamen dann im Format #####main.tif, usw.

    Da die Bilddateien unkomprimiert sind, kommen pro Film schonmal bis zu mehreren hundert Gigabyte an Daten zusammen.

    Bisher kopieren wir die Files ganz normal über das Netzwerk von einem Server auf den nächsten.


    Idee

    Da alle Server über jeweils 2 Gigabit-LAN-Schnittstellen verfügen, wollte ich gern für den Kopiervorgang jeweils beide Schnittstellen nutzen, um möglichst mit der doppelten Geschwindigkeit kopieren zu können.
    Der Treiber der NICs, sowie der eingesetzte Netzwerkswitch bieten zwar Teaming / Bonding-Optionen an, allerdings konnte in keiner Konfiguration ein Geschwindigkeitszuwachs erzielt werden.

    Mir kam die Idee die Routingtabelle des Quell-Rechners zu modifizieren und dann jeweils über beide Schnittstellen an beide Schnittstellen am Ziel-Rechner zu kopieren.

    Dazu habe ich ein kleines Programm in AutoIt geschrieben, welches zunächst 2 temporäre Einträge in der Routingtabelle einfügt:

    [autoit]

    $netconfig1 = RunWait(@WindowsDir & "\system32\route add " & $ip_d2n1 & " MASK 255.255.255.255 " & $ip_d1n1, @WindowsDir, @SW_HIDE)
    $netconfig2 = RunWait(@WindowsDir & "\system32\route add " & $ip_d2n2 & " MASK 255.255.255.255 " & $ip_d1n2, @WindowsDir, @SW_HIDE)

    [/autoit]

    Da ja alle Files durchnummeriert sind, wird im zweiten Schritt mittels einer For-Schleife jeweils ein Kopiervorgang mit den "ungeraden" Dateinamen von der ersten Netzwerkschnittstelle des Quell-Rechners auf die erste Schnittstelle des Ziel-Rechners und entsprechend einer mit den "geraden" Dateinamen von der zweiten Schnittstelle des Quell-Rechners auf die zweite Schnittstelle des Zielrechners gestartet. Aus Performancegründen nutze ich dazu Robocopy.

    [autoit]

    Run(@WindowsDir & "\System32\robocopy " & $sourcepath & " " & "\\" & $ip_d2n1 & $targetpath & " " & $FileList[$counter], @WindowsDir, @SW_HIDE)

    [/autoit]


    und

    [autoit]

    Run(@WindowsDir & "\System32\robocopy " & $sourcepath & " " & "\\" & $ip_d2n2 & $targetpath & " " & $FileList[$counter], @WindowsDir, @SW_HIDE)

    [/autoit]

    Das Ganze klappt soweit auch ganz zufriedenstellend, immerhin erziele ich damit einen Datendurchsatz von ca. 170 MB/s.

    Was nicht so schön ist, ist die Tatsache, dass für jede einzelne Datei ein eigener Prozess gestartet wird. Im Taskmanager werden dann schnell mal ca 1.500 aktive Prozesse angezeigt. Das macht zumindest die parralele Arbeit auf dem Quell-Rechner zu einer gewissen Qual.

    Meine Idee ist nun, dass nur 2 Prozesse gestartet werden, nämlich einer für die "ungeraden" und einer für die "geraden" Files.
    Dazu müsste man dann erstmal die komplette Dateiliste durchgehen und den String für den Kopiervorgang irgendwie generieren lassen, bevor dieser gestartet wird.

    Am Ende müsste es dann ungefähr so aussehen:

    Code
    robocopy quellverzeichnis zielverzeichnis file00001.tif file00003.tif file00005.tif ... file7999.tif


    und

    Code
    robocopy quellverzeichnis zielverzeichnis file00002.tif file00004.tif file00006.tif ... file8000.tif

    Mit welchem Befehl könnte ich einen solchen String über eine For-Schleife generieren?

    Ich hoffe, dass ich mich einigermaßen verständlich ausdrücken konnte und dass mir jemand helfen kann.


    Vielen Dank schon einmal im Voraus.


    Gruß
    Gardinero

  • Mit welchem Befehl könnte ich einen solchen String über eine For-Schleife generieren?

    [autoit]

    FileWrite

    [/autoit]


    ich denke aber dies würde dann die Befehlszeile für robocopy sprengen. Ich würde daher dazu raten ein Verzeichniss komplett über eine Route kopieren zu lassen und über die 2. Route ein 2. Verzeichnis.

    mfg autoBert

  • Würde auch mal vermuten, dass du bei einer gewissen Dateianzahl an die Grenzen der erlaubten Parameteranzahl kommst. Robocopy bietet aber anscheinend auch die Möglichkeit eine JOB-Datei abzuarbeiten. Dein Autoit Script könnte also eine solche Datei erzeugen und dann Robocopy für beide Jobs aufrufen.

    http://www.skonet.com/Articles_Archi…b_Template.aspx

    EDIT:

    [autoit]

    FileWrite

    [/autoit]


    Öhm ich denke mal er meinte wie er in einer Schleife den Parameterstring zusammenbaut...

    [autoit]


    $sCMDa = @WindowsDir & "\System32\robocopy " & $sourcepath & " " & "\\" & $ip_d2n2 & $targetpath
    $sCMDb = $sCMDa

    [/autoit][autoit][/autoit][autoit]

    for $i=0 to ubound($FileList)-1
    if $i > ubound($FileList)-1 then exitloop
    $sCMDa &= " " & $FileList[$i]
    $i += 1 ; damit nur jede zweite datei im String landet
    if $i > ubound($FileList)-1 then exitloop
    $sCMDb &= " " & $FileList[$i]
    next

    [/autoit][autoit][/autoit][autoit]

    consolewrite($sCMDa & @crlf)
    consolewrite($sCMDb & @crlf)

    [/autoit][autoit][/autoit][autoit]

    ;Run($sCMDa, @WindowsDir, @SW_HIDE)
    ;Run($sCMDb, @WindowsDir, @SW_HIDE)

    [/autoit]

    3 Mal editiert, zuletzt von misterspeed (11. Dezember 2012 um 19:54)