AWS Lambda/ Aws Пакетный рабочий процесс
Я написал лямбду, которая запускается из корзины s3, чтобы распаковать zip-файл и обработать текстовый документ внутри. Из-за ограничения памяти лямбды мне нужно перенести процесс на что-то вроде пакета AWS. Поправьте меня, если я ошибаюсь, но мой рабочий процесс должен выглядеть примерно так.
Полагаю, мне нужно написать лямбду, чтобы поместить местоположение корзины s3 на амазонках. SQS, где пакет AWS может прочитать местоположение и выполнить всю распаковку / обработку данных, если их больше памяти.
Вот моя текущая лямбда, она принимает событие, вызванное корзиной s3, проверяет, является ли он zip-файлом, а затем отправляет имя этого ключа s3 в SQS. Должен ли я сказать пакету AWS начать чтение очереди здесь, в моей лямбде? Я совершенно новичок в AWS в целом и не уверен, что должен был пойти отсюда.
public class dockerEventHandler implements RequestHandler<S3Event, String> {
private static BigData app = new BigData();
private static DomainOfConstants CONST = new DomainOfConstants();
private static Logger log = Logger.getLogger(S3EventProcessorUnzip.class);
private static AmazonSQS SQS;
private static CreateQueueRequest createQueueRequest;
private static Matcher matcher;
private static String srcBucket, srcKey, extension, myQueueUrl;
@Override
public String handleRequest(S3Event s3Event, Context context)
{
try {
for (S3EventNotificationRecord record : s3Event.getRecords())
{
srcBucket = record.getS3().getBucket().getName();
srcKey = record.getS3().getObject().getKey().replace('+', ' ');
srcKey = URLDecoder.decode(srcKey, "UTF-8");
matcher = Pattern.compile(".*\\.([^\\.]*)").matcher(srcKey);
if (!matcher.matches())
{
log.info(CONST.getNoConnectionMessage() + srcKey);
return "";
}
extension = matcher.group(1).toLowerCase();
if (!"zip".equals(extension))
{
log.info("Skipping non-zip file " + srcKey + " with extension " + extension);
return "";
}
log.info("Sending object location to key" + srcBucket + "//" + srcKey);
//pass in only the reference of where the object is located
createQue(CONST.getQueueName(), srcKey);
}
}
catch (IOException e)
{
log.error(e);
}
return "Ok";
}
/*
*
* Setup connection to amazon SQS
* TODO - Find updated api for sqs connection to eliminate depreciation
*
* */
@SuppressWarnings("deprecation")
public static void sQSConnection() {
app.setAwsCredentials(CONST.getAccessKey(), CONST.getSecretKey());
try{
SQS = new AmazonSQSClient(app.getAwsCredentials());
Region usEast1 = Region.getRegion(Regions.US_EAST_1);
SQS.setRegion(usEast1);
}
catch(Exception e){
log.error(e);
}
}
//Create new Queue
public static void createQue(String queName, String message){
createQueueRequest = new CreateQueueRequest(queName);
myQueueUrl = SQS.createQueue(createQueueRequest).getQueueUrl();
sendMessage(myQueueUrl,message);
}
//Send reference to the s3 objects location to the queue
public static void sendMessage(String SIMPLE_QUE_URL, String S3KeyName){
SQS.sendMessage(new SendMessageRequest(SIMPLE_QUE_URL, S3KeyName));
}
//Fire AWS batch to pull from que
private static void initializeBatch(){
//TODO
}
Я установил Docker и понимаю образы Docker. Я считаю, что мой образ докера должен содержать весь код для чтения очереди, распаковки, обработки и установки файла в RDS в одном образе / контейнере докера.
Я ищу кого-то, кто сделал что-то подобное, что они могли бы поделиться, чтобы помочь. Что-то вроде:
Мистер S3: Эй, лямбда, у меня есть файл
Мистер Лямбда: Ладно, S3, я вижу вас, эй, вот вам пакет, вы могли бы распаковать и сделать что-нибудь с этим
Мистер Бэтч: Gotchya mr lambda, я позабочусь об этом и положу его в RDS или какую-нибудь базу данных после.
Я еще не написал образ класса / докера, но у меня есть весь код, сделанный для обработки / распаковки и запуска до конца. Лямбда просто ограничена памятью из-за того, что некоторые файлы имеют размер 1 Гб или больше.
1 ответ
Итак, после просмотра документов AWS в Batch вам не нужна очередь SQS. Пакетный режим имеет концепцию под названием "Очередь заданий", которая аналогична очереди SQS FIFO, но отличается тем, что эти очереди заданий имеют приоритеты, и задания внутри них могут зависеть от других заданий. Основной процесс:
- Сначала странная часть заключается в настройке ролей IAM, чтобы агенты контейнеров могли общаться со службой контейнеров, и пакет AWS может запускать различные экземпляры, когда это необходимо (есть также отдельная роль, необходимая для обнаружения экземпляров). Подробную информацию о необходимых разрешениях можно найти в этом документе (PDF) на странице 54.
- Теперь, когда это сделано, вы настраиваете вычислительную среду. Это экземпляры EC2 по требованию или спот, которые содержат ваши контейнеры. Рабочие места работают на уровне контейнера. Идея состоит в том, что ваша вычислительная среда - это максимальное выделение ресурсов, которое могут использовать ваши рабочие контейнеры. Как только этот предел достигнут, ваша работа должна ждать освобождения ресурсов.
- Теперь вы создаете очередь заданий. Это связывает задания с созданной вами вычислительной средой.
- Теперь вы создаете определение задания. Ну, технически вы не должны и можете делать это через лямбду, но это немного облегчает ситуацию. В вашем определении задания будет указано, какие ресурсы контейнера понадобятся для вашей работы (вы, конечно, можете переопределить это и в лямбде)
- Теперь, когда все это сделано, вы захотите создать лямбда-функцию. Это будет вызвано вашим событием S3 Bucket. Эта функция потребует необходимых разрешений IAM для запуска задания отправки в пакетном режиме (а также любых других разрешений). По сути, все, что нужно сделать лямбде, - это задание отправки вызова в пакет AWS. Основные параметры, которые вам нужны - это очередь заданий и определение задания. Вы также установите ключ S3 для почтового индекса, необходимого в качестве параметра для работы.
- Теперь, когда происходит соответствующее событие S3, он вызывает лямбду, которая затем отправляет задание в очередь пакетных заданий AWS. Тогда, предполагая, что установка прошла хорошо, она с удовольствием привлечет ресурсы для обработки вашей работы. Обратите внимание, что в зависимости от размера экземпляра EC2 и выделенных ресурсов контейнера это может занять немного времени (намного дольше, чем подготовка лямбда-функции).