Удивительно, но на веб-сайте AWS не так много документации, связанной с использованием AWS JavaScript SDK для загрузки данных в S3. В течение последней недели поиска документации, связанной с S3, мне казалось, что пользователи Node.js и JavaScript — нелюбимые дети в мире AWS 😅 Примером могут служить эти фрагменты кода для использования многокомпонентной загрузки для загрузки данных в S3.
В любом случае, я отвлекся на то, что мы нелюбимые дети в AWS.
Есть два основных способа загрузить большой объем данных в S3. Один из них — использовать потоковую передачу для открытия потока и непрерывной записи в S3, а другой — использовать многокомпонентную загрузку.
Супер простое резюме потоковой передачи и многокомпонентных загрузок. Потоковая передача — это конвейер данных, в котором я беру некоторые данные и мгновенно передаю их какому-то другому процессу для их обработки. Точно так же, как пекарь делает одно печенье, передает его мне, а я его ем 😋, но это происходит до тех пор, пока у пекаря не закончатся печенья или мой желудок не лопнет, в зависимости от того, что наступит раньше. Многокомпонентная загрузка — это способ загрузки множества фрагментов данных, а затем их агрегирования в S3. Каждый фрагмент данных называется Частью. Это как пекарь, который отправляет людей за ингредиентами для печенья. Каждому человеку назначается своя конкретная задача, например, получение масла, муки, яиц, пищевой соды и т. д. Когда каждый человек, наконец, приносит все ингредиенты пекарю (S3), пекарь может объединить все части, чтобы сделать большую партию. куки (наш конечный продукт).
Преимущества потоковой передачи:
- Не нужно заранее знать размер ваших данных, потому что вы можете продолжать запись в поток, пока поток не будет закрыт.
- Уменьшает объем данных, загружаемых в память, поскольку данные будут отправлены на S3.
- Относительно просто написать реализацию.
Преимущества многокомпонентной загрузки:
- Части многокомпонентной загрузки могут загружаться параллельно, что может значительно увеличить скорость загрузки данных. Например, если я хочу загрузить таблицу с 10 миллионами строк. Я мог бы иметь 10 процессов, каждый из которых принимает миллион строк и загружает их параллельно, что ускорило бы время загрузки в 10 раз по сравнению с одним процессом, пытающимся загрузить все 10 миллионов строк.
- Уменьшает объем данных, загружаемых в память, поскольку данные могут быть отправлены в S3. То же, что потоковое.
Некоторые минусы, которые я определенно ощутил при попытке использовать многокомпонентную загрузку:
- Мне нужно было точно знать размер каждой части, прежде чем я мог загрузить эту часть в S3. Это означало отсутствие произвольных данных, если только я не знал, как их разделить заранее, и мне нужно было рассчитать размер данных, которые я загружал, прежде чем я мог приступить к загрузке данных. Подробнее об этом во фрагменте кода многокомпонентной загрузки.
- Можно распараллелить работу для более быстрой загрузки, но не так просто написать реализацию, чтобы это действительно произошло.
Вы должны выбрать любую реализацию, которая лучше подходит для вашего варианта использования. Например, я загружал от 5 до 10 ГБ данных на S3 без каких-либо ограничений по времени, а это означает, что дополнительная сложность многокомпонентной загрузки в обмен на скорость не была необходима.
Другое решение v2 или v3
Еще один момент, который следует учитывать, — использовать AWS SDK для JavaScript v2 или v3. С точки зрения различий, версия 2 SDK — это огромный пакет SDK AWS, который содержит все, а версия 3 SDK — это более модульный пакет, который позволяет вам вносить только те фрагменты кода, которые вам нужны, из AWS SDK. Это означает, что вам не нужно использовать все инструменты DynamoDB, ML, AI и т. д., которые могут быть включены в SDK v2.
В моем личном опыте тестирования я наблюдал более высокое использование памяти для v3 SDK как для потоковой передачи, так и для многокомпонентной загрузки. Но мой вариант использования не будет таким же, как ваш, и другие сообщали о противоположной проблеме с v2 SDK, использующей больше памяти. Я бы порекомендовал попробовать оба подхода самостоятельно, чтобы принять решение, которое имеет смысл для вашего варианта использования!
Потоковая передача на S3 через v3 SDK
Давайте разберем, что происходит выше! Наш поток, который мы будем использовать для отправки данных, представляет собой поток узла stream.Passthrough
, который является просто причудливым способом сказать, что он действует как поток записи и чтения. Мы передаем этот поток как тело нашего потока S3 с необязательными параметрами, для которых установлены значения по умолчанию, указанные выше. Теперь в строке 23 вы можете написать любой код для записи данных в поток, пока вы не закончите запись данных и не закроете свой поток. Очень важно, чтобы вы не забыли закрыть свой поток, иначе ожидание в строке 26 никогда не закончится.
Также есть комментарий к строке 22, который мы рассмотрим чуть подробнее ниже.
Потоковая передача на S3 через v2 SDK
Как видите, версия v2 примерно такая же, как v3. Мало что изменилось, за исключением того, что вы используете метод загрузки непосредственно из библиотеки S3 вместо импортированной библиотеки lib-storage
.
Теперь причина, по которой v2 sdk не требует библиотеки lib-storage
, заключается в том, что метод upload() в v2 фактически возвращает экземпляр ManagedUpload, который обрабатывает все автоматическое разбиение данных на более мелкие части и тайно выполняет многокомпонентную загрузку в фоновом режиме.
Предупреждение о записи данных в поток
Запись данных в поток без прослушивания того, что хочет поток, может быть опасной. Это как пекарь, постоянно бросающий в меня печенье, когда я уже сыт и больше не могу есть. Это было бы нехорошо для моего кошелька или моего здоровья, так как печенье стоит 💰
Эта ситуация широко известна как противодавление, о котором в Node.js есть отличная статья, посвященная противодавлению. Обратное давление может иметь такие последствия, как высокий уровень сбора мусора, увеличение использования памяти до сбоя экземпляра Node.js, высокий RSS (размер резидентного набора). Это означает, что вам, вероятно, следует заботиться о том, что возвращает метод stream.write()
, и перестать писать, когда он говорит вам остановиться.
Многокомпонентная загрузка на S3 через v2 SDK
Для составных загрузок нужно выполнить несколько шагов.
- Создайте составную загрузку, которая означает для S3, что вы будете создавать составной процесс загрузки. S3, в свою очередь, вернет вам UploadId, который однозначно идентифицирует вашу составную загрузку и будет требоваться во всех используемых вами составных методах.
- Загрузить часть. Это отдельный фрагмент ваших данных, который при загрузке в S3 вернет значение ETag, которое однозначно идентифицирует эту часть.
- Завершите многокомпонентную загрузку с помощью UploadId, чтобы идентифицировать составную загрузку и ВСЕ ETag с их PartNumber, чтобы S3 мог определить, какие биты данных должны быть объединены и в каком порядке. В нашем примере выше у нас есть только 1 часть, поэтому мы помечаем нашу часть номером детали 1.
Загрузка части сопровождается определенными предостережениями и правилами, которых вы должны придерживаться.
- Каждая часть должна быть не менее 5 МБ, если это не последняя часть.
- Вы можете иметь не более 10 000 частей в одной многокомпонентной загрузке.
- Если вы хотите использовать абстрактный объем данных, такой как поток, вы должны указать, сколько байтов вы будете загружать в этой части. Если данные легко вычислить, как строку или объект, то S3 выполнит расчет за вас, но часть по-прежнему должна соответствовать правилу «Каждая часть должна быть не менее 5 МБ, если только это не последняя часть».
Кроме того, все многокомпонентные загрузки ДОЛЖНЫ быть завершены или прерваны. Если они не будут завершены или прерваны, у вас будут случайные части, плавающие в вашем S3, которые вы не можете видеть, которые будут занимать данные, которые 💰 для вас. Вот руководство по поиску и удалению этих плавающих частей для тех случаев, когда вы сначала тестируете и запутались.
Не стесняйтесь узнать больше о многостраничных загрузках здесь!
Я невключаю многокомпонентный код загрузки v3, потому что у меня его нет под рукой, но все методы s3 можно просто заменить их аналогами в v3 sdk. Обратитесь к документации SDK для библиотеки v3, чтобы найти те же методы в режиме v3.
Это все, что я узнал за последнюю неделю, играя с библиотекой S3! Я надеюсь, что это было полезно 😃потому что мне было трудно найти всю необходимую информацию 😆