Behandle eine große Anzahl von Dateien

8

Ich habe eine externe Festplatte mit einer Milliarde Dateien. Wenn ich die externe Festplatte in Computer A einbinde, durchsucht mein Programm den Pfad aller Dateien und speichert den Pfad der Dateien in einer Datenbanktabelle. Wenn ich dann die externe Festplatte austausche, bleiben diese Daten in der Tabelle. Das Problem ist, wenn einige Dateien auf dem Computer B gelöscht werden, und ich es erneut auf dem Computer A mount, muss ich die Datenbanktabelle in Computer A synchronisieren. Ich möchte jedoch nicht alle Dateien erneut scannen, weil es dauert viel Zeit und viel Zeit verschwenden. Gibt es eine Möglichkeit, die Datenbanktabelle zu aktualisieren, ohne alle Dateien zu durchsuchen und gleichzeitig den verwendeten Speicher zu minimieren?

Außerdem ist in meinem Fall die Speicherbegrenzung wichtiger als die Zeit. Das bedeutet, dass ich mehr Speicher sparen möchte, als mehr Zeit zu sparen.

Ich denke, ich kann die Dateien in viele Abschnitte schneiden und eine bestimmte Funktion verwenden (möglicherweise SHA1?), um zu überprüfen, ob die Dateien in diesem Abschnitt gelöscht werden. Ich kann jedoch keine Möglichkeit finden, die Dateien in die Abschnitte zu schneiden. Kann mir jemand helfen oder mir bessere Ideen geben?

    
s011208 21.05.2012, 06:37
quelle

4 Antworten

1

Wenn Sie keine Kontrolle über das Dateisystem auf der Festplatte haben, haben Sie keine andere Wahl, als die Dateinamen auf der gesamten Festplatte zu scannen. Um die gelöschten Dateien aufzulisten, könntest du folgendes tun:

%Vor%

Eine Lösung für das Db-Leistungsproblem könnte sein, dass die Dateinamen in einer Liste irgendeiner Art gesammelt werden und eine Masseneinfügung / Aktualisierung durchgeführt wird, wenn Sie beispielsweise 1000 Dateien erreichen.

Wie bei Verzeichnissen mit 1 Milliarde Dateien müssen Sie nur den Code, der die Dateien auflistet, durch etwas ersetzen, das die C-Funktionen opendir und readdir umschließt. Wenn ich es wäre, würdest du dir im Moment keine Sorgen machen. Keine vernünftige Person hat 1 Milliarde Dateien in einem Verzeichnis, weil solche Dinge Dateisysteme und gängige OS-Tools lahm legen, so dass das Risiko gering ist und die Lösung einfach ist.

    
Joni 21.05.2012 07:28
quelle
0

Theoretisch könnten Sie die Dinge beschleunigen, indem Sie "modifizierte" Zeitstempel in Verzeichnissen überprüfen. Wenn ein Verzeichnis nicht geändert wurde, müssen Sie keine Dateien in diesem Verzeichnis überprüfen. Leider müssen Sie mögliche Unterverzeichnisse scannen, und um sie zu finden, müssen Sie das Verzeichnis scannen ... es sei denn, Sie haben die Verzeichnisbaumstruktur gespeichert.

Und natürlich ist das kein Problem, Sie haben ein flaches Verzeichnis mit einer Milliarde Dateien.

Ich stelle mir vor, dass Sie alle Dateipfade im Speicher zusammenstellen, damit Sie sie sortieren können, bevor Sie die Datenbank abfragen. (Und sie zu sortieren ist eine gute Idee ...) Es gibt jedoch eine Alternative zum Sortieren im Speicher:

  1. Schreiben Sie die Dateipfade in eine Datei.
  2. Verwenden Sie ein externes Dienstprogramm zum Sortieren, um die Datei in die Reihenfolge der Primärschlüssel zu sortieren.
  3. Lesen Sie die sortierte Datei und führen Sie Batch-Abfragen für die Datenbank in Schlüsselreihenfolge durch.

(Haben Sie wirklich eine Milliarde Dateien auf einer Disc? Das klingt wie ein schlechtes Design für Ihren Datenspeicher ...)

    
Stephen C 21.05.2012 07:00
quelle
0

Haben Sie eine Liste, was gelöscht wird, wenn das Löschen stattfindet (oder ändern Sie den Prozess, der zum Erstellen gelöscht wird)? Wenn das nicht der Fall ist, können Sie eine Liste von "Ich wurde gelöscht" mit einem Zeitstempel erstellen und dann Elemente aus dieser Liste auswählen, um nur nach Änderungen zu synchronisieren. Natürlich möchten Sie immer noch eine Art Batch-Job haben, um während einer langsamen Zeit auf dem Server zu synchronisieren, aber ich denke, das könnte die Last reduzieren.

Eine andere Möglichkeit kann sein, je nachdem, was den Code ändert, dass der Prozess die Datenbanken (wenn Sie mehrere Knoten haben) nur beim Löschen direkt aktualisiert. Dies würde eine gewisse Kopplung in die Systeme einführen, wäre aber der effizienteste Weg, dies zu tun.

Die besten Möglichkeiten sind meines Erachtens einige Unterschiede in der Idee des Messaging, dass eine Löschung stattgefunden hat (auch wenn das nur eine Datei ist, in die man mit einer Liste kürzlich gelöschter Dateien schreibt), oder irgendeine Art von direktem Callback Mechanismus, entweder durch Code oder nur durch die Anpassung des persistenten Datenspeichers, den die Anwendung direkt aus dem Löschprozess verwendet.

Selbst wenn all dies gesagt ist, müssten Sie immer eine Art von Indexsynchronisierung oder periodische Plausibilitätsprüfung der Indizes durchführen, um sicherzustellen, dass alles korrekt übereinstimmt.

Sie könnten (und ich wäre schockiert, wenn Sie nicht auf der Anzahl der Dateien basieren müssten) den Dateibereich in Ordner mit zB 5.000-10.000 Dateien pro Ordner partitionieren und dann ein einfache Datei mit einem Hash der Namen aller Dateien im Ordner. Dies würde Löschungen fangen, aber ich denke immer noch, dass ein direkter Rückruf einer Form, wenn das Löschen auftritt, eine viel bessere Idee ist. Wenn Sie einen monolithischen Ordner mit all diesen Dingen haben, erstellen Sie etwas, um das in separate Ordner zu zerlegen (wir benutzen eine einfache Nummer unter dem Hauptordner, damit wir ad nauseum weitermachen können), sollte alles sehr beschleunigen; Selbst wenn Sie dies für alle neuen Dateien tun müssen und die alten Dateien so belassen, wie sie sind, könnten Sie zumindest das bluten beim Dateiabruf stoppen.

Da Sie programmatisch einen Index der Dateien steuern, sollten Sie meiner Meinung nach das gleiche Programm irgendwie (oder benachrichtigt) haben, wenn zum Zeitpunkt der Änderung des zugrunde liegenden Dateisystems Änderungen vorgenommen werden, anstatt Änderungen zuzulassen passieren und dann alles nach Updates durchsehen. Um die Ausreißer, bei denen diese Kommunikation unterbrochen wird, abzufangen, sollten Sie natürlich auch einen Synchronisationscode verwenden, um zu überprüfen, was sich im Dateisystem befindet, und den Index regelmäßig zu aktualisieren (obwohl dies möglicherweise zu der Hauptanwendung ausgelagert werden sollte) ).

    
Scott Taylor 05.07.2012 11:21
quelle
0

Wenn Speicher wichtig ist, würde ich für die Betriebssystem-Einrichtungen gehen.

Wenn Sie ext4 haben, nehme ich an, dass Sie auf Unix sind (Sie können es auf anderen Betriebssystemen wie Win installieren). Wenn dies der Fall ist, können Sie den Befehl native find verwenden (dies wäre für die letzte Minute, Sie können sich natürlich die letzte Scanzeit merken und diese nach Belieben ändern): find / directory_path -type f -mtime -1 -print

Natürlich werden Sie die Löschungen nicht haben. Wenn ein heuristischer Algorithmus für Sie funktioniert, können Sie einen Thread erstellen, der langsam zu jeder in Ihrer Datenbank gespeicherten Datei geht (was immer zuerst angezeigt werden muss, dann von neuer zu älter) und prüfen, ob dieser noch online ist. Dies wird nicht viel Speicher verbrauchen. Ich denke, dass Sie dem Benutzer sowieso keine Milliarden Dateien zeigen können.

    
mihaisimi 05.07.2012 11:52
quelle

Tags und Links