如何避免Step Functions中不同工作流并行处理同一文件(非DynamoDB)
解决SQS触发的Step Functions工作流并发处理同一文件的问题(无DynamoDB)
针对你需要禁止workflow1与workflow2同时处理同一文件,且不使用DynamoDB的需求,以下是几个可行方案:
方案1:利用SQS FIFO队列的消息分组特性
将现有标准SQS队列替换为FIFO队列,把文件ID作为消息的MessageGroupId。SQS FIFO队列会保证同一分组ID的消息严格按顺序被消费,同一时间只有一条消息处于可见状态(即被某个工作流处理)。后续相同文件ID的消息会在队列中等待,直到当前工作流处理完成并确认消息。
- 优势:无需额外组件,完全依赖SQS原生特性,实现简单
- 限制:FIFO队列吞吐量低于标准队列(默认每秒300条消息),且若工作流处理耗时较长,会导致同组消息排队延迟
方案2:通过Step Functions ListExecutions API实现锁检查
在工作流启动的第一步,调用Lambda函数执行以下逻辑:
- 调用
ListExecutionsAPI,筛选出所有状态为RUNNING且输入包含当前文件ID的Step Functions执行 - 如果存在正在运行的同文件ID执行,将当前SQS消息重新放回队列(设置延迟时间,如30秒),然后终止当前工作流
- 如果不存在,继续执行后续处理步骤
- 注意事项:
ListExecutions有API调用配额(默认每秒100次),若并发量较高,需考虑配额扩容或添加重试逻辑 - 优势:无需额外存储服务,仅依赖Step Functions和Lambda原生能力
方案3:基于Redis的分布式锁(轻量缓存替代数据库)
如果可以接受使用缓存服务而非数据库,可借助Redis实现分布式锁:
- 工作流启动时,调用Lambda函数执行
SETNX file:<fileID> "locked"命令,同时设置过期时间(需长于工作流最长处理时间) - 若
SETNX返回成功,说明获取到锁,继续处理文件 - 若返回失败,将消息放回SQS延迟重试
- 工作流处理完成后,调用Lambda删除Redis中的锁键
- 优势:性能优于数据库,适合高并发场景
- 限制:需要维护Redis实例(可使用ElastiCache托管服务)
关于你提到的Step Functions内置存储:Step Functions本身没有提供内置的键值存储能力,因此必须依赖外部组件实现锁机制,但上述方案均无需使用DynamoDB,可满足你的需求。
内容的提问来源于stack exchange,提问作者Saranya Murali
相关产品推荐
相关产品推荐

