我试图使用ProcessPoolExecutor同时使用Dynamodb流触发lambdas。这是我收到的错误。
场景是当一堆记录(如1000条记录)落入dynamodb(批量大小为10)时,流会触发lambda。我之前使用过ThreadPoolExecutor并且它工作但是批量处理的10个进程中只有5-8个记录被处理并且剩下的都剩下。每个记录大约需要50秒才能完成。 AWS lambda的5分钟限制是否正在跳过ThreadPoolExecutor中的其他记录。此外,使用ProcessPoolExecutor将帮助我解决ThreadPoolExecutor ???
的问题 [Errno 38] Function not implemented: OSError
Traceback (most recent call last):
File "/var/task/ycf_calculator.py", line 464, in main
with ProcessPoolExecutor(max_workers=25) as executor:
File "/var/lang/lib/python3.6/concurrent/futures/process.py", line 390, in __init__
EXTRA_QUEUED_CALLS)
File "/var/lang/lib/python3.6/multiprocessing/context.py", line 102, in Queue
return Queue(maxsize, ctx=self.get_context())
File "/var/lang/lib/python3.6/multiprocessing/queues.py", line 42,in __init__
self._rlock = ctx.Lock()
File "/var/lang/lib/python3.6/multiprocessing/context.py", line 67, in Lock
return Lock(ctx=self.get_context())
File "/var/lang/lib/python3.6/multiprocessing/synchronize.py", line 163, in __init__
SemLock.__init__(self, SEMAPHORE, 1, 1, ctx=ctx)
File "/var/lang/lib/python3.6/multiprocessing/synchronize.py", line 60, in __init__
unlink_now)
OSError: [Errno 38] Function not implemented
答案 0 :(得分:2)
您正在使用一次调用来处理一批10条记录。每条记录大约需要50秒才能完成。没有并行处理,50 * 10 = 500秒。
Lambda的最长执行时间为300秒。 Lambda几乎可以在一个处理器/内核上运行,因此不支持多个CPU之间的多处理。 (有关更多见解,请参阅this question。)
问题是,你没有采用 Lambda 的方式。
我建议将现有的Lambda分成两个不同的Lambdas(批处理器和 worker )。
批处理器 Lambda由您的DynamoDB流触发(批量大小为10,如您的示例所示)。然后,此Lambda 异步为流中的10条记录中的每个调用 worker Lambda 。 (重要提示:每个 worker 调用仅传递一个记录。)
worker Lambda独立接收并处理一个且仅一个记录。就是这样。
简而言之,
1 dynamoDB stream -> 1 batch invocation -> 10 worker invocations
它大大简化了。无需混淆多线程或多处理。
你可以免费获得10个CPU内核!