在KafkaUtils.createstream()中使用“topics”参数的正确方法是什么?

时间:2018-01-09 04:02:04

标签: python pyspark apache-kafka spark-streaming

我正在使用python中的spark-streaming和kafka,并且松散地跟随this post,但我对早期提到的KafkaUtils.createStream()函数感到有些困惑。

documentation通过明确解释主题词典影响的内容并没有做太多工作。但我怀疑我只是这么认为,因为我对卡夫卡如何运作的了解是不稳定的,答案是显而易见的。

我理解它应该是这样的字典:{"topic.name": 1}我可以鹦鹉文档并说这意味着创建的流将从单个分区消耗。

所以我想我只是在寻找对这个特定功能的使用以及我对kafka概念的理解的一些澄清。我们将使用以下示例:

假设我已经定义了一个主题my.topic,该主题有3个分区,其传入的消息在一个密钥上分开,我们只说一个用户ID。

如果我像这样初始化一个流:

from pyspark.streaming.kafka import KafkaUtils

kafkaStream = KafkaUtils.createStream(
    ssc, 
    'kafka:2181', 
    'consumer-group-name', 
    {'my.topic':1}
)  

我是否正确地认为此流只会从单个分区消耗,因此不会看到每条消息都进入my.topic?换句话说,它只会看到来自用户ID的消息被发送到3个分区之一?

我的问题是:

  1. 如何正确设置此参数以使用发送到my.topic的所有邮件?

    我的直觉是我只想将主题参数设置为{'my.topic': 3},那么我的问题就变成了:

  2. 为什么我会使用小于分区总数的数字?

    我的直觉告诉我,这是你所做工作的“原子性”的问题。例如,如果我只是简单地将数据转换(例如,从CSV转换为JSON文档列表或其他内容),则将上述3个流中的每个都设置为{'my.topic': 1}作为其主题参数,并将所有部分设置为同一个使用者组通过启用每个分区的并行消费将是有益的,因为不需要就消耗的每条消息共享信息。

    与此同时,如果我正在计算整个主题的实时指标。带有过滤器等的时间窗口平均值。我很难看到一种方法来实现类似的东西而不设置{'my.topic': 3},或者如果它类似于总和,那么在消费者中对每个组件信号进行稍微复杂的下游处理组IE Sum1 + Sum2 + Sum3 = TotalSum

    但是我的知识再一次处于与卡夫卡和斯帕克一起玩耍的“初出茅庐”阶段。

  3. 有没有办法告诉createStream()从所有分区使用,而不知道有多少分区?类似于{'my.topic': -1}

  4. 单个流中是否可以指定多个主题? I.E. {'my.topic': 1, 'my.other.topic': 1}

  5. 我真的很讨厌这个问题的答案只是“是的,你的直觉是正确的。”最好的情况是有人告诉我,我对所有事情都有误解并让我直截了当。所以,请......那样做!

2 个答案:

答案 0 :(得分:2)

只需指定不带分区的主题,无论主题中有多少个分区,您都将获得该主题中的所有消息。

您需要做的就是查看示例代码:https://github.com/apache/spark/blob/v2.2.1/examples/src/main/python/streaming/direct_kafka_wordcount.py#L48

答案 1 :(得分:2)

这是Kafka-Spark集成页面中提到的。

  

val kafkaStream = KafkaUtils.createStream(streamingContext,        [ZK quorum],[消费者群组ID],[消费的Kafka分区的每个主题数量])

KafkaUtils.createStream将创建一个接收器并使用Kafka主题。

选项"要使用的Kafka分区的每个主题数量"意味着此接收器将并行读取多少个分区。

比如说你有一个名为" Topic1"有2个分区并且你提供了选项' Topic1':1,那么Kafka接收器将一次读取1个分区[它最终会读取所有分区,但一次只能读取一个分区]。原因是读取分区中的消息,并保留数据写入主题的顺序。

例如,假设Topic1的partition1包含消息{1,11,21,31,41},partition2包含消息{2,12,22,32,42},那么使用上述设置读取将产生类似{的流1,11,21,31,41,2,12,22,32,42}。每个分区中的消息是分开读取的,因此它们没有混合在一起。

如果您选择' Topic1':2,那么接收器将一次读取2个分区,这些分区中的消息将混合在一起。对于上面开始的例子,带有' Topic1':2的接收器将产生类似{1,2,11,12,21,22 ....}

的内容。

将此视为接收器可以在给定主题分区上执行的并行读取次数。

<强> 5。可以在单个流中指定多个主题吗? 是的你可以。