Apache kafka 如何在暴风雨中制作同步卡夫卡

Apache kafka 如何在暴风雨中制作同步卡夫卡,apache-kafka,apache-storm,Apache Kafka,Apache Storm,我试图使卡夫卡消费者同步消费卡夫卡的消息 我遇到的实际问题是消息队列存储在Storm Spout中 我想做的是让暴风雪等待卡夫卡的回复,然后让暴风雪消耗下一条信息 我正在使用Storm KafkaSpout: /** * Creates a configured kafka spout. * @param topicName Topic where the kafka spout subscribes * @return An instance of configu

我试图使卡夫卡消费者同步消费卡夫卡的消息

我遇到的实际问题是消息队列存储在Storm Spout中

我想做的是让暴风雪等待卡夫卡的回复,然后让暴风雪消耗下一条信息

我正在使用Storm KafkaSpout:

/**
     * Creates a configured kafka spout.
     * @param topicName Topic where the kafka spout subscribes
     * @return An instance of configured KafkaSpout
     */
    public KafkaSpout getkafkaSpout(String topicName){
        return new KafkaSpout(this.getSpoutConfig(topicName));
    }

    /**
     * Create the necessary configuration to create a new kafka spout.
     * @param topicName Topic where the kafka spout subscribes
     * @return Spout configuration
     */
    public SpoutConfig getSpoutConfig(String topicName) {
        SpoutConfig spoutConfig=new SpoutConfig(this.getZkHosts(),topicName, "", String.join("-",topicName,RandomStringUtils.randomAlphanumeric(20)));
        spoutConfig.scheme = new SchemeAsMultiScheme(new StringScheme());
        spoutConfig.startOffsetTime=kafka.api.OffsetRequest.LatestTime();
        return spoutConfig;
    }



builder.setSpout("kafkaPackedData", stormConfig.getkafkaSpout("topic_kafka"), 2);
我已经更新到Storm 2.0.0,我使用Storm kafka客户端。但是如果我配置 风暴队列为50:
setMaxSpoutPending(50)当我向卡夫卡发送许多数据时,它会停止使用这些数据

我已使用下一个配置配置Kafka consumer:

KafkaSpoutConfig spoutConf =  KafkaSpoutConfig.builder("stream1:9092", "kafkaToStormAlarms")
                    .setProp(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, "50000") //Set session timeout
                    .setProp(ConsumerConfig.REQUEST_TIMEOUT_MS_CONFIG, "60000") //Set request timeout
                    .setOffsetCommitPeriodMs(10000)    //Set automatic confirmation time (in ms)
                    .setFirstPollOffsetStrategy(LATEST)    //Set to pull the latest messages
                    .setRetry(kafkaSpoutRetryService)
                    .build();
当Storm使用与MaxSpoutPending配置相同的50条消息时,它将停止使用更多消息。也许下一个螺栓没有正确发送ACK?我使用Kafkaconsumerspoot之后的下一个螺栓:

public class testBolt extends BaseBasicBolt {

    @Override
    public void declareOutputFields(OutputFieldsDeclarer declarer) {
        declarer.declare(new Fields("MQTTmessage"));
    }

    @Override
    public void execute(Tuple tuple, BasicOutputCollector boc) {
        System.out.println("\n\n\n\nLLEGA BIENN AL SPLIT TEXT BOLT\n\n");
        System.out.println("TUPLE "+tuple);
        String text = tuple.getString(4);
        List<String> lines = Arrays.asList(text.split("\\r?\\n"));

        lines.forEach(line -> {
            boc.emit(new Values(line));
        });
    }
}
public类testBolt扩展了BaseBasicBolt{
@凌驾
公共无效申报输出字段(OutputFields申报器申报器){
declarer.declare(新字段(“MQTTmessage”);
}
@凌驾
public void execute(Tuple Tuple,BasicOutputCollector boc){
System.out.println(“\n\n\n\nlega BIENN AL SPLIT TEXT BOLT\n\n”);
System.out.println(“TUPLE”+TUPLE);
String text=tuple.getString(4);
列表行=数组.asList(text.split(\\r?\\n”);
行。forEach(行->{
boc.排放(新值(行));
});
}
}

关于节流喷嘴:是的,您可以通过将拓扑配置中的
拓扑.max.spout.pending
选项设置为
1
来实现这一点。如果您想获得良好的吞吐量,我不推荐使用它,但我假设您已经仔细考虑了为什么需要拓扑以这种方式运行

关于新的喷口:
stream1:9092
是Kafka正在运行的服务器吗,以及
kafkaToStormAlarms
是您要发送到的主题吗?如果不是,那可能是你的问题。否则,请在
storm/logs/workers artifacts
中检查工作日志,它可能会告诉您喷口没有排放任何东西的原因


最后,是的,您绝对应该使用
storm kafka客户端
而不是
storm kafka
,否则您将无法升级到storm 2.0.0或最新的卡夫卡版本

对不起,也许我的问题不太清楚。例如,我可以使用值为50的topology.max.spout.pending。但如果卡夫卡处理90条消息,Storm只能在他的队列中存储50条,那么我将丢失40条消息。我的问题发生了,当topology.max.spout.pending处于最大值时,它会丢失消息。当我在卡夫卡中插入许多信息时就会发生这种情况。也许使用Storm 2.0.0和卡夫卡的新客户端“Storm Kafka客户端”可以更好地工作?是的,我的卡夫卡服务器是stream1:9092,主题是卡夫卡。我正在测试。是的,请切换到
storm kafka client
。这里有一个例子说明了如何使用它。新的喷口永远不会丢失消息,除非您将其配置为跳过消息。我只是切换到Storm 2.1.0、kafka client 2.3.1和kafka server 2.3.1。但问题仍然存在。如果我有喷口最大队列50,并且我在卡夫卡前1秒添加了许多数据,一段时间后,Storm停止从卡夫卡消耗数据。可能是什么?(如果我让Storm Spout队列变大,效果会更好,但如果我更快速地发送数据,它也会失败)您确认元组正确吗?也许你的一个或多个螺栓有时不确认元组?试着在你的拓扑结构中只使用一个螺栓来确认。如果问题消失了,最有可能的一个螺栓没有确认元组。我用下一个非常简单的螺栓进行了测试,它工作正常。因为它会在打印后发送ACK。public void execute(Tuple Tuple){System.out.println(“OK”);collector.ack(Tuple);}但是如果我有一个更复杂的Bolt,它将所有Kafka消息存储在喷口队列中,如果队列已满,它将丢失消息。这是不可能控制的吗?