Einzelnen Beitrag anzeigen

Passi077

Registriert seit: 7. Okt 2004
23 Beiträge
 
#1

Performanceproblem: Inkrementelles Backup

  Alt 30. Apr 2009, 17:09
Hi,

ich hab mir ein Tool für ein inkrementelles Backup von mehreren Verzeichnissen geschrieben.
In der Testumgebung mit ca. 5000 Files funktioniert das auch wunderbar und sogar sehr performant. Leider ist dies im realen Einsatz, bei dem ca. 75.000 Dateien gesichert werden müssen, nicht mehr der Fall. Es gibt erhebliche Performanceprobleme beim Ausführen.

Das Ganze ist wie folgt implementiert:
Da es sich um ein inkrementelles Backup handelt, muss ich alle gesicherten Dateien mit den entsprechenden Dateien auf der Festplatte abgleichen. Dazu hab ich mir eine pseudo-Hash-Funktion geschrieben, die eben viel schneller ist als MD5 oder ähnliches. Dafür nicht unbedingt eindeutig, aber für meine Zwecke vollkommen ausreichend.

Bei einem Backup gehe ich nun wie folgt vor:
1. Laden der Liste von gesicherten Dateien mit den alten Hashwerten
2. Vergleichen aller dieser Dateien mit den aktuell auf der Festplatte vorhandenen Dateien
3. Daraus eine Liste mit Dateien erstellen, die kopiert werden müssen. Dazu gehören: Neue Dateien und geänderte Dateien
4. Auf der Festplatte nicht mehr vorhandene Dateien markieren

Um die Performance zu erhöhen setze ich auf HashMaps. Diese kommen aus der DCL. Die Zuordnung ist dabei: <Dateiname, Hash>

Die konkrete Implementierung für diese Schritte ist:
Delphi-Quellcode:
procedure TForm1.DoBackUp();
var
  fileListLastState: IStrStrMap;
  fileListCurrState: IStrStrMap;
begin
  // ..
  // Updated und Added Files finden
  iter := fileListCurrState.KeySet.First; // Hier gibt's ein Performanceproblem
  while iter.HasNext do
  begin
    key := iter.Next;
    if fileListLastState.ContainsKey(key) then
    begin
      if not (fileListLastState.GetValue(key)=getHash(key)) then
      begin
        UpdatedFiles.PutValue(key, getHash(key));
      end;
    end
    else
    begin
      AddedFiles.PutValue(key, getHash(key));
    end;
  end;

  // Deleted Files finden
  iter := fileListLastState.KeySet.First; // Hier gibt's ein Performanceproblem

  while iter.HasNext do
  begin
    key := iter.Next;
    if not fileListCurrState.ContainsKey(key) then
    begin
      DeletedFiles.PutValue(key, '-');
    end;
  end;
Danach werden dann die Dateien kopiert.

Das konkrete Problem ist jetzt, wenn die fileListCurrState (Dateien auf der Festplatte) und auch die fileListLastState (Dateien vom letzten Backup) z.B. 75.000 Einträge enthalten. Dann benötigt alleine das Holen eines Iterators für eine Map eine Ewigkeit.

Wie kann ich das Ganze aus performancetechnischer Sicht verbessern? Oder komplett anders aufbauen?

Vielen Dank schon für's Lesen
Pascal
  Mit Zitat antworten Zitat