我在使用新服务(例如非RDBMS数据存储或消息队列)时首先想到的一件事是:“我应该如何构建数据?”。
我已阅读并观看了一些介绍性材料。特别是,例如,Kafka: a Distributed Messaging System for Log Processing,写道:
了解这一点,说明如何使用主题和分区的好例子是什么?应该什么时候成为主题?应该何时成为分区?
举个例子,假设我的(Clojure)数据如下:
{:user-id 101 :viewed "/page1.html" :at #inst "2013-04-12T23:20:50.22Z"}
{:user-id 102 :viewed "/page2.html" :at #inst "2013-04-12T23:20:55.50Z"}
主题应该基于user-id
吗? viewed
? at
?分区怎么样?
我该如何决定?
答案 0 :(得分:124)
在为Kafka构建数据时,它实际上取决于它的消费意义。
在我看来,一个主题是一组相似类型的消息将由同一类型的消费者使用,所以在上面的例子中,我只有一个主题,如果你决定推一些通过Kafka的其他类型的数据,您可以稍后为其添加新主题。
主题在ZooKeeper中注册,这意味着如果尝试添加过多的主题,可能会遇到问题,例如:如果您有一百万用户并决定为每个用户创建一个主题。
另一方面,分区是一种并行化消息消耗的方法,并且代理群集中的分区总数必须至少与消费者组中的消费者数量相同才能理解分区特征。消费者群体中的消费者将根据分区将处理主题的负担分开,以便一个消费者只关心分区中的消息本身被“分配”。
可以使用生产者端的分区键显式设置分区,如果没有提供,则会为每条消息选择一个随机分区。
答案 1 :(得分:50)
一旦您知道如何对事件流进行分区,主题名称就会很简单,所以我们首先回答这个问题。
@Ludd是正确的 - 您选择的分区结构在很大程度上取决于您希望如何处理事件流。理想情况下,您需要一个分区键,这意味着您的事件处理是 partition-local 。
例如:
:user-id
进行分区。这样,与单个用户的站点活动相关的所有事件都将在同一分区中可用。这意味着,只需查看单个分区中的事件,流Apache Samza等流处理引擎就可以计算给定用户的平均现场时间。这避免了必须执行任何类型的昂贵的分区 - 全局处理:viewed
页面进行分区。再一次,Samza将能够通过查看单个分区中的事件来保持给定页面视图的计数通常,我们试图避免不得不依赖于全局状态(例如将数据保存在远程数据库中,如DynamoDB或Cassandra),而是能够使用分区本地状态。这是因为local state is a fundamental primitive in stream processing。
如果你需要上述两个用例,那么Kafka的一个常见模式是首先按:user-id
进行分区,然后按{{1}进行重新分区进行分区。准备好进行下一阶段的处理。
关于主题名称 - 这里显而易见的是:viewed
或events
。更具体地说,您可以使用user-events
和/或events-by-user-id
。
答案 2 :(得分:4)
我认为主题名称是一种消息的结论,并且生产者通过订阅主题向主题和消费者订阅消息发布消息。
主题可能包含许多分区。分区有利于并行性。分区也是复制的单位,所以在Kafka中,领导者和追随者也被称为分区级别。实际上,分区是一个有序队列,其顺序是消息到达顺序。主题由一个简单的单词中的一个或多个队列组成。这对我们建模我们的结构非常有用。
Kafka由LinkedIn开发,用于日志汇总和交付。这个场景非常好,作为一个例子。
您的Web或应用程序上的用户事件可以由Web服务器记录,然后通过生产者发送给Kafka代理。在生产者中,您可以指定分区方法,例如:事件类型(不同的事件保存在不同的分区中)或事件时间(根据您的应用程序逻辑将一天划分到不同的时间段)或用户类型或只是没有逻辑和平衡所有日志进入许多分区。
关于您的案例,您可以创建一个名为“page-view-event”的主题,并通过哈希键创建N个分区,以便将日志均匀地分配到所有分区。或者你可以选择一个分区逻辑来让你的灵魂分发日志。
答案 3 :(得分:4)
这与问题并不完全相关,但如果您已经根据主题确定了记录的逻辑隔离,并希望优化Kafka中的主题/分区计数,this博客可能会派上用场
简而言之:关键要点:
通常,Kafka群集中的分区越多,可以实现的吞吐量就越高。让生产的单个分区上的最大值可以 p ,并且消费 c 。假设您的目标吞吐量为 t 。然后你需要至少有max( t / p , t / c )分区。
目前,在Kafka中,每个代理都会打开每个日志段的索引和数据文件的文件句柄。因此,分区越多,需要在底层操作系统中配置打开文件句柄限制的值越高。例如。在我们的生产系统中,我们曾经看到一个错误too many files are open
,而我们有大约3600个主题分区。
当代理被不当关闭时(例如,kill -9),观察到的不可用性可能与分区数成正比。
Kafka中的端到端延迟由生产者发布消息到消费者读取消息的时间定义。根据经验,如果您关心延迟,那么将每个代理的分区数限制为100 x b x r 可能是个好主意,其中 b 是Kafka集群中的代理数量, r 是复制因子。