apache-kafka - 通过 MQ 传输音频流(可扩展性)

标签 apache-kafka redis stream rabbitmq mq

我的问题相当具体,所以我可以接受一般性答案,这将为我指明正确的方向。

问题描述: 我想将来自多个生产者的特定任务数据传递给处理该任务的特定消费者(两者都是在 k8s 中运行的 docker 容器)。这种关系是多对多的——任何生产者都可以为任何消费者创建数据包。每个消费者在任何给定时刻都会处理约 10 个数据流,而每个数据流每秒包含 100 个 160b 消息(来自不同的生产者)。

当前解决方案: 在我们当前的解决方案中,每个生产者都有一个任务的缓存:(IP:PORT)对消费者的值,并使用UDP数据包直接发送数据。它具有很好的可扩展性,但部署起来相当困惑。

问题: 这可以通过消息队列(Kafka、Redis、rabbitMQ...)的形式来实现吗?例如,为每个任务提供一个 channel ,生产者在其中发送数据,而消费者则可以消费它们? MQ 可以处理多少个流(我知道它会有所不同 - 建议您最好的)。

编辑:1000 个流等于每秒 100 000 条消息是否可行? (1000 个流的吞吐量为 16 Mb/s)

编辑 2:将打包大小固定为 160b(拼写错误)

最佳答案

除非您需要磁盘持久性,否则甚至不要查看消息代理方向。您只是将一个问题添加到另一个问题上。直接网络编码是解决音频广播的正确方法。现在,如果您的代码很困惑并且想要简化的编程模型,那么 ZeroMQ 库是套接字的良好替代品。这将为您提供您关心的所有 MessageBroker 功能:a) 离散消息传递而不是流,b) 客户端可发现性;无需过度使用另一个软件层。

说到“可行”:每秒 100,000 条消息(160kb 消息)是大量数据,即使没有任何消息传递协议(protocol),它也达到 1.6 Gb/秒。一般来说,Kafka 在小消息的消息吞吐量方面表现出色,因为它在多层上对消息进行批处理。要知道 Kafka 的持续性能通常受到磁盘速度的限制,因为 Kafka 是故意这样编写的(最慢的组件是磁盘)。但是,您的消息非常大,您需要同时写入和读取消息,因此如果没有大型集群安装,我不会看到这种情况发生,因为您的问题是实际数据吞吐量,而不是消息数量。

由于您的数据有限,即使是其他经典的 MQ 软件(例如 ActiveMQ、IBM MQ 等)实际上也能够很好地应对您的情况。一般来说,经典代理比 Kafka 更“健谈”,并且在处理小消息时无法命中 Kafka 的消息槽。但只要您使用大型非持久消息(以及正确的代理配置),您也可以期待这些消息具有不错的性能(以 mb/秒为单位)。经典代理将通过正确的配置,直接将生产者的套接字连接到消费者的套接字,而无需访问磁盘。相比之下,Kafka 总是首先持久化到磁盘。因此,与 Kafka 相比,它们甚至具有一些延迟优势。

然而,这种直接的套接字到套接字“优化”只是这个答案的开始的一个完整循环。除非您需要音频流持久性,否则您使用中间代理所做的就是找到一种间接方法将生成套接字绑定(bind)到消耗套接字,然后通过此连接发送离散消息。如果这就是您所需要的 - ZeroMQ 就是为此而设计的。

还有一种名为 MQTT 的消息传递协议(protocol),如果您选择寻求代理解决方案,您可能会对它感兴趣。因为它是一种可扩展性极强且开销较低的解决方案。

关于apache-kafka - 通过 MQ 传输音频流(可扩展性),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66522070/

相关文章:

java - 永远运行kafka消费者(新消费者API)

java - Maven 冲突依赖 kafka-stream-test-utils 和 kafka-streams

apache-kafka - 使用 Kafka 最佳实践的 Oracle 变更数据捕获

redis hset 和键空间通知

javascript - 如何从 Redis 获取所有数据到 Javascript 数组

docker - 手动安装Kafka连接器

node.js - 在多个 Node 实例中共享 IO 对象

java - 为什么使用 java.io.Filter* 而不是扩展具体的流实现?

java - 使用 Docker api 连接到容器后如何使用 stdin、stdout 和 stderr 流?

c++ - 如何从 C++ 中的文件流中检测行的结尾