Als Entwickler stehen wir oft vor Herausforderungen, wenn es um die Verarbeitung und Bereitstellung umfangreicher Daten geht. Bei Kamero haben wir kürzlich einen erheblichen Engpass in unserer Dateibereitstellungspipeline behoben. Unsere Anwendung ermöglicht es Benutzern, Tausende von Dateien, die mit einem bestimmten Ereignis verknüpft sind, als eine einzige ZIP-Datei herunterzuladen. Diese Funktion, die von einer Node.js-basierten Lambda-Funktion unterstützt wird, die für das Abrufen und Komprimieren von Dateien aus S3-Buckets verantwortlich ist, hatte mit Speicherbeschränkungen und langen Ausführungszeiten zu kämpfen, als unsere Benutzerbasis wuchs.
Dieser Beitrag beschreibt unseren Weg von einer ressourcenhungrigen Node.js-Implementierung zu einer schlanken und blitzschnellen Go-Lösung, die massive S3-Downloads effizient verarbeitet. Wir werden untersuchen, wie wir unser System optimiert haben, um Benutzern ein nahtloses Erlebnis zu bieten, wenn sie eine große Anzahl von Dateien von bestimmten Ereignissen anfordern, alles verpackt in einem praktischen einzigen Zip-Download.
Unsere ursprüngliche Lambda-Funktion hatte bei der Verarbeitung großer ereignisbasierter Dateisätze mehrere kritische Probleme:
Unsere ursprüngliche Implementierung nutzte die s3-zip-Bibliothek, um ZIP-Dateien aus S3-Objekten zu erstellen. Hier ist ein vereinfachter Ausschnitt davon, wie wir Dateien verarbeitet haben:
const s3Zip = require("s3-zip"); // ... other code ... const body = s3Zip.archive( { bucket: bucketName }, eventId, files, entryData ); await uploadZipFile(Upload_Bucket, zipfileKey, body);
Obwohl dieser Ansatz funktionierte, wurden alle Dateien vor dem Erstellen der ZIP-Datei in den Speicher geladen, was zu einer hohen Speicherauslastung und potenziellen Fehlern wegen unzureichendem Arbeitsspeicher bei großen Dateisätzen führte.
Wir haben uns entschieden, unsere Lambda-Funktion in Go neu zu schreiben und dabei deren Effizienz und integrierte Parallelitätsfunktionen zu nutzen. Die Ergebnisse waren verblüffend:
Wir haben das AWS SDK for Go v2 verwendet, das im Vergleich zu v1 eine bessere Leistung und eine geringere Speichernutzung bietet:
cfg, err := config.LoadDefaultConfig(context.TODO()) s3Client = s3.NewFromConfig(cfg)
Gos Goroutinen ermöglichten es uns, mehrere Dateien gleichzeitig zu verarbeiten:
var wg sync.WaitGroup sem := make(chan struct{}, 10) // Limit concurrent operations for _, photo := range photos { wg.Add(1) go func(photo Photo) { defer wg.Done() sem <- struct{}{} // Acquire semaphore defer func() { <-sem }() // Release semaphore // Process photo }(photo) } wg.Wait()
Dieser Ansatz ermöglicht es uns, mehrere Dateien gleichzeitig zu verarbeiten und gleichzeitig den Grad der Parallelität zu kontrollieren, um eine Überlastung des Systems zu verhindern.
Anstatt alle Dateien in den Speicher zu laden, streamen wir den ZIP-Inhalt direkt an S3:
pipeReader, pipeWriter := io.Pipe() go func() { zipWriter := zip.NewWriter(pipeWriter) // Add files to zip zipWriter.Close() pipeWriter.Close() }() // Upload streaming content to S3 uploader.Upload(ctx, &s3.PutObjectInput{ Bucket: &destBucket, Key: &zipFileKey, Body: pipeReader, })
Dieser Streaming-Ansatz reduziert die Speichernutzung erheblich und ermöglicht uns die Verarbeitung viel größerer Dateimengen.
Die Neufassung von Go lieferte beeindruckende Verbesserungen:
Das Umschreiben unserer Lambda-Funktion in Go hat nicht nur unsere unmittelbaren Skalierungsprobleme gelöst, sondern auch eine robustere und effizientere Lösung für unsere Dateiverarbeitungsanforderungen bereitgestellt. Während Node.js uns anfangs gute Dienste leistete, verdeutlichte diese Erfahrung, wie wichtig es ist, das richtige Tool für die jeweilige Aufgabe auszuwählen, insbesondere bei der Bewältigung ressourcenintensiver Aufgaben im großen Maßstab.
Denken Sie daran, dass die beste Sprache oder das beste Framework von Ihrem spezifischen Anwendungsfall abhängt. In unserem Szenario stimmten die Leistungsmerkmale von Go perfekt mit unseren Anforderungen überein, was zu einer deutlich verbesserten Benutzererfahrung und geringeren Betriebskosten führte.
Stehten Sie mit serverlosen Funktionen vor ähnlichen Herausforderungen? Wie haben Sie sie überwunden? Wir würden gerne von Ihren Erfahrungen in den Kommentaren unten hören!
Das obige ist der detaillierte Inhalt vonVon Node.js bis hin zu Go: Laden Sie Tausende von Dateien in einer einzigen Zip-Datei auf. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!