我所能找到的有关Amazon Simple Queue Service(SQS)性能的所有信息,包括其自己的文档,都表明获得高吞吐量需要多个线程。我已经使用带有节点12的JS API对此进行了验证。如果创建多个线程,则每个线程的吞吐量大致相同,因此总吞吐量的增长几乎是线性的。但是我正在具有很多内核的一台不错的机器上运行它。当我在Lambda上的单个内核上运行时,多个线程并不能提高性能,通常这是我对多线程应用程序的期望。
但是这是我不了解的-CPU方面的工作很少,大部分时间都花在等待Web请求上。 AWS SQS API似乎是异步的,因为所有方法都将回调用于响应,并且我正在使用Promises来“异步化”所有API调用,并同时运行多个任务。通常,Node可以很好地处理任何类型的异步IO,并极大地提高了吞吐量,我一直都在使用数据库API,多个流等来执行此操作。但是SQS绝对不是这样,它的行为就像IO实际上是同步的,并且阻塞了网络调用中的线程,这对于任何现代API来说都是令人发指的。
有人在单个Node线程中成功获得高SQS消息吞吐量吗?对于FIFO队列(发送,接收和删除,所有这些都调用最大批处理大小为10的批处理方法),我看到的最大值约为50到100条消息/秒。这是在lambda(即自己的网络)上运行的,这仅比通过Internet在笔记本电脑上运行它快一点,这是另一个令人惊讶的发现。 Amazon's documentation说批处理时,FIFO队列应该每秒最多支持3000条消息,这对我来说很好。是否真的需要多个内核或虚拟CPU上的多个线程来实现?这太荒谬了,我简直不敢相信会使用太多CPU,主要应该是IO时间,应该是异步的。
编辑:
随着我继续进行测试,我发现线程数的线性改善仅在每个线程处理不同的队列时发生。如果所有线程都在处理同一个队列,则添加线程没有任何改善。因此,它的行为就像每个队列都受到亚马逊的限制。但是,似乎限制的吞吐量远低于我发现的最大吞吐量。现在真的很困惑和失望!
Michael对原始问题的评论是正确的。我正在将所有消息发送到同一消息组。我以前一直在使用AMQP消息队列,在该队列中,消息将按照发送的顺序在队列中进行排序,然后按该顺序分发给订阅者。但是当多个侦听器占用AMQP队列时,由于网络等待时间的变化,无法保证将按时间顺序依次接收它们。
因此,这实际上是SQS的一个非常酷的功能,即保证消息将按在同一消息组中发送的顺序按时间顺序接收。就我而言,我不在乎收货单。因此,现在我为每个消息设置一个唯一的消息组ID,并通过增加异步消息接收循环的数量(仍仅在一个线程中)来提高性能,并且吞吐量非常惊人!