Конкатенация файлов в S3 с использованием AWS Lambda
Есть ли способ использовать Lambda для конкатенации файлов S3?
У меня есть Firehose для потоковой передачи данных в S3 с самым длинным возможным интервалом (15 минут или 128 МБ), и поэтому у меня ежедневно 96 файлов данных, но я хочу объединить все данные в один ежедневный файл данных для максимальной производительности при чтении данных позже в Искре (EMR).
Я создал решение, в котором функция Lambda вызывается, когда Firehose передает новый файл в S3. Затем функция считывает (s3.GetObject) новый файл из исходного блока и объединенный файл ежедневных данных (если он уже существует с предыдущими ежедневными данными, в противном случае создает новый) из целевого сегмента, декодирует оба тела ответа в строку, а затем просто сложите их вместе и запишите в целевую корзину с помощью s3.PutObject (который перезаписывает предыдущий агрегированный файл).
Проблема заключается в том, что когда объем агрегированного файла достигает 150+ МБ, функция Lambda достигает предела памяти ~1500 МБ при чтении двух файлов, а затем завершается ошибкой.
В настоящее время у меня есть минимальный объем данных, с несколькими сотнями МБ в день, но этот объем будет расти в геометрической прогрессии в будущем. Для меня странно, что у Lambda такие низкие лимиты, и что они уже достигнуты с такими маленькими файлами.
Или каковы альтернативы объединения данных S3, в идеале вызванных событием, созданным объектом S3, или каким-либо образом запланированным заданием, например, запланированным ежедневно?
2 ответа
Вы можете создать лямбда-функцию, которая будет вызываться только один раз в день с использованием запланированных событий, а в вашей лямбда-функции вы должны использовать " Загрузка части - копирование", для которой не требуется загружать файлы с помощью лямбда-функции. Уже есть пример этого в этой теме
Я бы пересмотрел, действительно ли вы хотите сделать это:
- Стоимость S3 будет расти.
- Сложность трубопровода будет расти.
- Задержка от входа Firehose до входа Spark будет увеличиваться.
- В случае сбоя одного внедрения файла в Spark ( это произойдет в распределенной системе), вам придется перетасовать огромный файл, возможно, нарезать его, если внедрение не атомарное, загрузить его снова, и все это может занять очень много времени для большого количества данных., В этот момент вы можете обнаружить, что время восстановления настолько велико, что вам придется отложить следующую инъекцию…
Вместо этого, если это невозможно в данной ситуации, если вы сделаете файлы Firehose как можно меньше и сразу же отправите их в Spark:
- Вы можете архивировать объекты S3 практически сразу, что снижает затраты.
- Данные доступны в Spark как можно скорее.
- В случае сбоя одной закачки файла в Spark, остается меньше данных, которые нужно перетасовать, и если у вас есть автоматическое восстановление, это даже не будет заметно, если какая-либо система все время будет работать под полным наклоном (в этом случае массовая закачка будет еще хуже).
- При установке TCP-соединений и аутентификации наблюдается незначительное увеличение задержки.
Я не знаком со Spark конкретно, но в общем случае такое "канальное" решение будет включать:
- Периодический запуск или (что еще лучше) прослушиватель событий в выходном сегменте Firehose для обработки ввода как можно скорее.
- Инжектор / трансформатор для эффективного перемещения данных из S3 в Spark. Похоже, Паркет может помочь с этим.
- Действующий экземпляр Spark/EMR/ базового сервиса данных, готовый для получения данных.
- В случае базовой службы данных, какой-то способ создания нового кластера Spark для запроса данных по требованию.
Конечно, если невозможно сохранить данные Spark готовыми (но не запрашиваемыми ("запрашиваемыми"? Я не знаю)) за разумную сумму, это может быть не вариант. Также возможно, что ввод больших порций данных занимает очень много времени, но для готовой к выпуску системы это маловероятно.
Если вам действительно нужно разделить данные на ежедневные дампы, вы можете использовать многоэтапную загрузку. Для сравнения, мы делаем легкую обработку нескольких файлов в минуту (много ГБ в день) из Firehose без значительных накладных расходов.