Разделить файл S3 на более мелкие файлы по 1000 строк

У меня есть текстовый файл на S3 около 300 миллионов строк. Я хочу разбить этот файл на более мелкие файлы по 1000 строк каждый (с последним файлом, содержащим остаток), который я бы затем хотел поместить в другую папку или корзину на S3.

До сих пор я запускал это на своем локальном диске с помощью команды linux:

split -l 1000 file

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

Каков наиболее эффективный способ разделения этого файла S3, в идеале с использованием Python (в функции Lambda) или с помощью других команд S3? Это быстрее, чтобы просто запустить это на моем локальном диске?

2 ответа

Решение

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

Джон Ротенштейн привел вам пример использования локального диска в экземпляре EC2. Это дает преимущество работы в центрах обработки данных AWS, поэтому он получает высокоскоростное соединение, но имеет ограничения, которые: (1) вам нужно место на диске для хранения исходного файла и его частей, и (2) вам нужен экземпляр EC2 где вы можете сделать это.

Одна небольшая оптимизация состоит в том, чтобы избежать локальной копии большого файла, используя дефис в качестве места назначения s3 cp: это отправит вывод стандартному выводу, и вы можете затем передать его в split (здесь я также использую дефис, чтобы сказать split для чтения из стандартного ввода):

aws s3 cp s3://my-bucket/big-file.txt - | split -l 1000 - output.
aws s3 cp output.* s3://dest-bucket/

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

aws s3 cp s3://src-bucket/src-file - | split -b 1000 --filter 'aws s3 cp - s3://dst-bucket/result.$FILE' -

Итак, теперь вы устранили проблему локального хранилища, но остались с вопросом, где его запустить. Я бы порекомендовал AWS Batch, который может раскрутить экземпляр EC2 всего за время, необходимое для выполнения команды.

Конечно, вы можете написать скрипт Python для этого на Lambda, и это будет иметь преимущество в том, что он будет запускаться автоматически при загрузке исходного файла на S3. Я не очень знаком с Python SDK (boto), но похоже, что get_object будет возвращать тело исходного файла в виде потока байтов, который затем можно будет перебирать в виде строк, накапливая столько строк, сколько вы хотите в каждом выходном файле,

Ваш метод кажется правильным (скачать, разделить, загрузить).

Вы должны запускать команды из экземпляра Amazon EC2 в том же регионе, что и корзина Amazon S3.

Используйте интерфейс командной строки AWS (CLI) для загрузки / выгрузки файлов:

aws s3 cp s3://my-bucket/big-file.txt .

aws s3 cp --recursive folder-with-files s3://my-bucket/destination-folder/
Другие вопросы по тегам