Kafka的Spring Cloud Data Flow主题创建

时间:2019-12-14 19:09:30

标签: python spring kubernetes apache-kafka spring-cloud-dataflow

我有自己的内部带有Python的Spring Cloud Data Flow处理器,我将此示例用作指导:https://dataflow.spring.io/docs/recipes/polyglot/processor/。 然后,我想缩放并创建其中三个处理器,因此使用spring.cloud.deployer.myApp.count=3创建了3个内含Python的容器。 我对示例中的代码进行了一些修改:创建Kafka使用者时,我还传递了一个组ID,因此消息应该负载均衡。

consumer = KafkaConsumer(get_input_channel(), group_id=get_consumer_group(), bootstrap_servers=[get_kafka_binder_brokers()])

问题是SCDF创建的Kafka主题只有一个分区,因此消息仅到达一个pod。 所以我想知道:

  • 我应该以某种方式配置SCDF来创建具有3个分区的Kafka主题吗?
  • 还是我不应该依靠SCDF并用Python自己创建主题?我想这将是多余的,因为SCDF也会创建此主题。
  • SCDF中的哪个组件实际上负责创建Kafka主题?我如何影响分区数量?
  • 如果我停止该流并以4个处理器步骤再次启动,则该主题是否应使用第4个分区扩展?因为当前没有新分区被创建。

2 个答案:

答案 0 :(得分:1)

请花点时间回顾一下Spring Cloud Data Flow的responsibilities。如果不清楚,SCDF不会与支持消息传递中间件(如Kafka)进行交互,也不会在运行时使用它。换句话说,SCDF不会创建与其关联的主题或分区,而只是自动配置Spring Cloud Stream(SCSt)属性。

但是,如果您在自定义处理器中使用SCSt,则该框架会自动将所需渠道绑定到中间件中的基础主题。该框架还具有更改分区行为的功能。您也可以使用分区过度的主题来部署处理器。 several other configuration options可以构建所需的流数据处理行为。

您正在查看的Python示例并不具有SCSt提供的所有功能。该食谱是一个示例演练,演示了如何有人可以在Python中构建本机处理器样式的应用程序,其中在Python代码本身中手动创建了生产者和使用者配置。 SCDF和SCSt都不影响此配方中的应用程序行为。

  

我应该以某种方式配置SCDF来创建具有3个分区的Kafka主题吗?

如前所述,SCDF不与Kafka交互。

  

还是我不应该依靠SCDF在Python中自己创建主题?我想这将是多余的,因为SCDF也会创建此主题。

如果您的自定义处理器不是Spring Cloud Stream应用程序,是的,您有责任在代码中明确定义主题和分区。

  

SCDF中的哪个组件实际上负责创建Kafka主题?我如何影响分区数量?

Spring Cloud Stream。请参阅上面的说明。

  

如果我停止该流并以4个处理器步骤再次启动,则该主题是否应使用第4个分区扩展?因为当前没有新分区被创建。

您不一定需要重新启动流数据管道。如果您的主题是预先分区过度的,是的,运行时任何其他使用者都应该能够自动参与竞争的使用者关系。请随时注意spring-io/dataflow.spring.io#156-我们正在添加一个配方,以演示使用SCSt + SCDF + Kafka进行手动和自动缩放的可能性。

答案 1 :(得分:1)

能够通过将以下代码引入Python容器启动脚本中来解决此问题,https://dataflow.spring.io/docs/recipes/polyglot/processor/中提供了改进的代码。使用SCDF服务器传递的参数来获取代理URL,主题名称,实例数:

admin_client = KafkaAdminClient(bootstrap_servers=[get_kafka_binder_brokers()], client_id=sys.argv[0])

partition_count = get_cmd_arg("spring.cloud.stream.instanceCount")

# create Kafka topic if does not exist
new_topic = NewTopic(name=get_input_channel(), num_partitions=partition_count, replication_factor=1)
try:
    admin_client.create_topics(new_topics=[new_topic])
except TopicAlreadyExistsError:
    logging.info(f"Topic {get_input_channel()} was already created")

# add Kafka partitions to existing topic
new_partitions = NewPartitions(total_count=partition_count)
try:
    admin_client.create_partitions(topic_partitions={get_input_channel(): new_partitions})
except InvalidPartitionsError as exp:
    logging.info(f"No need to increase Kafka partitions for topic {get_input_channel()}")