#amazon-s3 #aws-lambda
#amazon-s3 #aws-lambda
Вопрос:
В project необходимо обработать файл с записью в 50 КБ. Но, согласно текущей реализации AWS, размер полезной нагрузки ответа, возвращаемый функцией Lambda, не может превышать 6 МБ.
Кто-нибудь может помочь мне узнать, какие подходы / реализации я могу перенести сюда?
Лямбда-код:
@Override
public String handleRequest(S3Event event, Context context) {
String bucket = null;
String key = null;
String jsonStringFromCSV = null;
csvToJsonParser = new FileToJsonParserServiceImpl();
context.getLogger().log("Received event: " event);
try {
if (null != event.getRecords().get(0) amp;amp; event.getRecords().size() > 0) {
bucket = event.getRecords().get(0).getS3().getBucket().getName();
key = event.getRecords().get(0).getS3().getObject().getKey();
S3Object response = s3.getObject(new GetObjectRequest(bucket, key));
String contentType = response.getObjectMetadata().getContentType();
context.getLogger().log("CONTENT TYPE: " contentType);
InputStream objectData = response.getObjectContent();
BufferedReader bufferReader = new BufferedReader(new InputStreamReader(objectData, "UTF-8"));
jsonStringFromCSV = csvToJsonParser.getMemberObjectListAsJson(bufferReader);
}
return jsonStringFromCSV;
} catch (Exception e) {
e.printStackTrace();
context.getLogger().log(String.format("Error getting object %s from bucket %s. Make sure they exist and"
" your bucket is in the same region as this function.", key, bucket));
throw new RuntimeException(e);
}
}
Ответ №1:
Размер ответа здесь не проблема, поскольку вы уже используете S3, в конце концов, ваша функция будет выполняться асинхронно, и никакая другая система не сможет получить ее ответ напрямую (вы можете, однако, отправить ее ответ в SNS или SQS и позже обработать его, например).
Что вы можете сделать, чтобы добиться желаемого, так это чтобы ваш Lambda запускался событием S3. Затем вы должны обработать этот файл (однако это не может превышать 15 минут, поэтому, если ваш файл действительно огромен, то Lambda, возможно, не лучший инструмент здесь, но 50K записей — учитывая, что записи имеют длину всего пару (k) байт — должно быть нормально) и вывести его где-нибудь в другом месте (будь то DynamoDB, S3, RDS, SNS, SQS и т.д.).
Ограничение размера полезной нагрузки Lambda здесь определенно не является для вас ограничением.
РЕДАКТИРОВАТЬ: операционная система хочет где-нибудь сохранить строку, сгенерированную из файла CSV, поэтому вот один из способов добиться этого:
Вы могли бы сохранить эту большую строку JSON в файле в S3 без необходимости вызывать другой Lambda для выполнения задания. Короче говоря, ваша функция обработает файл CSV, сгенерирует из него строку, а затем сохранит ее в файле S3. Если вам нужно сохранить его в базе данных, вы могли бы использовать DynamoDB, но поскольку DDB имеет ограничения на размер объектов, вы могли бы просто создать атрибут в вашей таблице с именем processedFilePath, который указывает на ваш объект S3.
Если вы хотите немного разделить вещи, ваш исходный Lambda-файл мог бы сохранить файл в S3, вызвать {some_identifier}_processed.txt
и затем поместить сообщение в SQS с этим ключом (или использовать другое событие S3, но давайте использовать SQS, чтобы увидеть разные подходы). Затем вы могли бы подключить другой Lambda для обработки этого сообщения SQS и сохранить его в DynamoDB. Ваш объект в DynamoDB будет выглядеть следующим образом:
{
"id": "2511d862-53c1-48e2-beb4-ecc6c9deaac1",
"bucket": "my-processed-files-bucket",
"processedFileKey": "{some_identifier}_processed.txt"
}
Таким образом, вы можете обойти размеры полезной нагрузки как в Lambda, так и в DynamoDB и просто загрузить файл на основе processedFileKey
, когда это необходимо
Комментарии:
1. Я новичок в AWS. Работа, на которую я нацеливаюсь здесь, заключается в следующем: мой лямбда-код преобразует CSV-файл в строку Json. Как эта строка затем будет доставлена в другие лямбды AWS? Нужно ли мне повторно запускать строку из моего анализатора Lambda? Я добавил свой лямбда-код в качестве вложения.
2. Вы могли бы сохранить эту большую строку JSON в файле в S3 без необходимости вызывать другой Lambda для выполнения задания. Короче говоря, ваша функция обработает файл CSV, сгенерирует из него строку, а затем сохранит ее в файле S3. Если вам нужно сохранить его в базе данных, вы могли бы использовать DynamoDB, но поскольку DDB имеет ограничения на размер объектов, вы могли бы просто создать атрибут в своей таблице с именем
processedFilePath
, который указывает на ваш объект S3. Имеет ли это смысл для вас?3. Итак, если я использую приведенный выше код, который я реализовал, в конечном итоге будут установлены ограничения по размеру полезной нагрузки? верно? И для достижения этого я могу следовать одному из подходов, которые вы упомянули?
4. Я отредактировал свой ответ, чтобы показать, как вы могли бы этого достичь. Посмотрим, поможет ли это
5. Очень высокий уровень, прежде чем возвращать что-либо, вы бы сделали что-то вроде:
s3.putObject(myBucket, jsonStringFromCSV
) и затемsqs.putMessage(myQueue, jsonStringFromCSV)
. Lambda, прослушивающая очередь SQS, затем обработает его и сохранит в DynamoDB. Последний шаг, очевидно, необязателен, вы могли бы просто сохранить его в DynamoDB после сохранения нового файла в S3 без необходимости создавать очередь SQS или другой Lambda для обработки его сообщений, но я хотел показать, как вы могли бы его отключить.