Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Dari Node.js ke Go: Mengecas Super Beban Tabur Beribu-ribu Fail sebagai Zip Tunggal

Dari Node.js ke Go: Mengecas Super Beban Tabur Beribu-ribu Fail sebagai Zip Tunggal

WBOY
WBOYasal
2024-08-21 12:32:40820semak imbas

From Node.js to Go: Supercharging Sownloads of Thousands of Files as a Single Zip

Sebagai pembangun, kami sering menghadapi cabaran apabila berurusan dengan pemprosesan dan penghantaran data berskala besar. Di Kamero, baru-baru ini kami telah menangani kesesakan yang ketara dalam saluran penghantaran fail kami. Aplikasi kami membolehkan pengguna memuat turun beribu-ribu fail yang dikaitkan dengan acara tertentu sebagai fail zip tunggal. Ciri ini, dikuasakan oleh fungsi Lambda berasaskan Node.js yang bertanggungjawab untuk mengambil dan mengezip fail daripada baldi S3, bergelut dengan kekangan memori dan masa pelaksanaan yang panjang apabila pangkalan pengguna kami berkembang.

Siaran ini memperincikan perjalanan kami daripada pelaksanaan Node.js yang haus sumber kepada penyelesaian Go yang ramping dan sepantas kilat yang mengendalikan muat turun S3 secara besar-besaran dengan cekap. Kami akan meneroka cara kami mengoptimumkan sistem kami untuk memberikan pengguna pengalaman yang lancar apabila meminta sejumlah besar fail daripada acara tertentu, semuanya dibungkus ke dalam muat turun zip tunggal yang mudah.

Cabaran

Fungsi Lambda asal kami menghadapi beberapa isu kritikal semasa memproses set fail berasaskan acara yang besar:

  1. Penggunaan Memori: Walaupun dengan 10GB memori yang diperuntukkan, fungsi ini akan gagal apabila memproses 20,000+ fail untuk acara yang lebih besar.
  2. Masa Pelaksanaan: Operasi zip untuk acara dengan banyak fail mengambil masa terlalu lama, kadangkala tamat masa sebelum selesai.
  3. Skalabiliti: Fungsi tidak dapat mengendalikan beban yang semakin meningkat dengan cekap, mengehadkan keupayaan kami untuk melayani pengguna dengan set fail besar daripada acara popular.
  4. Pengalaman Pengguna: Masa penyediaan muat turun perlahan memberi kesan kepada kepuasan pengguna, terutamanya untuk acara dengan jumlah fail yang banyak.

Pelaksanaan Node.js: Pandangan Pantas

Pelaksanaan asal kami menggunakan perpustakaan s3-zip untuk mencipta fail zip daripada objek S3. Berikut ialah coretan ringkas tentang cara kami memproses fail:

const s3Zip = require("s3-zip");

// ... other code ...

const body = s3Zip.archive(
  { bucket: bucketName },
  eventId,
  files,
  entryData
);

await uploadZipFile(Upload_Bucket, zipfileKey, body);

Semasa pendekatan ini berfungsi, ia memuatkan semua fail ke dalam memori sebelum mencipta zip, membawa kepada penggunaan memori yang tinggi dan kemungkinan ralat kehabisan memori untuk set fail yang besar.

Masukkan Go: Penulisan Semula yang Mengubah Permainan

Kami memutuskan untuk menulis semula fungsi Lambda kami dalam Go, memanfaatkan kecekapannya dan ciri konkurensi terbina dalam. Hasilnya sangat mengagumkan:

  1. Penggunaan Memori: Dikurangkan daripada 10GB kepada 100MB sahaja untuk beban kerja yang sama.
  2. Kelajuan: Fungsi menjadi kira-kira 10 kali lebih pantas.
  3. Kebolehpercayaan: Berjaya memproses 20,000+ fail tanpa masalah.

Pengoptimuman Utama dalam Pelaksanaan Go

1. Operasi S3 yang cekap

Kami menggunakan AWS SDK untuk Go v2, yang menawarkan prestasi yang lebih baik dan penggunaan memori yang lebih rendah berbanding v1:

cfg, err := config.LoadDefaultConfig(context.TODO())
s3Client = s3.NewFromConfig(cfg)

2. Pemprosesan Serentak

Gorutin Go membolehkan kami memproses berbilang fail serentak:

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()

Pendekatan ini membolehkan kami memproses berbilang fail secara serentak sambil mengawal tahap konkurensi untuk mengelakkan sistem yang melampau.

3. Penstriman Penciptaan Zip

Daripada memuatkan semua fail ke dalam memori, kami menstrim kandungan zip terus ke 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,
})

Pendekatan penstriman ini mengurangkan penggunaan memori dengan ketara dan membolehkan kami mengendalikan set fail yang lebih besar.

Hasilnya

Penulisan semula kepada Go memberikan peningkatan yang mengagumkan:

  1. Penggunaan Memori: Dikurangkan sebanyak 99% (dari 10GB kepada 100MB)
  2. Kelajuan Pemprosesan: Meningkat lebih kurang 1000%
  3. Kebolehpercayaan: Berjaya mengendalikan 20,000+ fail tanpa masalah
  4. Kecekapan Kos: Penggunaan memori yang lebih rendah dan masa pelaksanaan yang lebih pantas menyebabkan kos AWS Lambda berkurangan

Pengajaran

  1. Pemilihan Bahasa Penting: Kecekapan dan model keselarasan Go membuat perbezaan besar dalam kes penggunaan kami.
  2. Fahami Kesesakan Anda: Memprofilkan fungsi Node.js kami membantu kami mengenal pasti bahagian utama untuk penambahbaikan.
  3. Manfaatkan Penyelesaian Cloud-Native: Menggunakan AWS SDK for Go v2 dan memahami keupayaan S3 yang dibenarkan untuk penyepaduan dan prestasi yang lebih baik.
  4. Fikirkan dalam Strim: Memproses data sebagai strim dan bukannya memuatkan segala-galanya ke dalam memori adalah penting untuk operasi berskala besar.

Kesimpulan

Menulis semula fungsi Lambda kami dalam Go bukan sahaja menyelesaikan isu penskalaan segera kami tetapi juga menyediakan penyelesaian yang lebih mantap dan cekap untuk keperluan pemprosesan fail kami. Walaupun Node.js memberi perkhidmatan yang baik kepada kami pada mulanya, pengalaman ini menyerlahkan kepentingan memilih alat yang sesuai untuk tugas itu, terutamanya apabila menangani tugasan intensif sumber secara berskala.

Ingat, bahasa atau rangka kerja terbaik bergantung pada kes penggunaan khusus anda. Dalam senario kami, ciri prestasi Go diselaraskan dengan sempurna dengan keperluan kami, menghasilkan pengalaman pengguna yang bertambah baik dengan ketara dan mengurangkan kos operasi.

Pernahkah anda menghadapi cabaran yang sama dengan fungsi tanpa pelayan? Bagaimana anda mengatasi mereka? Kami ingin mendengar tentang pengalaman anda dalam ulasan di bawah!

Atas ialah kandungan terperinci Dari Node.js ke Go: Mengecas Super Beban Tabur Beribu-ribu Fail sebagai Zip Tunggal. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn