ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

AWS Lambda 长任务支持 90 分钟超时:架构实战与成本选型指南

AWS Lambda 长任务支持 90 分钟超时:架构实战与成本选型指南 最近接到好几个朋友问同一件事 他们手里有一批跑三十分钟到一小时的数据清洗任务之前要么拆成一堆小任务用 Step Functions 串起来要么干脆把 Lambda 换成 ECS/Fargate 容器折腾半天成本还不低。问能不能用 AWS Lambda 直接跑完一整个长任务。我当时的答案还是Lambda 最多 15 分钟超过就别想了。结果没几天 AWS 就官宣了——Lambda 在 Lambda Managed Instances 执行环境上单次 function timeout 上限从 15 分钟直接拉到了 90 分钟。这个改动的意义比表面上看到的超时时间加长大得多它对 ETL、批量推理、报表生成、数据迁移这一类场景几乎是直接解绑。这篇我来把公告背后的细节、配置方法、成本变化、并发影响以及我实测过程中踩到的坑全部梳理一遍给准备上手的人一份能直接用的参考。1. 15分钟的上限是怎么来的为什么现在改成90分钟1.1 我绕开15分钟限制的折腾史先说背景。Lambda 刚出来那几年函数超时上限是 300 秒后来 AWS 在 2018 年把上限提到了 900 秒也就是 15 分钟。这个数字在过去六年里一直没动过AWS 官方在各个场合被问到能不能支持更长的执行时间回答基本都是没有计划。所以过去六年但凡遇到超过 15 分钟的任务大家的常规操作无非这几种把大任务按数据分片拆成几千个小 Lambda 调用每个跑几十秒最后做一次 merge用 Step Functions 把任务拆成多步靠状态机串联步骤之间来回传 payload直接把长任务搬到 Batch、ECS/Fargate 或者自建服务上Lambda 只做触发和回调利用 SQS 队列 定时触发做续跑跑不完就再塞回去继续这些方案都能用但架构复杂度是肉眼可见地涨。尤其当你只是想把一个 CSV 从三千行清洗成三千行、单线程跑也就二十来分钟的时候为了它去搭一套 Step Functions 状态机怎么看都像杀鸡用牛刀。1.2 这次公告到底说了什么AWS 这次是直接把 Lambda 的单次最大执行时间提到了 5400 秒也就是 90 分钟。不过注意不是所有 Lambda 函数都能自动获得这个上限前提是函数要跑在Lambda Managed Instances这种执行基础设施上。这个名词很多人第一次见。简单说Lambda Managed Instances 就是原先基于 Firecracker microVM 的那套执行环境的正式名称。AWS 在公告里做了两件事一是给这套环境改名二是把超时上限从 900 秒提升到 5400 秒。同一个公告里还提到LMI 环境的函数自动扩缩容到 1000 并发/分钟的部分不再单独收费稳态并发也免去了额外费用只是这些细节当时被 90 分钟这个数字盖过了风头。我的理解是AWS 之所以能放开 90 分钟是因为 LMI 这套基于 microVM 的隔离模型相对松耦合长跑任务不会像早期共享运行时那样把宿主机资源长时间占死。对用户来说最直接的感知就是以前最大 900 秒的限制基本被干掉了一批中等规模、运行时间在一个半小时以内的活儿可以原封不动留在 Lambda 里。官方说这功能在全部商业区域陆续上线。也就是说你现在去控制台把函数超时拉到 5400 秒如果没看到这个选项多半是区域还没同步或者函数还没完成迁移稍等或新建函数即可。2. Lambda Managed Instances执行基础设施改名背后的技术信号2.1 从Firecracker microVM到LMI到底差在哪很多人搞混一件事觉得Lambda Managed Instances是新出来的第三种运行模式。准确说它就是原来那套 Firecracker 微虚拟化执行环境的官方新名字再加上 90 分钟超时和新的扩缩容计费逻辑。Firecracker 的微 VM 模型是 AWS 从 2018 年就开始用的沙箱方案每个函数跑在一个极轻量的虚拟机里安全隔离性接近传统 VM但启动速度能达到毫秒级。这个模型最擅长的是短小精悍的请求型任务。后来 AWS 又推出了基于新运行时的执行环境两者在冷启动、扩缩容、支持的配置项上略有差异。现在 AWS 把老的这套命名为 LMI有点老骥伏枥、转正上岗的味道说明 AWS 并不打算让这套环境慢慢退场反而要延长它的生命周期扩大它的适用场景。对使用者来说这个改名的信号是你不需要改变现有的函数代码、部署方式或事件源映射只要函数跑在 LMI 上以前所有基于 Firecracker 的配置和限制基本不变只是上限放宽了。2.2 超时时间变了哪些机制没变很多人会问90 分钟超时了那计费、并发、重试这些东西变了吗我目前实测下来核心机制基本没变计费方式不变还是按 GB-秒计费也就是说跑的时间越长账单自然越高。90 分钟只是允许你跑不是免费让你跑。并发模型不变每个并发执行依旧占用一个并发槽位长任务占着槽位不放对并发配额是实打实的消耗。重试策略不变异步调用的默认重试仍然是两次失败事件依旧走死信队列或失败目的地。冷启动机制不变90 分钟的超时不会延长初始化阶段的时间预算Init 阶段依然是那套规则。不变的部分反而更重要。因为很多人脑子里只有超时上限变大了这一个信息容易忽略并发槽位、账单监控、调用方超时这些配套问题。后面我会专门写一节。3. 实操把函数的超时时间改成90分钟3.1 控制台改法如果只是想赶紧试一把控制台操作非常简单打开 Lambda 控制台进入目标函数详情页左侧选择Configuration配置找到General configuration通用配置点 Edit把 Timeout 从原来的比如 5 分钟拖到 90 分钟或者直接输入 5400 秒保存函数就会用新的上限。有一点我想提醒如果编辑页面里的超时上限仍然只能填到 900说明这个函数目前不在 LMI 执行环境上或者还停留在旧版基础设施。这时候不要硬搜为什么我的控制台没有 90 分钟先确认函数是否被 AWS 后台自动迁移到了 LMI。AWS 当时说的是会逐步把兼容函数自动迁移到 LMI但你可能刚好在迁移队列末尾。3.2 CLI改法与验证命令行方式更适合批量操作和自动化脚本。更新单个函数的超时时间用update-function-configurationaws lambda update-function-configuration \ --function-name my-long-etl-job \ --timeout 5400更新完验证一下是否生效aws lambda get-function-configuration \ --function-name my-long-etl-job \ --query Timeout如果输出5400就说明配置完成。需要提醒的是update-function-configuration只改配置不改代码函数版本也会生成新的版本记录。如果你要批量改多个函数建议写个小循环把所有函数名放进一个文本文件里逐行执行更新最好加上超时时间的参数校验避免手误把 5400 填成 540。3.3 改之前先确认执行环境与区域可用性这是我觉得最容易被坑的一步。光把 Timeout 改成 5400 不代表一定能跑 90 分钟前提条件是这个函数真的跑在 LMI 上且区域支持。我的建议是直接在控制台看是否出现 5400 的上限选项这是最直观的判断查看函数创建时间。AWS 的自动迁移是按批次来的新创建的函数默认就会用 LMI老函数可能要等迁移如果函数还是旧环境又急着用我的经验是直接另建一个新函数把代码和配置迁过去通常比干等迁移快得多使用中国以外区域的时候留意区域的公告状态因为这种级别的基础架构升级通常是分批上线的。另外函数的architectures参数x86_64 还是 arm64不影响 90 分钟超时选 Graviton 还是 x86 只看性能和成本偏好即可。4. 90分钟能解什么局不能解什么局4.1 适合直接迁移的六类任务90 分钟这个窗口覆盖了一大批不上不下的任务类型。我按自己经验和社区反馈整理了六类中量级 ETL 管道从 RDS、S3 里拉几百万行数据做清洗、转换、聚合写回结果表或数据湖。以前这种任务最容易踩 15 分钟红线现在单次跑完不用拆。ML 批量推理小批次模型推理、特征工程、Embedding 生成。尤其是调用第三方推理 API 时大批量请求可能需要几十分钟Lambda 90 分钟刚好能同步完成。PDF/报表批量生成生成几百份合同、月报、发票每份几秒串行下来半小时到一小时很常见。数据迁移与回填给数据库加索引、按条件刷历史数据、把旧表数据迁移到新结构。这种任务天然不是实时请求非常适合长超时。日志压缩与归档把分散在多个 S3 前缀的日志做压缩、合并、分区重排跑完再触发下游分析。爬虫与采集任务站点数量中等、单站耗时可控的批量抓取90 分钟可以覆盖一个完整批次。这类任务的共同点运行时间在 10 到 90 分钟之间不需要人工介入失败可以重跑且能接受异步执行。完美匹配 Lambda 的事件驱动模型。4.2 别被90分钟忽悠的场景有些场景虽然 Lambda 现在能跑 90 分钟但不代表你应该让它跑实时 API 请求就算函数能跑 90 分钟API Gateway 的最大集成超时是 29 秒应用负载均衡的闲置超时默认 60 秒这些前置组件根本等不到函数跑完。所以把耗时的 HTTP 请求直接放进 Lambda依旧是错误用法该拆异步还是得拆异步。超过 90 分钟的重型任务比如上千个文件的视频转码、几 TB 数据的全量迁移、模型训练。这类任务别硬塞 LambdaBatch 和 ECS/Fargate 有按小时甚至按天计算的能力容器里的资源控制也更灵活。需要人审的长时间审批流程Step Functions 工作流的执行时长可以到一年还能实现等待人类确认这种编排需求不是单靠 Lambda 超时能解决的。我自己的判断标准很简单任务有多长如果超过 90 分钟或者需要编排多个步骤、有等待条件直接上 Step Functions 或 Batch如果任务在 90 分钟以内、不需要人参与、失败可重试Lambda 现在就是最省事的选择。4.3 成本粗算90 分钟除了能不能跑大家最关心的是跑得起吗。Lambda 计费是 GB-秒也就是内存大小乘执行时间。用 1GB 内存跑 90 分钟5400 秒 × 1GB 5400 GB-秒按目前的按量价格大约 0.0000166667 美元/GB-秒大概 0.09 美元用 8GB 内存跑 90 分钟大约是 0.72 美元。换句话说一个哪怕每天跑几十次的中等长任务在成本上是完全可控的。不过这只算了 Lambda 执行费用没算 S3 读写、日志、数据库连接等外部费用。长任务跑得久日志量和外部 API 调用量都会上来这些要单独评估。5. 并发、配额和下游依赖长任务最容易忽视的三件事5.1 并发槽位才是真正的瓶颈这是我觉得 90 分钟超时最容易被低估的地方。函数超时从 15 分钟变 90 分钟单个函数占用的并发资源时间就变成了原来的 6 倍。假设你的函数有 100 的预留并发那么同一时刻最多只能同时跑 100 个 90 分钟任务。如果你的队列里积压了 1000 个任务每个跑 40 分钟实际吞吐量取决于并发槽位数和任务时长的组合而不是90 分钟超时很宽裕。计算方式我一般这样用单槽位每小时吞吐 3600 秒 / 单任务平均执行时间 总吞吐 并发槽位数 × 单槽位每小时吞吐举个例子并发配额 50任务平均执行 30 分钟那么每小时最多完成 50 × 2 100 个任务。如果任务平均执行时间也拉长到 80 分钟那每小时就只有约 37 个。所以决定要不要上 90 分钟先算一下任务时长分布和并发预算别到时候大量请求被 Throttle429打回来。5.2 存储、内存和临时资源长任务通常会积攒临时数据。Lambda 的/tmp目录默认只有 512MB最多可以配到 10GB。跑 40 分钟的 ETL 任务如果中间结果都往/tmp里写512MB 很容易爆。我建议凡是时长超过 15 分钟的任务把临时目录大小至少配到 2GB 以上并且养成定时清理的习惯。内存方面也别光盯着超时。函数内存越大CPU 和网络带宽也越大长任务的执行速度会明显变快。有时候跑得快比能跑 90 分钟更重要一个 8GB 内存、35 分钟跑完的任务可能比 1GB 内存、80 分钟跑完的任务总成本还低。如果时间预算充足可以在测试环境用不同内存配置跑一遍画出一条内存-耗时-成本曲线再定。5.3 下游API和数据库连接的超时函数能跑 90 分钟不代表下游服务能陪你等 90 分钟。我遇到过数据库连接池在函数长时间执行时被数据库侧断开的情况也遇到过下游 HTTP 服务在 30 秒无响应时主动断开连接。长任务最好遵循三步走外部 HTTP 调用的客户端超时时间显式设大至少大于单次调用的预期耗时数据库连接开启自动重连或连接池校验避免空闲连接被踢掉后还在用对长时间运行的任务在代码里加入周期性心跳或进度日志这样即使下游断开也能通过日志定位卡点而不是面对一片寂静。6. 五个我实测踩过的坑和对应解法6.1 坑一调用方客户端超时把 Lambda 函数超时改成 90 分钟之后我第一次测试直接翻车原因不是函数本身而是调用方。Lambda 的 SDK 客户端默认请求超时普遍在 30 到 60 秒我用同步 Invoke 去调用一个跑了 40 分钟的函数客户端在 60 秒左右直接报错但函数还在后台继续跑。解法分两种如果不需要等结果用异步调用InvocationTypeEvent函数执行完走目的地配置通知如果确实需要同步拿结果就必须把 SDK 客户端的 socket 超时和 read 超时都改成大于 5400 秒或者干脆自己做一个提交任务 轮询结果的模式。我实测下来异步 事件通知最省心同步轮询适合调用方本身也是长期运行的 Worker。6.2 坑二前置网络链路超时第二个坑是测试环境走了 Application Load Balancer。假设 Lambda 的 90 分钟没问题但 ALB 默认的闲置超时只有 60 秒连接一旦闲置就会被断开。API Gateway 的集成超时更是只有 29 秒根本不可能让用户在线等一个跑 40 分钟的函数。解法不是去调 ALB 超时而是把架构改成异步请求进来先返回一个任务 IDLambda 在后台慢慢跑前端轮询任务状态或等 S3 结果文件。函数长超时解决的是后台执行的窗口而不是用户同步等待的窗口这两个概念一定要分开。6.3 坑三监控报警误报很多团队在 Lambda 上配过函数执行时间超过 15 分钟就报警的规则用来抓异常慢的函数。现在函数合法执行时间拉长到 90 分钟老规则会狂报警一天几百条告警最终结果就是狼来了没人看。我建议做一次全面的告警规则审计把运行时间上限类告警改成基于基线的动态阈值比如超过过去 7 天 P95 执行时间的 3 倍才报警对已知的长任务函数单独建告警规则不共用短任务的规则告警信息里加上函数名和任务类型标签方便判断是不是预期行为。6.4 坑四失败重试与幂等长任务跑了 70 分钟后失败这种痛我太熟悉了。Lambda 异步调用默认重试两次也就是说失败后还会自动再跑两遍。如果函数逻辑没有幂等性每重试一次就多写一批重复数据、多发一批邮件、多扣一次下游 API 费用。幂等设计在短任务里是最佳实践在长任务里就是免死金牌。我现在的做法是每个任务分配唯一 ID通过环境变量或事件 payload 传入数据库写入用唯一键约束重复执行相同任务 ID 直接跳过外部副作用操作发邮件、调支付、写第三方之前先查任务状态执行完立刻标记完成失败时把任务 ID、进度、堆栈全部打进日志和失败目的地方便人工介入。6.5 坑五账单失控90 分钟超时解放了任务长度也放大了失控成本。如果一个函数因为代码 bug 进入死循环以前 15 分钟就会被强行终止现在最多能跑 90 分钟账单也随之拉长。我现在的底线配置是给函数设置合理的超时值不要一上来就填 5400。大部分任务的 P99 执行时间可能只要 20 分钟那就填 25 分钟留点余量就行没必要给所有函数开 90 分钟给账户设置预算告警特别是 Lambda 相关的 Cost Allocation Tag开启 CloudWatch 的 Lambda Insights 或自定义埋点监控每次调用的实际执行时间分布如果出现大批量贴边跑的调用说明任务量估算有问题。6.6 坑六事件源轮询与批量窗口的配合最后一个坑发生在使用 SQS、Kinesis 或 DynamoDB Streams 作为事件源的时候。事件源映射的批处理窗口和函数执行时间是两套独立机制函数在长跑期间事件源映射会停止拉取新消息但队列里的消息会持续积压如果可见性超时设置小于函数执行时间消息可能在函数还没处理完时就再次变为可见被另一个并发实例重复消费。解法是把队列的 visibility timeout 设置为函数最大执行时间的至少 6 倍取整到秒或者更稳妥地用函数执行时间 重试时间作为 visibility timeout 的计算基准。流类事件源的迭代器老化问题也一样长任务处理批次时间长可能导致某个分片长时间没有 checkpoint触发迭代器超龄告警。这时候要么调大迭代器最大老化时间要么减少单个批次的数据量让函数尽快交还分片。7. 我自己的选型判断和个人体会这段没有大道理纯分享我最近几个项目的处理方式。第一个项目是客户的历史订单数据回填总共 400 万条记录需要调用第三方风控接口逐条打分每个接口调用约 300 毫秒。串行跑完大约 33 小时这明显超过 90 分钟直接用 Batch 或 Step Functions 分布式跑。但如果客户的数据量缩到 60 万条串行 5 小时我会拆成 6 到 8 个并发 Lambda每个跑 40 分钟左右90 分钟超时刚好够用成本还比容器低。第二个项目是内部报表系统每天凌晨生成一百多份 PDF以前要切成四批用 Step Functions 串联现在直接一个 Lambda 在 90 分钟内跑完代码更简单排错也更容易。那个 Step Functions 状态机直接下线了。第三个项目是某次数据平台迁移我评估后认为迁移脚本单次跑 50 分钟但需要重试和断点续跑最后选了 Lambda S3 存储 checkpoint 手动重跑的方式没有引入任何常驻服务。这种能少一个系统就少一个系统的做法在运维资源有限的小团队里价值很大。90 分钟超时本质上给 Lambda 划了一条新边界一个半小时以内的、可自动重试的、无人工介入的批处理任务都可以考虑留在 Lambda 里。至于超过这个范围的该用 Step Functions 编排就用 Step Functions该上 Batch/ECS 就上不必拘泥于全都上 Lambda。我在实际使用中最深刻的体会是超时放宽之后真正的架构决策点从能不能跑变成了跑多久最划算、失败怎么办、下游扛不扛得住。把这些想清楚你才能真正吃透这次升级不然只是把一个 15 分钟的炸弹换成了 90 分钟的炸弹爆炸前摇更长而已。
返回列表