如何忽略长时间执行的 AWS Lambda 超时限制 300 秒?
How to ignore AWS Lambda timeout limit 300 seconds for long execution?
我在 AWS Lambda 中遇到超时问题 Node.js,默认超时时间为 300 秒。
我想从 S3 存储桶下载 zip
size>300MB
并在解压后上传到同一存储桶中的临时文件夹。
但是由于数据量大,我无法在时间间隔内完成此操作。
我可以使用 EBS,但想获得任何可以与 Lambda 函数一起使用的最接近的解决方案。
如果能得到相关的建议来完成这个任务就太好了。
这是我用 Lambda 函数写的东西。
exports.handler = (event, context, callback) => {
console.log('Received event for big file:', JSON.stringify(event, null, 2));
// Get the object from the event and show its content type
const bucket = event.Records[0].s3.bucket.name;
const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' '));
const params = {
Bucket: bucket,
Key: key,
};
s3.getObject(params, (err, data) => {
if (err) {
console.log('Error', err);
const message = `Error getting object ${key} from bucket ${bucket}. Make sure they exist and your bucket is in the same region as this function.`;
console.log(message);
callback(message);
} else {
console.log('Started to save buffers....');
JSZip.loadAsync(data.Body).then(function(zip) {
console.log('Started to extract files.....');
async.eachSeries(zip.files, function(item, cbk1) {
if (!item.dir) {
async.waterfall([function(cbk) {
zip.file(item.name).async("text").then(function(content) {
cbk(null, content)
})
}], function(err, content) {
s3.putObject({
Bucket: bucket,
Key: 'bigtemp/' + item.name.replace(/^.*[\\/]/, ''),
Body: content
}, function(err, result) {
if(result && result.ETag){
console.log('uploaded file: ', result.ETag);
}
console.log('Error ', err);
cbk1();
});
})
} else {
cbk1();
}
});
});
callback(null, data.ContentType);
}
});
};
超时由 AWS 强加,虽然它可能会在未来更改(这已经发生了两次 -- it is 15 minutes as of this writing。之前是 300 秒,从原始值 60 秒更新)今天不会帮助你。 Lambda 本身并不适用于长 运行 进程。
选项 1:通过在 Docker
中模拟 AWS Lambda 迁移到 ECS
存在将 lambda 函数移植到 ECS 的解决方案,而无需通过在 docker 容器中模拟 lambda 来重写函数。您可以使用 docker-lambda or node-docker-lambda 来模拟 docker 中的 lambda,然后您只需通过 runTask 传递事件。
如果您最终改变主意想要维护您的 lambda 函数,另一个示例使用 lambda 作为事件接收器并将大部分工作移至 ECS。
一些示例实现:
- Migrating Lambda to ECS - 使用 AWS Lambda docker 模拟器并通过 runTask 触发。
- lambda-ecs-worker-pattern - 使用 AWS Lambda 处理 S3 事件,并写入由 ECS worker 处理的 SQS 队列。
选项 2:AWS Step Functions
如果超时不是单个特定操作的瓶颈,您可以将其拆分为 AWS Step Functions,有效地将一个 lambda 转换为多个。因此,一个函数将调用 S3 getObject,另一个函数将处理压缩,另一个函数将调用 S3 putObject,等等以避开超时。我怀疑情况并非如此,但值得一提。
这是一个迟到的 post 但最近限制增加到 15 分钟。
我在 AWS Lambda 中遇到超时问题 Node.js,默认超时时间为 300 秒。
我想从 S3 存储桶下载 zip
size>300MB
并在解压后上传到同一存储桶中的临时文件夹。
但是由于数据量大,我无法在时间间隔内完成此操作。
我可以使用 EBS,但想获得任何可以与 Lambda 函数一起使用的最接近的解决方案。
如果能得到相关的建议来完成这个任务就太好了。
这是我用 Lambda 函数写的东西。
exports.handler = (event, context, callback) => {
console.log('Received event for big file:', JSON.stringify(event, null, 2));
// Get the object from the event and show its content type
const bucket = event.Records[0].s3.bucket.name;
const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' '));
const params = {
Bucket: bucket,
Key: key,
};
s3.getObject(params, (err, data) => {
if (err) {
console.log('Error', err);
const message = `Error getting object ${key} from bucket ${bucket}. Make sure they exist and your bucket is in the same region as this function.`;
console.log(message);
callback(message);
} else {
console.log('Started to save buffers....');
JSZip.loadAsync(data.Body).then(function(zip) {
console.log('Started to extract files.....');
async.eachSeries(zip.files, function(item, cbk1) {
if (!item.dir) {
async.waterfall([function(cbk) {
zip.file(item.name).async("text").then(function(content) {
cbk(null, content)
})
}], function(err, content) {
s3.putObject({
Bucket: bucket,
Key: 'bigtemp/' + item.name.replace(/^.*[\\/]/, ''),
Body: content
}, function(err, result) {
if(result && result.ETag){
console.log('uploaded file: ', result.ETag);
}
console.log('Error ', err);
cbk1();
});
})
} else {
cbk1();
}
});
});
callback(null, data.ContentType);
}
});
};
超时由 AWS 强加,虽然它可能会在未来更改(这已经发生了两次 -- it is 15 minutes as of this writing。之前是 300 秒,从原始值 60 秒更新)今天不会帮助你。 Lambda 本身并不适用于长 运行 进程。
选项 1:通过在 Docker
中模拟 AWS Lambda 迁移到 ECS存在将 lambda 函数移植到 ECS 的解决方案,而无需通过在 docker 容器中模拟 lambda 来重写函数。您可以使用 docker-lambda or node-docker-lambda 来模拟 docker 中的 lambda,然后您只需通过 runTask 传递事件。
如果您最终改变主意想要维护您的 lambda 函数,另一个示例使用 lambda 作为事件接收器并将大部分工作移至 ECS。
一些示例实现:
- Migrating Lambda to ECS - 使用 AWS Lambda docker 模拟器并通过 runTask 触发。
- lambda-ecs-worker-pattern - 使用 AWS Lambda 处理 S3 事件,并写入由 ECS worker 处理的 SQS 队列。
选项 2:AWS Step Functions
如果超时不是单个特定操作的瓶颈,您可以将其拆分为 AWS Step Functions,有效地将一个 lambda 转换为多个。因此,一个函数将调用 S3 getObject,另一个函数将处理压缩,另一个函数将调用 S3 putObject,等等以避开超时。我怀疑情况并非如此,但值得一提。
这是一个迟到的 post 但最近限制增加到 15 分钟。