在一个实例进行故障转移的情况下,位于kafka流实例中的本地状态存储无法同步

时间:2019-06-20 16:19:54

标签: apache-kafka apache-kafka-streams

我正在本地计算机上运行多个kafka流使用者实例(2个实例),每个实例都有自己的自定义本地存储,并且每个实例都有不同的名称。

根据文档,如果其中一个实例发生故障,则kafka必须将死实例的存储同步到活动实例的存储(如果我错了,请纠正我)。

我为两个实例配置了相同的应用程序ID,以让kafka知道这些实例属于同一组。

当其中一个实例被杀死时,其他(活动)实例的存储将不与死实例的存储同步。我已经在两个商店上启用了更改日志主题。

但是,当我在两个实例中都使用相同的商店名称时,商店将按预期进行同步,不确定这些实例是否指向一个商店。对于这两个实例,我具有不同的StreamsConfig.STATE_DIR_CONFIG位置。

如果我缺少什么,请让我知道,存储名称可以在不同的应用程序实例上不同吗? kafka是否会自动照顾新实例存储上的更改日志主题?

//下面是我的流配置

@Bean
public KafkaStreams kafkaStreams(KafkaProperties properties,
                                 @Value("${spring.application.name}") String appName) {
    final Properties props = new Properties();
    props.put(StreamsConfig.APPLICATION_ID_CONFIG, appName);
    props.put(StreamsConfig.CLIENT_ID_CONFIG, "client2");
    props.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, properties.getBootstrapServers());
    props.put(StreamsConfig.CACHE_MAX_BYTES_BUFFERING_CONFIG, 0);
    props.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.String().getClass());
    props.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, JsonSerde.class);
    props.put(StreamsConfig.COMMIT_INTERVAL_MS_CONFIG, 10 * 1000);
    //props.put(StreamsConfig.STATE_DIR_CONFIG, "/tmp/kafka-streams1");
    props.put(StreamsConfig.NUM_STANDBY_REPLICAS_CONFIG, "1");
    props.put(StreamsConfig.consumerPrefix(ConsumerConfig.PARTITION_ASSIGNMENT_STRATEGY_CONFIG),
            new RoundRobinAssignor().getClass().getName());
    props.put("auto.offset.reset", "earliest");
    final KafkaStreams kafkaStreams = new KafkaStreams(kafkaStreamTopology(), props);
    System.out.println("Invoked kafkaStreams");
    //kafkaStreams.cleanUp();
    kafkaStreams.start();
    return kafkaStreams;
}

1 个答案:

答案 0 :(得分:0)

  

我正在本地计算机上运行多个kafka流使用者实例(2个实例),每个实例都有自己的自定义本地存储,并且每个实例都有不同的名称。

这听起来不正确。如果您使用相同的application.id(即group.id)运行多个实例,则所有实例必须执行相同的代码。 (我想知道为什么您的应用程序最初不会崩溃。)

我不确定您尝试达到的目标是100%。如果您可以共享拓扑代码可能会有所帮助?

请注意,KafkaStreams分片逻辑存储基于输入主题分区的数量(参见https://docs.confluent.io/current/streams/architecture.html)。也许您将分片与逻辑存储区混淆了?

如果要有两个逻辑存储,每个逻辑存储都有一个分片,则仍可以运行多个实例,并且这些存储将在不同的实例上执行(并且故障转移也将起作用)。但是,您仍然需要在启动时在两个实例上“包括”这两个存储。