通过 MQ 流式传输音频流(可扩展性)
Posted
技术标签:
【中文标题】通过 MQ 流式传输音频流(可扩展性)【英文标题】:Streaming audio streams trough MQ (scalability) 【发布时间】:2021-06-05 21:02:45 【问题描述】:我的问题比较具体,所以我可以接受一般性的回答,这将为我指明正确的方向。
问题描述: 我想将来自多个生产者的特定任务数据传递给从事该任务的特定消费者(两者都是在 k8s 中运行的 docker 容器)。这种关系是多对多的——任何生产者都可以为任何消费者创建数据包。每个消费者在任何给定时刻都在处理大约 10 个数据流,而每个数据流每 秒 包含 100 个 160b 消息(来自不同的生产者)。
当前解决方案: 在我们当前的解决方案中,每个生产者都有一个任务的缓存:(IP:PORT)对消费者的值,并使用UDP数据包直接发送数据。它具有很好的可扩展性,但部署起来相当混乱。
问题: 这可以通过各种消息队列(Kafka、Redis、rabbitMQ ......)的形式实现吗?例如,每个任务都有一个通道,生产者发送数据而消费者 - 很好地消费它们? MQ 可以处理多少个流(我知道它会有所不同 - 建议你最好的)。
编辑:1000 个流等于每秒 100 000 条消息是否可行? (1000 个流的吞吐量为 16 Mb/s)
编辑 2:将打包大小固定为 160b(错字)
【问题讨论】:
【参考方案1】:除非您需要磁盘持久性,否则甚至不要查看消息代理方向。您只是将一个问题添加到另一个问题上。直接网络代码是解决音频广播的正确方法。现在,如果您的代码很混乱,并且如果您想要一个简化的编程模型,那么可以使用 ZeroMQ 库来替代套接字。这将为您提供您关心的所有 MessageBroker 功能:a) 离散消息而不是流,b) 客户端可发现性;而不会过度使用另一个软件层。
说到“可行”:每秒 100 000 条消息和 160kb 消息是大量数据,即使没有任何消息协议,它也达到 1.6 Gb/秒。一般来说,Kafka 在小消息的消息吞吐量上大放异彩,因为它在许多层上对消息进行批处理。知道 Kafka 的这种持续性能通常受到磁盘速度的限制,因为 Kafka 是故意这样编写的(最慢的组件是磁盘)。但是,您的消息非常大,您需要同时写入和读取消息,因此如果没有大型集群安装,我认为不会发生这种情况,因为您的问题是实际数据吞吐量,而不是消息数量。
由于您的数据有限,即使是其他经典的 MQ 软件,如 ActiveMQ、IBM MQ 等,实际上也能够很好地应对您的情况。一般来说,经典代理比 Kafka 更“健谈”,并且在处理小消息时无法达到 Kafka 的消息吞吐量。但是,只要您使用大型非持久消息(和适当的代理配置),您也可以期望这些消息以 mb/sec 为单位获得不错的性能。经典代理将通过适当的配置,直接将生产者的套接字连接到消费者的套接字,而不会碰到磁盘。相比之下,Kafka 将始终首先保存到磁盘。所以他们甚至比 Kafka 有一些延迟优势。
但是,这种直接的套接字到套接字“优化”只是一个完整的循环转向这个答案的开始。除非您需要音频流持久性,否则您对中间代理所做的一切就是找到一种间接方式将生产套接字绑定到消费套接字,然后通过此连接发送离散消息。如果这就是你所需要的——ZeroMQ 就是为此而生的。
还有一种称为 MQTT 的消息传递协议,如果您选择寻求代理解决方案,您可能会对它感兴趣。因为它是一种具有极低开销的可扩展解决方案。
【讨论】:
对不起,我的意思是 160b 不是 kb 所以 16kb/s 流 :D 无论如何,我研究这个方向的原因是通过 k8s 的内部 NAT 引导 RTP 数据包非常困难。不提及在容器上打开端口是很棘手的。 我一定会研究 zeroMQ,谢谢(尽管不能投票 - 分数不够)【参考方案2】:基本方法
从 Kafka 的角度来看,问题中的每个流都可以映射到 Kafka 中的一个主题,并且 因此每个主题都有一对生产者-消费者。
缺点:如果你有很多流,你最终会得到很多主题,而且 IMO 解决方案在这里也会变得更加混乱,因为你正在增加数量。主题。
另一种方法
或者,最好的方法是将多个流映射到一个主题,其中每个流由一个键分隔(就像您使用 IP:Port 组合一样),然后让多个消费者分别订阅一组特定的分区由密钥决定。分区是 Kafka 的可扩展性点。
缺点:虽然你可以增加数量。分区,你不能减少它们。
数据类型很重要
如果您的流是异构的,从某种意义上说,它们不适合共享一个共同的主题,您可以创建更多主题。
通常,主题由它们托管的数据和/或消费者对主题中数据的处理方式决定。如果您的所有消费者都做同样的事情,即具有相同的处理逻辑,那么选择一个具有多个分区的主题是合理的。
需要考虑的几点:
与您当前的解决方案不同(我想),一旦收到消息,一旦收到并处理它就不会丢失,而是继续留在主题中直到配置的保留期。
在确定键控策略时要格外小心,即哪些消息位于哪些分区中。如前所述,如果您的所有消费者都做同样的事情,那么他们都可以在一个消费者组中分担工作量。
属于同一组的消费者执行一项共同任务,并将订阅由分区分配者确定的一组分区。然后每个消费者将获得一组密钥,换句话说,一组流或根据您当前的解决方案,一组一个或多个 IP:Port 对。
【讨论】:
感谢您的回答,您能估计一下我可以同时处理多少个流吗? 1000 个流相当于每秒 100 000 条消息是否可行?以上是关于通过 MQ 流式传输音频流(可扩展性)的主要内容,如果未能解决你的问题,请参考以下文章