【问题标题】:Slower execution of AWS Lambda batch-writes to DynamoDB with multiple threads使用多线程对 DynamoDB 的 AWS Lambda 批量写入执行速度较慢
【发布时间】:2016-02-06 10:19:25
【问题描述】:

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

我在 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()

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

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

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

【问题讨论】:

    标签: python multithreading amazon-web-services amazon-dynamodb aws-lambda


    【解决方案1】:

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

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

    还有一件事,这对你来说可能很明显(但不是我!)。我的印象是,batch_writes 在容量规划方面为您节省了资金。 (例如,20 次分批写入 200 次只需要 10 个写入单位。我本可以发誓我曾听到 AWS 人员在演示文稿中提到过这一点,但那不是重点。)

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

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

    祝你好运!

    【讨论】:

    • 是的,我一直在通过 CloudWatch 检查它的行为,并且没有任何限制。而且我确实知道它们的成本仍然与单个写入相同。我考虑过精简上传到 S3 的文件,直到只需要一个线程,这很可能是我所做的,但这应该是可能的,我想看看我是否可以修复它。
    • 也许是另一种选择。不要将文件精简到 S3,而是将它们加载到 Kinesis Stream 上……然后,您可以通过将 lambda 函数焊接到 Kinesis 流来调整有多少“事件”一次进入 Lambda 函数。跨度>
    【解决方案2】:

    事实证明线程更快,但仅当文件达到特定文件大小时。我最初的工作文件大小约为 1/2 MG。使用 10 MG 文件,线程版本的输出速度提高了约 50%。仍然不确定为什么它不适用于较小的文件,也许它只是需要时间来做饭,你知道我的意思吗?电脑是喜怒无常的东西。

    【讨论】:

      【解决方案3】:

      作为背景,我对 python 和 dynamoDB 以及使用 python 的多处理库有很好的经验。由于您的文件大小相当小,因此可能是该过程的设置时间使您对性能感到困惑。如果您还没有,如果您需要将任何数据传回主线程,请使用 python 多处理池并根据您的用例使用 map 或 imap。使用池是在 python 中运行多个进程的最简单的方法。如果您需要将应用程序运行得更快作为优先事项,您可能需要考虑使用 golang 并发,并且您始终可以将代码构建为二进制文件以便在 python 中使用。干杯。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-06-16
        • 1970-01-01
        • 2019-03-02
        • 2016-05-22
        • 2022-01-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多