AWS Lambda读取SQS FIFO队列未遵循批量大小1的问题排查
我配置了一个从SQS FIFO队列读取消息的AWS Lambda函数,需要任务在特定时间并发执行。原本以为将批量大小(batch size)设为1时,每个任务会映射到独立的Lambda实例,但实际观察到连续发送的任务在同一实例中串行执行。
我期望设置batch size=1能强制SQS队列中的任务并发执行,却出现了Lambda串行执行的情况。关于batch size=1参数,我是否有遗漏的知识点?
补充代码
消息发送代码(Python)
for req in reqs: rand_str = str(random.randint(1, 2**15)) queue.send_message( MessageBody=json.dumps(req), MessageDeduplicationId=rand_str, MessageGroupId=rand_str )
Lambda处理函数(Python)
def handle_request(event, context): request = event['Records'][0] payload = json.loads(request["body"]) b = Bot(payload) b.run() handle_result(b)
你遇到的问题核心并非batch size=1的理解错误,而是忽略了Lambda和SQS FIFO队列的几个关键并发控制逻辑:
Lambda实例复用≠串行执行
Lambda实例在处理完请求后会被保留一段时间(通常数分钟),如果后续请求进来时实例仍存活,会复用该实例处理请求。但这只影响单个实例的任务处理顺序,如果同时有多个请求,Lambda会自动启动新实例实现并发。你看到的串行,可能是消息发送间隔过短,或者并发被人为限制。SQS FIFO队列的并发触发限制
虽然你给每个消息分配了随机MessageGroupId(这是FIFO队列实现并发的正确做法,同一GroupId的消息才会串行),但Lambda的SQS触发器有一个Maximum concurrency配置项:- 如果该值被设置为1,无论队列中有多少消息,Lambda只会用一个实例串行处理;
- 默认应为unlimited,确保Lambda能根据消息量启动足够多的实例。
Lambda账户/函数级并发限制
- 检查AWS账户的Lambda全局并发配额,如果配额被设为1,所有Lambda函数都会串行执行;
- 检查你这个Lambda函数的预留并发设置,如果预留并发为1,也会限制只能用一个实例处理请求。
消息发送方式的影响
你的代码是逐个串行发送消息,如果发送间隔极短,Lambda可能来不及启动新实例,就复用了之前的实例处理后续消息,导致看起来是串行。可以尝试同时发送多个消息(比如用异步方式),验证是否会启动多个Lambda实例。
解决步骤
- 进入Lambda控制台,找到你的函数→配置→触发器→编辑SQS触发器,确认Maximum concurrency未被限制为1;
- 查看Lambda函数的配置→并发,检查预留并发和账户级并发配额;
- 调整消息发送方式,尝试同时提交多个消息,观察是否出现并发执行的Lambda实例;
- 确保SQS队列的可见性超时大于Lambda函数的最大执行时间,避免消息被重复处理干扰观察。
内容的提问来源于stack exchange,提问作者user139156

