使用多个线程向 DynamoDB 批量写入 AWS Lambda 的执行速度较慢

Nat*_*ate 5 python multithreading amazon-web-services amazon-dynamodb aws-lambda

免责声明:我知道这个问题会惹恼一些人,因为它含糊、理论性强,而且代码很少。

我有一个 Python 中的 AWS Lambda 函数,它从 S3 读取非规范化记录文件,正确格式化其内容,然后通过批量写入将其上传到 DynamoDB。一切都像广告上说的那样。然后,我尝试将此管道的上传部分分解为线程,希望更有效地利用 DynamoDB 写入能力。然而,多线程版本慢了大约 50%。由于代码很长,我包含了伪代码。

NUM_THREADS = 4
for every line in the file:
   Add line to list of lines
   if we've read enough lines for a single thread:
       Create thread that uploads list of lines
       thread.start()
       clear list of lines.

for every thread started:
    thread.join()
Run Code Online (Sandbox Code Playgroud)

到目前为止我已经检查过的重要说明和问题的可能根源:

  • 当使用 DynamoDB Local 进行本地测试时,线程确实使我的程序运行得更快。
  • 相反,如果我只使用 1 个线程,或者即使我使用多个线程但在启动后立即加入该线程(实际上是单线程),程序的完成速度会快得多。1 线程 ~30s,多线程 ~45s。
  • 我在线程之间没有共享内存,没有锁等。
  • 我尝试为每个线程创建新的 DynamoDB 连接并共享一个连接,但没有效果。
  • 我已经确认,添加更多线程不会压垮 DynamoDB 的写入容量,因为它发出相同数量的批量写入请求,而且在整个执行过程中,与单个线程相比,我没有更多未处理的项目。
  • 线程化应该可以提高执行时间,因为程序是网络绑定的,即使 Python 线程并不真正在多个内核上运行。
  • 我尝试先读取整个文件,然后生成所有线程,认为也许最好不要中断磁盘IO,但没有效果。
  • 我尝试过线程库和进程库。

我再次知道这个问题非常理论化,因此可能很难看出问题的根源,但是是否有一些我不知道的 Lambda 怪癖?我还可以尝试其他方法来帮助诊断问题吗?任何帮助表示赞赏。

pmu*_*ler 1

Nate,您是否完全排除了 Dynamodb 端的问题?写请求总数可能相同,但对于多线程,每秒的数量会不同。

控制台有一些有用的图表来显示您的写入(或批量写入)是否受到限制。如果您的 Lambda 函数中没有正确的“后退,重试”逻辑,Lambda 将不断尝试,您的问题会变得更糟。

另一件事,这对你来说可能是显而易见的(但对我来说不是!)。我的印象是,batch_writes 在容量规划方面为您节省了资金。(例如,以 20 为一组的批次进行 200 次写入只会花费 10 个写入单元。我可以发誓我听到 AWS 人员在演示中提到了这一点,但这不是重点。)

事实上,batch_writes 为您节省了一些时间,但在经济上没有任何意义。

最后一个想法:我敢打赌 Lambda 处理时间比提高 Dynamodb 写入容量更便宜。如果您并不特别急于完成 Lambda,为什么不让它在单线程上运行呢?

祝你好运!