春天的卡夫卡和交易

时间:2018-09-07 10:06:16

标签: spring apache-kafka spring-transactions spring-kafka

我想将Spring Kafka与Transactions一起使用,但我真的不了解应该如何配置它以及如何工作。

这是我的配置

    props.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, "true");
    props.put(ProducerConfig.RETRIES_CONFIG, String.valueOf(Integer.MAX_VALUE));
    props.put(ProducerConfig.MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION, 1);
    props.put(ProducerConfig.ACKS_CONFIG, "all");

此配置在带有事务ID前缀的DefaultKafkaProducerFactory中使用:

defaultKafkaProducerFactory.setTransactionIdPrefix("my_app.");

问题1:

我应该如何选择此交易ID前缀? 如果我理解正确,spring会使用此前缀为每个创建的生产者生成一个事务ID。

为什么我们不能只使用“ UUID.randomUUID()?

问题2:

如果生产者被销毁,它将生成一个新的交易ID。 因此,如果应用程序崩溃,则在重新启动时它将重用旧的事务ID。

那正常吗?

问题3:

我正在使用部署在云上的应用程序,该应用程序可以自动缩放。 这意味着我的前缀无法固定,因为我在每个实例上的所有生产者的事务ID都会发生冲突。

我应该在其中添加随机部分吗? 实例按比例缩小/放大或崩溃并重新启动时,是否需要恢复相同的前缀?

问题4:

最后但并非最不重要的一点是,我们正在为Kafka使用凭据。 这似乎不起作用:

Current ACLs for resource `TransactionalId:my_app*`:
    User:CN... has Allow permission for operations: All from hosts: *

我应该如何设置知道我的交易ID的ACL?

编辑1

进一步阅读后,如果我理解正确的话。

如果您有一个C0(消费者)从P0(分区)中读取。如果经纪人开始进行消费者再平衡。 可以将P0分配给另一个使用者C1。 消费者C1应该使用与先前C0相同的交易ID,以防止重复(僵尸隔离)?

如何在spring-kafka中实现这一目标?事务标识似乎与使用者无关,因此分区已读取。

谢谢

1 个答案:

答案 0 :(得分:1)

  1. 由于僵尸防护,您不能使用随机TID-如果服务器崩溃,您可能会在该主题中进行部分事务,该事务永远不会完成,并且任何写入操作都不会占用任何分区进行该交易。

  2. 这是出于设计原因-出于上述原因。

  3. 同样,您不能随机化;由于上述原因。

例如,

Cloud Foundry具有一个指示实例索引的环境变量。如果您使用的云平台不包含类似内容,则必须以某种方式对其进行仿真。然后,在交易ID中使用它:

spring.kafka.producer.transaction-id-prefix=foo-${instance.index}-
  1. ACL-我无法回答;我对kafka权限不熟悉;对此最好单独问一个问题。

  2. 我认为我们需要向Spring添加一些逻辑,以确保特定主题/分区始终使用相同的交易ID。

https://github.com/spring-projects/spring-kafka/issues/800#issuecomment-419501929