«Если рабочий хочет хорошо выполнять свою работу, он должен сначала заточить свои инструменты» — Конфуций, «Аналитики Конфуция. Лу Лингун»
титульная страница > программирование > От Node.js к Go: увеличение загрузки тысяч файлов в одном ZIP-архиве

От Node.js к Go: увеличение загрузки тысяч файлов в одном ZIP-архиве

Опубликовано 24 августа 2024 г.
Просматривать:176

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

Как разработчики, мы часто сталкиваемся с проблемами при крупномасштабной обработке и доставке данных. В Kamero мы недавно устранили серьезное узкое место в нашем конвейере доставки файлов. Наше приложение позволяет пользователям загружать тысячи файлов, связанных с определенным событием, в виде одного zip-файла. Эта функция, основанная на функции Lambda на основе Node.js, отвечающей за выборку и сжатие файлов из корзин S3, столкнулась с ограничениями памяти и длительным временем выполнения по мере роста нашей пользовательской базы.

В этом посте подробно описан наш путь от ресурсоемкой реализации Node.js к экономичному и молниеносному решению Go, которое эффективно справляется с массовыми загрузками S3. Мы рассмотрим, как мы оптимизировали нашу систему, чтобы обеспечить пользователям удобство работы при запросе большого количества файлов с определенных событий, упакованных в один удобный архив для загрузки.

Вызов

Наша исходная функция Lambda столкнулась с несколькими критическими проблемами при обработке больших наборов файлов на основе событий:

  1. Потребление памяти: даже при наличии 10 ГБ выделенной памяти функция не будет работать при обработке 20 000 файлов для более крупных событий.
  2. Время выполнения: операции архивирования событий с многочисленными файлами выполнялись слишком долго, иногда время ожидания истекало до завершения.
  3. Масштабируемость: функция не могла эффективно справляться с растущей нагрузкой, что ограничивало наши возможности обслуживать пользователей большими наборами файлов с популярных событий.
  4. Пользовательский опыт: Медленная подготовка к загрузке влияла на удовлетворенность пользователей, особенно на мероприятиях с большим количеством файлов.

Реализация Node.js: краткий обзор

Наша первоначальная реализация использовала библиотеку s3-zip для создания zip-файлов из объектов S3. Вот упрощенный фрагмент того, как мы обрабатывали файлы:

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

// ... other code ...

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

await uploadZipFile(Upload_Bucket, zipfileKey, body);

Хотя этот подход работал, он загружал все файлы в память перед созданием zip-архива, что приводило к интенсивному использованию памяти и возможным ошибкам нехватки памяти для больших наборов файлов.

Enter Go: переписывание, меняющее правила игры

Мы решили переписать нашу функцию Lambda на Go, максимально используя ее эффективность и встроенные функции параллелизма. Результаты были ошеломляющими:

  1. Использование памяти: объем уменьшен с 10 ГБ до всего 100 МБ при той же рабочей нагрузке.
  2. Скорость: функция стала работать примерно в 10 раз быстрее.
  3. Надежность: успешно обрабатывает 20 000 файлов без проблем.

Ключевые оптимизации в реализации Go

1. Эффективные операции S3

Мы использовали AWS SDK для Go v2, который обеспечивает лучшую производительность и меньшее использование памяти по сравнению с v1:

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

2. Параллельная обработка

Горутины Go позволили нам обрабатывать несколько файлов одновременно:

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 



Этот подход позволяет нам обрабатывать несколько файлов одновременно, контролируя при этом уровень параллелизма, чтобы не перегружать систему.

3. Потоковое создание Zip

Вместо того, чтобы загружать все файлы в память, мы передаем содержимое zip-архива непосредственно на 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,
})

Такой подход потоковой передачи значительно снижает использование памяти и позволяет нам обрабатывать гораздо большие наборы файлов.

Результаты

Переписывание на Go привело к впечатляющим улучшениям:

  1. Использование памяти: уменьшено на 99 % (с 10 ГБ до 100 МБ)
  2. Скорость обработки: увеличена примерно на 1000 %
  3. Надежность: успешно обрабатывает 20 000 файлов без проблем
  4. Эффективность затрат: меньшее использование памяти и более быстрое время выполнения приводят к снижению затрат на AWS Lambda

Извлеченные уроки

  1. Выбор языка имеет значение: модель эффективности и параллелизма Go существенно изменила наш вариант использования.
  2. Определите свои узкие места: профилирование нашей функции Node.js помогло нам определить ключевые области для улучшения.
  3. Используйте облачные решения: использование AWS SDK для Go v2 и понимание возможностей S3 позволили улучшить интеграцию и повысить производительность.
  4. Думайте в потоках: обработка данных в виде потоков, а не загрузка всего в память, имеет решающее значение для крупномасштабных операций.

Заключение

Переписывание нашей лямбда-функции в Go не только решило наши непосредственные проблемы с масштабированием, но также предоставило более надежное и эффективное решение для наших потребностей в обработке файлов. Хотя Node.js поначалу сослужил нам хорошую службу, этот опыт подчеркнул важность выбора правильного инструмента для работы, особенно при решении масштабных ресурсоемких задач.

Помните, что лучший язык или фреймворк зависит от вашего конкретного варианта использования. В нашем сценарии характеристики производительности Go идеально соответствовали нашим потребностям, что привело к значительному улучшению пользовательского опыта и снижению эксплуатационных расходов.

Сталкивались ли вы с подобными проблемами при использовании бессерверных функций? Как вы их преодолели? Мы будем рады услышать о вашем опыте в комментариях ниже!

Заявление о выпуске Эта статья воспроизведена по адресу: https://dev.to/hiteshsisara/from-nodejs-to-go-supercharging-s3-downloads-of-thousands-of-files-as-a-single-zip-474b?1Если есть есть ли какие-либо нарушения, пожалуйста, свяжитесь с [email protected], чтобы удалить
Последний учебник Более>

Изучайте китайский

Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.

Copyright© 2022 湘ICP备2022001581号-3