JavaScript中有效的有限并行执行

Let’s say you need to save 10000 books into a books service. The service’s API only allows us to save 100 books per request. My first idea would be to split everything into chunks of 100 books and fire everything in parallel.

假设您需要将10000本书保存到图书服务中。 该服务的API仅允许我们每个请求保存100本书。 我的第一个想法是将所有内容分解为100本书的一部分,并并行地进行所有操作。

The downside is that it will create a spike in the load of the books service. It usually means that the service will either struggle to process such a spike or it will be over-provisioned to handle loads like that. Over-provisioning usually means paying for computing power that isn’t used most of the time.

不利之处在于,这将导致图书服务的负荷激增。 通常,这意味着服务将要么难以处理这样的峰值,要么会被超额配置以处理类似的负载。 过度配置通常意味着要支付大部分时间未使用的计算能力。

So we want to flatten the spike a bit. To do that we will use what’s called a limited parallel execution. Basically, we will be sending batches of books in parallel but not more than 10 at a time.

因此,我们想稍微平整峰值。 为此,我们将使用所谓的有限并行执行。 基本上,我们将并行发送一批图书,但一次最多发送10本书。

export const saveBooks = async (books) => {
  const chunks = chunk(chunk(books, 100), 10)


  const results = []


  for (const chunkOfChunks of chunks) {
    const chunkResults = await Promise.all(chunkOfChunks.map(saveBooksChunk))


    results.push(...chunkResults)
  }


  return results
}

You probably already know that this code has one issue. On each iteration, we have to wait for the slowest operation to complete.

您可能已经知道此代码有一个问题。 在每次迭代中,我们都必须等待最慢的操作完成。

Image for post

Let’s solve that as well with a promise pool. A promise pool allows you to limit the maximum number of functions running in parallel by waiting for the promises to settle. I’m going to use the @supercharge/promise-pool package, but there are many alternatives.

让我们用一个promise pool解决这个问题。 承诺池允许您通过等待承诺来限制并行运行的最大数量。 我将使用@supercharge/promise-pool程序包,但有许多替代方法。

export const saveBooks = async (books) => {
  const chunks = chunk(books, 100)


  const { results } = await PromisePool
    .withConcurrency(10)
    .for(chunks)
    .process(saveBooksChunk)


  return results
}

As you can see we no longer wait for the slowest function to complete and start a new execution as soon as one finished execution.

如您所见,我们不再等待最慢的函数完成并在执行完成后立即开始新的执行。

Image for post

In this particular example, the total execution time was reduced by a third.

在此特定示例中,总执行时间减少了三分之一。

Of course, there there is no limit to perfection. What if the books service has a rate limit? What if there is more than one producer? Your next step then would be setting up a queue like RabbitMQ, Apache Kafka, or Amazon SQS. But that’s another topic.

当然,完美无极限。 如果图书服务有价格限制,该怎么办? 如果生产者不止一个怎么办? 然后,您的下一步将是设置一个队列,例如RabbitMQ,Apache Kafka或Amazon SQS。 但这是另一个话题。

翻译自: https://medium.com/@arsenyyankovsky/effective-limited-parallel-execution-in-javascript-ea2a1fb9a632

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值