kafka根据生产者分配的分区将传入的消息拆分为多个分区。来自分区的消息然后被不同使用者组中的使用者使用。
这种体系结构使我对使用kafka作为工作/任务队列持谨慎态度,因为我必须在生产时指定分区,这间接限制了哪些使用者可以使用它,因为分区只发送给使用者组中的一个使用者。我不希望提前指定分区,这样无论哪个使用者可以执行该任务都可以这样做。有没有一种方法可以在kafka体系结构中构造分区/生产者,在这种体系结构中,任务可以由下一个可用的使用者拉取,而不必在生成工作时通过选择分区来提前分割工作?
对于这个主题只使用一个分区会将所有任务放在同一个队列中,但是每个使用者组的使用者数量限制为1个,因此每个使用者必须位于不同的组中。然后所有的任务都被分配到每个用户组,这不是我要找的那种工作队列。
apachekafka适合用作任务队列吗?
4条答案
按热度按时间gorkyyrv1#
将kafka用于任务队列是个坏主意。改用rabbitmq,它做得更好更优雅。
尽管您可以将kafka用于任务队列,但您会遇到一些问题:kafka不允许多个使用者(按设计)使用单个分区,因此,例如,如果一个分区被许多任务填满,而拥有该分区的使用者正忙,则该分区中的任务将“饿死”。这也意味着,主题中任务的使用顺序将与任务的生成顺序不同,如果任务需要按特定顺序使用,则可能会导致严重问题(在Kafka中,为了完全实现您必须只有一个使用者和一个分区,这意味着只有一个使用者和一个分区进行串行使用)节点。如果您有多个使用者和多个分区,则在主题级别将无法保证任务的使用顺序)。
事实上,Kafka的主题并不是以计算机科学的方式出现的。队列意味着先进先出-这不是你在Kafka的主题级别得到的。
另一个问题是很难动态更改分区的数量。添加或删除新员工应该是动态的。如果您想确保新的worker将获得kakfa中的任务,您必须将分区号设置为最大可能的worker。这不够优雅。
所以底线是使用rabbitmq或其他队列。
说到这里,samza(linkedin)正在使用kafka作为某种基于流媒体的任务队列:samza
编辑:规模考虑:我忘了提到kakfa是一个大数据/大规模工具。如果你的就业率是巨大的,那么Kafka可能是一个很好的选择,尽管你的事情我写了早些时候,因为处理巨大的规模是非常具有挑战性的,Kafka是非常好的做这件事。如果我们谈论的是更小的规模(比如说,高达每秒几个dosens/数百个工作),那么与rabbitmq相比,kafka也是一个糟糕的选择。
2skhul332#
本主题围绕工作或任务队列中任务的执行顺序进行了大量讨论。我会提出这样一个概念:执行顺序不应该是工作队列的一个特征。
工作队列是一种通过在完成不同任务时应用可控数量的工作线程来控制资源使用的方法。对队列中的任务强制执行处理顺序意味着对队列中的任务也强制执行完成顺序,这实际上意味着队列中的任务将始终按顺序处理,而下一个任务仅在前一个任务结束后处理。这实际上意味着您有一个单线程任务队列。
如果执行顺序在某些任务中很重要,那么这些任务应该在完成后将序列中的下一个任务添加到工作队列中。或者您支持一种顺序作业类型,在处理时,该类型实际上在一个worker上按顺序处理一系列作业。
在任何情况下,工作队列都不应该实际地对其任何工作进行排序—下一个可用的处理器应该始终执行下一个任务,而不管任务完成之前或之后发生了什么。
我还把Kafka作为工作队列的基础,但我研究得越多,它看起来就越不像理想的平台。
我认为它主要被用作同步不同资源的手段,而不是执行不同作业请求的手段。
我认为在工作队列中另一个很重要的方面是支持任务的优先级排序。例如,如果队列中有20个任务,并且一个新任务以更高的优先级到达,那么我希望该任务跳到行的开头,由下一个可用的辅助进程拾取。Kafka不允许这样。
x3naxklr3#
我想说,这取决于规模。你预计在一个时间单位里有多少任务?
你所描述的最终目标基本上就是Kafka默认的工作方式。当您生成消息时,默认(最广泛使用的)选项是使用random partitioner,它以循环方式选择分区,保持分区均匀使用(因此可以避免指定分区)。
分区的主要目的是并行处理消息,因此您应该以这种方式使用它。
分区用于的另一个常用的“事情”是确保某些消息在生成时以相同的顺序被使用(然后您指定分区键,使所有这些消息最终都在同一个分区中)。e、 g.使用
userId
as key将确保以这种方式处理所有用户)。b0zn9rqh4#
在尝试将kafka用作消息队列时,有两个主要障碍:
正如在ofer的回答中所描述的,您只能使用来自单个使用者的单个分区,并且处理顺序只能在一个分区内得到保证。因此,如果不能在分区之间公平地分配任务,这可能是个问题
默认情况下,您只能确认处理到给定点(偏移量)的所有消息。与传统的消息队列不同,您不能进行选择性确认,如果失败,则可以进行选择性重试。这可以通过使用kmq来解决,kmq在附加主题的帮助下添加了单独的acks功能(免责声明:我是kmq的作者)。
rabbitmq当然是另一种选择,但它也提供了不同的(较低的)性能和复制保证。简而言之,rabbitmq文档声明代理不允许分区。另请参阅我们对消息队列与数据复制mqperf的比较。