Unable to connect Spring Boot application to Kafka messages having CDC events - java
I am having trouble in connecting my basic Spring Boot consumer application with the Apache Kafka that contains CDC events from Debezium. My consumer application is running separately on my host, while Kafka in running on the docker with following setup
kafka:
image: quay.io/debezium/kafka
ports:
- 29092:29092
- 19092:19092
links:
- zookeeper
environment:
- ZOOKEEPER_CONNECT=zookeeper:2181
- LOG_LEVEL=DEBUG
- LISTENERS=PLAINTEXT://:9092, CONNECTIONS_FROM_HOST://:29092, CONNECTIONS_FROM_OUTSIDE://:19092
- ADVERTISED_LISTENERS= PLAINTEXT://kafka:9092, CONNECTIONS_FROM_HOST://localhost:29092, CONNECTIONS_FROM_OUTSIDE://{ec2 instance ip address}:19092
- LISTENER_SECURITY_PROTOCOL_MAP=PLAINTEXT:PLAINTEXT, CONNECTIONS_FROM_HOST:PLAINTEXT, CONNECTIONS_FROM_OUTSIDE:PLAINTEXT
restart: on-failure
I already have a topic in my Kafka broker with the name "product_sb" that contains the CDC events from debezium that looks like this:
Key (166 bytes): {"schema":{"type":"struct","fields":[{"type":"int32","optional":false,"field":"id"}],"optional":false,"name":"dbserver1.inventory.product_sb.Key"},"payload":{"id":1}}
Value (2443 bytes): {"schema":{"type":"struct","fields":[{"type":"struct","fields":[{"type":"int32","optional":false,"field":"id"},{"type":"string","optional":true,"field":"name"},{"type":"double","optional":false,"field":"price"},{"type":"int32","optional":false,"field":"quantity"}],"optional":true,"name":"dbserver1.inventory.product_sb.Value","field":"before"},{"type":"struct","fields":[{"type":"int32","optional":false,"field":"id"},{"type":"string","optional":true,"field":"name"},{"type":"double","optional":false,"field":"price"},{"type":"int32","optional":false,"field":"quantity"}],"optional":true,"name":"dbserver1.inventory.product_sb.Value","field":"after"},{"type":"struct","fields":[{"type":"string","optional":false,"field":"version"},{"type":"string","optional":false,"field":"connector"},{"type":"string","optional":false,"field":"name"},{"type":"int64","optional":false,"field":"ts_ms"},{"type":"string","optional":true,"name":"io.debezium.data.Enum","version":1,"parameters":{"allowed":"true,last,false,incremental"},"default":"false","field":"snapshot"},{"type":"string","optional":false,"field":"db"},{"type":"string","optional":true,"field":"sequence"},{"type":"string","optional":true,"field":"table"},{"type":"int64","optional":false,"field":"server_id"},{"type":"string","optional":true,"field":"gtid"},{"type":"string","optional":false,"field":"file"},{"type":"int64","optional":false,"field":"pos"},{"type":"int32","optional":false,"field":"row"},{"type":"int64","optional":true,"field":"thread"},{"type":"string","optional":true,"field":"query"}],"optional":false,"name":"io.debezium.connector.mysql.Source","field":"source"},{"type":"string","optional":false,"field":"op"},{"type":"int64","optional":true,"field":"ts_ms"},{"type":"struct","fields":[{"type":"string","optional":false,"field":"id"},{"type":"int64","optional":false,"field":"total_order"},{"type":"int64","optional":false,"field":"data_collection_order"}],"optional":true,"field":"transaction"}],"optional":false,"name":"dbserver1.inventory.product_sb.Envelope"},"payload":{"before":null,"after":{"id":1,"name":"Laptop","price":170000.0,"quantity":1},"source":{"version":"1.9.5.Final","connector":"mysql","name":"dbserver1","ts_ms":1664161694254,"snapshot":"true","db":"inventory","sequence":null,"table":"product_sb","server_id":0,"gtid":null,"file":"mysql-bin.000002","pos":1684,"row":0,"thread":null,"query":null},"op":"r","ts_ms":1664161694258,"transaction":null}}
Partitio
n: 0 Offset: 0
The following is the Spring Boot application of consumer that is trying to connect to the Kafka
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Service;
#Service
public class KafkaConsumer {
private static final Logger LOGGER = LoggerFactory.getLogger(KafkaConsumer.class);
#KafkaListener(topics = "product_sb")
public void consume(String message){
LOGGER.info(String.format("Message received --> %s", message));
}
}
The following is the application.properties file for the consumer
#CONFIGURING CONSUMER
#Configuring address of the kafka server
spring.kafka.consumer.bootstrap-servers: localhost:29092
#Configuring consumer group
spring.kafka.consumer.group-id: mygroup
#Configure offset for consumer
spring.kafka.consumer.auto-offset-reset: earliest
#Key Value deserializer
spring.kafka.consumer.key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
spring.kafka.consumer.value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
While running the Spring Boot application, I am getting the following error:
org.apache.kafka.clients.NetworkClient : [Consumer clientId=consumer-mygroup-1, groupId=mygroup] Node -1 disconnected.
org.apache.kafka.clients.NetworkClient : [Consumer clientId=consumer-mygroup-1, groupId=mygroup] Cancelled in-flight API_VERSIONS request with correlation id 1 due to node -1 being disconnected (elapsed time since creation: 31ms, elapsed time since send: 31ms, request timeout: 30000ms)
org.apache.kafka.clients.NetworkClient : [Consumer clientId=consumer-mygroup-1, groupId=mygroup] Bootstrap broker localhost:29092 (id: -1 rack: null) disconnected
I have followed many articles but couldn't get my application working. I initially tried to connect my Spring Boot running on my host to the Kafka running on the ec2 instance but had the same issue.
Can anyone suggest solution for this?
It would also be useful if someone can help me with working on serialization and deserialization of event from debezium that is stored in the Kafka topic. The following are the configurations of the source connector I have used:
{
"name": "inventory-connector",
"config": {
"connector.class": "io.debezium.connector.mysql.MySqlConnector",
"tasks.max": "1",
"database.hostname": "proxysql",
"database.port": "6033",
"database.user": "root",
"database.password": "root",
"database.server.id": "184054",
"database.server.name": "dbserver1",
"database.include.list": "inventory",
"database.history.kafka.bootstrap.servers": "kafka:9092",
"database.history.kafka.topic": "schema-changes.inventory",
"transforms": "route",
"transforms.route.type": "org.apache.kafka.connect.transforms.RegexRouter",
"transforms.route.regex": "([^.]+)\\.([^.]+)\\.([^.]+)",
"transforms.route.replacement": "$3",
"gtid.new.channel.position": "earliest"
}
}
Related
Is there a "Circuit Breaker" for Spring Boot Kafka client?
In case that Kafka server is (temporarily) down, my Spring Boot application ReactiveKafkaConsumerTemplate keeps trying to connect unsuccessfully, thus causing unnecessary traffic and messing the log files: 2021-11-10 14:45:30.265 WARN 24984 --- [onsumer-group-1] org.apache.kafka.clients.NetworkClient : [Consumer clientId=consumer-group-1, groupId=consumer-group] Connection to node -1 (localhost/127.0.0.1:29092) could not be established. Broker may not be available. 2021-11-10 14:45:32.792 WARN 24984 --- [onsumer-group-1] org.apache.kafka.clients.NetworkClient : [Consumer clientId=consumer-group-1, groupId=consumer-group] Bootstrap broker localhost:29092 (id: -1 rack: null) disconnected 2021-11-10 14:45:34.845 WARN 24984 --- [onsumer-group-1] org.apache.kafka.clients.NetworkClient : [Consumer clientId=consumer-group-1, groupId=consumer-group] Connection to node -1 (localhost/127.0.0.1:29092) could not be established. Broker may not be available. 2021-11-10 14:45:34.845 WARN 24984 --- [onsumer-group-1] org.apache.kafka.clients.NetworkClient : [Consumer clientId=consumer-group-1, groupId=consumer-group] Bootstrap broker localhost:29092 (id: -1 rack: null) disconnected Is it possible to use something like a circuit breaker (an inspiration here or here), so the Spring Boot Kafka client in case of a failure (or even better a few consecutive failures) slows down the pace of its connection attempts, and returns to the normal pace only after the server is up again? Is there already a ready-made config parameter, or any other solution? I am aware of the parameter reconnect.backoff.ms, this is how I create the ReactiveKafkaConsumerTemplate bean: #Bean public ReactiveKafkaConsumerTemplate<String, MyEvent> kafkaConsumer(KafkaProperties properties) { final Map<String, Object> map = new HashMap<>(properties.buildConsumerProperties()); map.put(ConsumerConfig.GROUP_ID_CONFIG, "MyGroup"); map.put(ConsumerConfig.RECONNECT_BACKOFF_MS_CONFIG, 10_000L); final JsonDeserializer<DisplayCurrencyEvent> jsonDeserializer = new JsonDeserializer<>(); jsonDeserializer.addTrustedPackages("com.example.myapplication"); return new ReactiveKafkaConsumerTemplate<>( ReceiverOptions .<String, MyEvent>create(map) .withKeyDeserializer(new ErrorHandlingDeserializer<>(new StringDeserializer())) .withValueDeserializer(new ErrorHandlingDeserializer<>(jsonDeserializer)) .subscription(List.of("MyTopic"))); } And still the consumer is trying to connect every 3 seconds.
See https://kafka.apache.org/documentation/#consumerconfigs_retry.backoff.ms The base amount of time to wait before attempting to reconnect to a given host. This avoids repeatedly connecting to a host in a tight loop. This backoff applies to all connection attempts by the client to a broker. and https://kafka.apache.org/documentation/#consumerconfigs_reconnect.backoff.max.ms The maximum amount of time in milliseconds to wait when reconnecting to a broker that has repeatedly failed to connect. If provided, the backoff per host will increase exponentially for each consecutive connection failure, up to this maximum. After calculating the backoff increase, 20% random jitter is added to avoid connection storms. and
Kafka Consumer in spring can I re-assign partitions programmatically?
I'm new to Kafka, and using #KafkaListener (spring) to define kafka consumer. I would like to check whether its possible to manually assign the partition to the consumer in runtime. For example, when the application starts I don't want to "consume" any data. I'm using currently #KafkaListener(autoStartup=false ... ) for that purpose. At some point, I'm supposed to get a notification (from another part of the application) that contains a partitionId to work on, so I would like to "skip" to the latest available offset of that partition because I don't need to consume the data that has happened to already exist there and "associate" the KafkaConsumer with the partitionId from that notification. Later on I might get a notification to "Stop listening to this partition", despite the fact the the producer that exists somewhere else keeps writing to that topic and to that partition, so I should "unlink" the consumer from the partition and stop getting messages. I saw there is a org.springframework.kafka.annotation.TopicPartition but it provides a way to specify a "static" association, so I'm looking for a "dynamic" way to do so. I guess I could resort to the low-level Kafka Client API but I would really prefer to use spring here. UPDATE I use topic cnp_multi_partition_test_topic with 3 partitions. My Current Code that tries to manage partitions dynamically from the consumer looks like this: #Slf4j public class SampleKafkaConsumer { #KafkaListener(id = Constants.CONSUMER_ID, topics = Constants.TEST_TOPIC, autoStartup = "false") public void consumePartition(#Payload String data, #Headers MessageHeaders messageHeaders) { Object partitionId = messageHeaders.get(KafkaHeaders.RECEIVED_PARTITION_ID); Object sessionId = messageHeaders.get(KafkaHeaders.RECEIVED_MESSAGE_KEY); log.info("Consuming from partition: [ {} ] message: Key = [ {} ], content = [ {} ]",partitionId, sessionId, data); } } #RequiredArgsConstructor public class MultiPartitionKafkaConsumerManager { private final KafkaListenerEndpointRegistry registry; private final ConcurrentKafkaListenerContainerFactory<String, String> factory; private final UUIDProvider uuidProvider; private ConcurrentMessageListenerContainer<String, String> container; public void assignPartitions(List<Integer> partitions) { if(container != null) { container.stop(); container = null; } if(partitions.isEmpty()) { return; } var newTopicPartitionOffsets = prepareTopicPartitionOffsets(partitions); container = factory.createContainer(newTopicPartitionOffsets); container.getContainerProperties().setMessageListener( registry.getListenerContainer(Constants.CONSUMER_ID).getContainerProperties().getMessageListener()); // random group container.getContainerProperties().setGroupId("sampleGroup-" + uuidProvider.getUUID().toString()); container.setConcurrency(1); container.start(); } private TopicPartitionOffset[] prepareTopicPartitionOffsets(List<Integer> partitions) { return partitions.stream() .map(p -> new TopicPartitionOffset(TEST_TOPIC, p, 0L, TopicPartitionOffset.SeekPosition.END)) .collect(Collectors.toList()) .toArray(new TopicPartitionOffset[] {}); } } Both are Spring beans (singletons) managed through java configuration. The producer is generating 3 messages every second and sends it into 3 partitions of the test topic. I've used kafka UI tool to make sure that indeed all the messages arrive as expected I use an #EventListener and #Async to make it happen concurrently. Here is how do I try to simulate the work: #SpringBootTest // kafka is available, omitted for brevity public class MyTest { #Autowired MultiPartitionKafkaConsumerManager manager; #Test public void test_create_kafka_consumer_with_manual_partition_management() throws InterruptedException { log.info("Starting the test"); sleep(5_000); log.info("Start listening on partition 0"); manager.assignPartitions(List.of(0)); sleep(10_000); log.info("Start listening on partition 0,2"); manager.assignPartitions(List.of(0,2)); sleep(10_000); log.info("Do not listen on partition 0 anymore"); manager.assignPartitions(List.of(2)); sleep(10_000); log.info("Do not listen on partition 2 anymore - 0 partitions to listen"); manager.assignPartitions(Collections.emptyList()); sleep(10_000); Logs show the following: 06:34:20.164 [main] INFO c.h.c.p.g.m.SamplePartitioningTest - Starting the test 06:34:25.169 [main] INFO c.h.c.p.g.m.SamplePartitioningTest - Start listening on partition 0 06:34:25.360 [main] INFO o.a.kafka.common.utils.AppInfoParser - Kafka version: 2.5.1 06:34:25.360 [main] INFO o.a.kafka.common.utils.AppInfoParser - Kafka commitId: 0efa8fb0f4c73d92 06:34:25.361 [main] INFO o.a.kafka.common.utils.AppInfoParser - Kafka startTimeMs: 1633664065360 06:34:25.405 [main] INFO o.a.k.clients.consumer.KafkaConsumer - [Consumer clientId=consumer-sampleGroup-96640bc4-e34f-4ade-9ff9-7a2d0bdf38c9-1, groupId=sampleGroup-96640bc4-e34f-4ade-9ff9-7a2d0bdf38c9] Subscribed to partition(s): cnp_multi_partition_test_topic-0 06:34:25.422 [main] INFO o.s.s.c.ThreadPoolTaskScheduler - Initializing ExecutorService 06:34:25.429 [consumer-0-C-1] INFO o.a.k.c.c.i.SubscriptionState - [Consumer clientId=consumer-sampleGroup-96640bc4-e34f-4ade-9ff9-7a2d0bdf38c9-1, groupId=sampleGroup-96640bc4-e34f-4ade-9ff9-7a2d0bdf38c9] Seeking to LATEST offset of partition cnp_multi_partition_test_topic-0 06:34:35.438 [main] INFO c.h.c.p.g.m.SamplePartitioningTest - Start listening on partition 0,2 06:34:35.445 [consumer-0-C-1] INFO o.a.k.clients.consumer.KafkaConsumer - [Consumer clientId=consumer-sampleGroup-96640bc4-e34f-4ade-9ff9-7a2d0bdf38c9-1, groupId=sampleGroup-96640bc4-e34f-4ade-9ff9-7a2d0bdf38c9] Unsubscribed all topics or patterns and assigned partitions 06:34:35.445 [consumer-0-C-1] INFO o.s.s.c.ThreadPoolTaskScheduler - Shutting down ExecutorService 06:34:35.453 [consumer-0-C-1] INFO o.s.k.l.KafkaMessageListenerContainer$ListenerConsumer - sampleGroup-96640bc4-e34f-4ade-9ff9-7a2d0bdf38c9: Consumer stopped 06:34:35.467 [main] INFO o.a.kafka.common.utils.AppInfoParser - Kafka version: 2.5.1 06:34:35.467 [main] INFO o.a.kafka.common.utils.AppInfoParser - Kafka commitId: 0efa8fb0f4c73d92 06:34:35.467 [main] INFO o.a.kafka.common.utils.AppInfoParser - Kafka startTimeMs: 1633664075467 06:34:35.486 [main] INFO o.a.k.clients.consumer.KafkaConsumer - [Consumer clientId=consumer-sampleGroup-05fb12f3-aba1-4918-bcf6-a1f840de13eb-2, groupId=sampleGroup-05fb12f3-aba1-4918-bcf6-a1f840de13eb] Subscribed to partition(s): cnp_multi_partition_test_topic-0, cnp_multi_partition_test_topic-2 06:34:35.487 [main] INFO o.s.s.c.ThreadPoolTaskScheduler - Initializing ExecutorService 06:34:35.489 [consumer-0-C-1] INFO o.a.k.c.c.i.SubscriptionState - [Consumer clientId=consumer-sampleGroup-05fb12f3-aba1-4918-bcf6-a1f840de13eb-2, groupId=sampleGroup-05fb12f3-aba1-4918-bcf6-a1f840de13eb] Seeking to LATEST offset of partition cnp_multi_partition_test_topic-0 06:34:35.489 [consumer-0-C-1] INFO o.a.k.c.c.i.SubscriptionState - [Consumer clientId=consumer-sampleGroup-05fb12f3-aba1-4918-bcf6-a1f840de13eb-2, groupId=sampleGroup-05fb12f3-aba1-4918-bcf6-a1f840de13eb] Seeking to LATEST offset of partition cnp_multi_partition_test_topic-2 06:34:45.502 [main] INFO c.h.c.p.g.m.SamplePartitioningTest - Do not listen on partition 0 anymore 06:34:45.503 [consumer-0-C-1] INFO o.a.k.clients.consumer.KafkaConsumer - [Consumer clientId=consumer-sampleGroup-05fb12f3-aba1-4918-bcf6-a1f840de13eb-2, groupId=sampleGroup-05fb12f3-aba1-4918-bcf6-a1f840de13eb] Unsubscribed all topics or patterns and assigned partitions 06:34:45.503 [consumer-0-C-1] INFO o.s.s.c.ThreadPoolTaskScheduler - Shutting down ExecutorService 06:34:45.510 [consumer-0-C-1] INFO o.s.k.l.KafkaMessageListenerContainer$ListenerConsumer - sampleGroup-05fb12f3-aba1-4918-bcf6-a1f840de13eb: Consumer stopped 06:34:45.527 [main] INFO o.a.kafka.common.utils.AppInfoParser - Kafka version: 2.5.1 06:34:45.527 [main] INFO o.a.kafka.common.utils.AppInfoParser - Kafka commitId: 0efa8fb0f4c73d92 06:34:45.527 [main] INFO o.a.kafka.common.utils.AppInfoParser - Kafka startTimeMs: 1633664085527 06:34:45.551 [main] INFO o.a.k.clients.consumer.KafkaConsumer - [Consumer clientId=consumer-sampleGroup-5e12d8c7-5900-434a-959f-98b14adda698-3, groupId=sampleGroup-5e12d8c7-5900-434a-959f-98b14adda698] Subscribed to partition(s): cnp_multi_partition_test_topic-2 06:34:45.551 [main] INFO o.s.s.c.ThreadPoolTaskScheduler - Initializing ExecutorService 06:34:45.554 [consumer-0-C-1] INFO o.a.k.c.c.i.SubscriptionState - [Consumer clientId=consumer-sampleGroup-5e12d8c7-5900-434a-959f-98b14adda698-3, groupId=sampleGroup-5e12d8c7-5900-434a-959f-98b14adda698] Seeking to LATEST offset of partition cnp_multi_partition_test_topic-2 06:34:55.560 [main] INFO c.h.c.p.g.m.SamplePartitioningTest - Do not listen on partition 2 anymore - 0 partitions to listen 06:34:55.561 [consumer-0-C-1] INFO o.a.k.clients.consumer.KafkaConsumer - [Consumer clientId=consumer-sampleGroup-5e12d8c7-5900-434a-959f-98b14adda698-3, groupId=sampleGroup-5e12d8c7-5900-434a-959f-98b14adda698] Unsubscribed all topics or patterns and assigned partitions 06:34:55.562 [consumer-0-C-1] INFO o.s.s.c.ThreadPoolTaskScheduler - Shutting down ExecutorService 06:34:55.576 [consumer-0-C-1] INFO o.s.k.l.KafkaMessageListenerContainer$ListenerConsumer - sampleGroup-5e12d8c7-5900-434a-959f-98b14adda698: Consumer stopped So I do see that the consumer is started, it even tries to poll the records internally, but I think I see the WakeupException thrown and "swallowed" by a proxy. I'm not sure I understand why does it happen?
You can't change manual assignments at runtime. There are several ways to achieve your desired result. You can declare the listener in a prototype bean; see Can i add topics to my #kafkalistener at runtime You can use the listener container factory to create a new container with the appropriate topic configuration and copy the listener from the statically declared container. I can provide an example of the latter if needed. ... EDIT Here's an example for the second technique... #SpringBootApplication public class So69465733Application { public static void main(String[] args) { SpringApplication.run(So69465733Application.class, args); } #KafkaListener(id = "dummy", topics = "dummy", autoStartup = "false") void listen(String in) { System.out.println(in); } #Bean ApplicationRunner runner(KafkaListenerEndpointRegistry registry, ConcurrentKafkaListenerContainerFactory<String, String> factory) { return args -> { System.out.println("Hit Enter to create a container for topic1, partition0"); System.in.read(); ConcurrentMessageListenerContainer<String, String> container1 = factory.createContainer(new TopicPartitionOffset("topic1", 0, SeekPosition.END)); container1.getContainerProperties().setMessageListener( registry.getListenerContainer("dummy").getContainerProperties().getMessageListener()); container1.getContainerProperties().setGroupId("topic1-0-group2"); container1.start(); System.out.println("Hit Enter to create a container for topic2, partition0"); System.in.read(); ConcurrentMessageListenerContainer<String, String> container2 = factory.createContainer(new TopicPartitionOffset("topic2", 0, SeekPosition.END)); container2.getContainerProperties().setMessageListener( registry.getListenerContainer("dummy").getContainerProperties().getMessageListener()); container2.getContainerProperties().setGroupId("topic2-0-group2"); container2.start(); System.in.read(); container1.stop(); container2.stop(); }; } } EDIT Log after sending records to topic1, topic2 from the command-line producer. Hit Enter to create a container for topic1, partition0 ConsumerConfig values: ... Kafka version: 2.7.1 Kafka commitId: 61dbce85d0d41457 Kafka startTimeMs: 1633622966736 [Consumer clientId=consumer-topic1-0-group2-1, groupId=topic1-0-group2] Subscribed to partition(s): topic1-0 Hit Enter to create a container for topic2, partition0 [Consumer clientId=consumer-topic1-0-group2-1, groupId=topic1-0-group2] Seeking to LATEST offset of partition topic1-0 [Consumer clientId=consumer-topic1-0-group2-1, groupId=topic1-0-group2] Cluster ID: ppGfIGsZTUWRTNmRXByfZg [Consumer clientId=consumer-topic1-0-group2-1, groupId=topic1-0-group2] Resetting offset for partition topic1-0 to position FetchPosition{offset=2, offsetEpoch=Optional.empty, currentLeader=LeaderAndEpoch{leader=Optional[localhost:9092 (id: 0 rack: null)], epoch=0}}. ConsumerConfig values: ... Kafka version: 2.7.1 Kafka commitId: 61dbce85d0d41457 Kafka startTimeMs: 1633622969071 [Consumer clientId=consumer-topic2-0-group2-2, groupId=topic2-0-group2] Subscribed to partition(s): topic2-0 Hit Enter to stop containers [Consumer clientId=consumer-topic2-0-group2-2, groupId=topic2-0-group2] Seeking to LATEST offset of partition topic2-0 [Consumer clientId=consumer-topic2-0-group2-2, groupId=topic2-0-group2] Cluster ID: ppGfIGsZTUWRTNmRXByfZg [Consumer clientId=consumer-topic2-0-group2-2, groupId=topic2-0-group2] Resetting offset for partition topic2-0 to position FetchPosition{offset=2, offsetEpoch=Optional.empty, currentLeader=LeaderAndEpoch{leader=Optional[localhost:9092 (id: 0 rack: null)], epoch=0}}. record from topic1 [Consumer clientId=consumer-topic1-0-group2-1, groupId=topic1-0-group2] Discovered group coordinator localhost:9092 (id: 2147483647 rack: null) record from topic2 [Consumer clientId=consumer-topic2-0-group2-2, groupId=topic2-0-group2] Discovered group coordinator localhost:9092 (id: 2147483647 rack: null) Application shutdown requested.
kafka consumer try to connect to random hostname instead right one
I'm new to Kafka and started exploring with sample program. It used to work without any issue but all of sudden consumer.poll() command hangs and never returns. Googling suggested to check the servers are accessible. Producer and Consumer java code runs in same machine, where producer able to post record to Kafka, but consumer poll method hangs. Environment: Kafka version: 1.1.0 Client: Java Runs in Ubuntu docker container inside windows Zookeeper and 2 Broker servers runs in same container When I have enabled logging for client code, I see below exception: 2018-07-06 21:24:18 DEBUG NetworkClient:802 - [Consumer clientId=consumer-1, groupId=IDCS_Audit_Event_Consumer] Error connecting to node 4bdce773eb74:9095 (id: 2 rack: null) java.io.IOException: Can't resolve address: 4bdce773eb74:9095 at org.apache.kafka.common.network.Selector.doConnect(Selector.java:235) at org.apache.kafka.common.network.Selector.connect(Selector.java:214) ................. ................. I'm not sure why consumer trying to connect to 4bdce773eb74 even though my broker servers are 192.168.99.100:9094,192.168.99.100:9095. And my full consumer code: final String BOOTSTRAP_SERVERS = "192.168.99.100:9094,192.168.99.100:9095"; final Properties props = new Properties(); props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, BOOTSTRAP_SERVERS); props.put(ConsumerConfig.GROUP_ID_CONFIG, "Event_Consumer"); props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, LongDeserializer.class.getName()); props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName()); KafkaConsumer<Long, String> consumer = new KafkaConsumer<Long, String>(props); TopicPartition tpLogin = new TopicPartition("login1", 0); TopicPartition tpLogout = new TopicPartition("logout1", 1); List<TopicPartition> tps = Arrays.asList(tpLogin, tpLogout); consumer.assign(tps); while (true) { final ConsumerRecords<Long, String> consumerRecords = consumer.poll(1000); if (consumerRecords.count()==0) { continue; } consumerRecords.forEach(record -> { System.out.printf("Consumer Record:(%d, %s, %d, %d)\n", record.key(), record.value(), record.partition(), record.offset()); }); consumer.commitAsync(); Thread.sleep(5000); } } Please help in this issue. EDIT As I said earlier, I have 2 brokers, say broker-1 and broker-2. If I stop broker-1, then above exception is not logged, but still poll() method didn't returns. Below message logged indefinitely, if I stop broker-1: 2018-07-07 11:31:24 DEBUG AbstractCoordinator:579 - [Consumer clientId=consumer-1, groupId=IDCS_Audit_Event_Consumer] Sending FindCoordinator request to broker 192.168.99.100:9094 (id: 1 rack: null) 2018-07-07 11:31:24 DEBUG AbstractCoordinator:590 - [Consumer clientId=consumer-1, groupId=IDCS_Audit_Event_Consumer] Received FindCoordinator response ClientResponse(receivedTimeMs=1530943284196, latencyMs=2, disconnected=false, requestHeader=RequestHeader(apiKey=FIND_COORDINATOR, apiVersion=1, clientId=consumer-1, correlationId=573), responseBody=FindCoordinatorResponse(throttleTimeMs=0, errorMessage='null', error=COORDINATOR_NOT_AVAILABLE, node=:-1 (id: -1 rack: null))) 2018-07-07 11:31:24 DEBUG AbstractCoordinator:613 - [Consumer clientId=consumer-1, groupId=IDCS_Audit_Event_Consumer] Group coordinator lookup failed: The coordinator is not available. 2018-07-07 11:31:24 DEBUG AbstractCoordinator:227 - [Consumer clientId=consumer-1, groupId=IDCS_Audit_Event_Consumer] Coordinator discovery failed, refreshing metadata Thanks in Advance, Soman
I found the issue. When I'm creating topic, broker-0(runs on port:9093; broker id:0) and broker-2(runs on port:9094; broker id:2) was running. Today I have mistakenly started broker-1(runs on port:9095; broker id:1) and broker-2. After stopping broker-1 and starting broker-0, resolves the issue. Now consumer able to get the events. Definitely human error from my side, but I have 2 comments: I think Kafka should gracefully use broker-2(port no:9094) and ignore broker-1(port no:9095) why Kafka trying to contact 4bdce773eb74:9095, instead of right IP address(192.168.99.100)? thanks.
Apache Kafka Cluster start fails with NoNodeException
I'm trying to start a spark streaming session which consumes from a Kafka queue and I'm using Zookeeper for config mgt. However, when I try to start this following exception is being thrown. 18/03/26 09:25:49 INFO ZookeeperConnection: Checking Kafka topic core-data-tickets does exists ... 18/03/26 09:25:49 INFO Broker: Kafka topic core-data-tickets exists 18/03/26 09:25:49 INFO Broker: Processing topic : core-data-tickets 18/03/26 09:25:49 WARN ZookeeperConnection: Resetting Topic Offset org.I0Itec.zkclient.exception.ZkNoNodeException: org.apache.zookeeper.KeeperException$NoNodeException: KeeperErrorCode = NoNode for /consumers/clt/offsets/core-data-tickets/4 at org.I0Itec.zkclient.exception.ZkException.create(ZkException.java:47) at org.I0Itec.zkclient.ZkClient.retryUntilConnected(ZkClient.java:685) at org.I0Itec.zkclient.ZkClient.readData(ZkClient.java:766) at org.I0Itec.zkclient.ZkClient.readData(ZkClient.java:761) at kafka.utils.ZkUtils$.readData(ZkUtils.scala:443) at kafka.utils.ZkUtils.readData(ZkUtils.scala) at net.core.data.connection.ZookeeperConnection.readTopicPartitionOffset(ZookeeperConnection.java:145) I have already created the relevant Kafka topic. Any insights on this would be highly appreciated. # I'm using the following code to run the spark job spark-submit --class net.core.data.compute.Broker --executor-memory 512M --total-executor-cores 2 --driver-java-options "-Dproperties.path=/ebs/tmp/continuous-loading-tool/continuous-loading-tool/src/main/resources/dev.properties" --conf spark.ui.port=4045 /ebs/tmp/dev/data/continuous-loading-tool/target/continuous-loading-tool-1.0-SNAPSHOT.jar
I guess that this error has to do with offsets retention. By default, offsets are stored for only 1440 minutes (i.e. 24 hours). Therefore, if the group has not committed offsets within a day, Kafka won't have information about it. A possible workaround is to set the value of offsets.retention.minutes accordingly. offsets.retention.minutes Offsets older than this retention period will be discarded
The group coordinator is not available-Kafka
When I am write a topic to kafka,there is an error:Offset commit failed: 2016-10-29 14:52:56.387 INFO [nioEventLoopGroup-3-1][org.apache.kafka.common.utils.AppInfoParser$AppInfo:82] - Kafka version : 0.9.0.1 2016-10-29 14:52:56.387 INFO [nioEventLoopGroup-3-1][org.apache.kafka.common.utils.AppInfoParser$AppInfo:83] - Kafka commitId : 23c69d62a0cabf06 2016-10-29 14:52:56.409 ERROR [nioEventLoopGroup-3-1][org.apache.kafka.clients.consumer.internals.ConsumerCoordinator$DefaultOffsetCommitCallback:489] - Offset commit failed. org.apache.kafka.common.errors.GroupCoordinatorNotAvailableException: The group coordinator is not available. 2016-10-29 14:52:56.519 WARN [kafka-producer-network-thread | producer-1][org.apache.kafka.clients.NetworkClient$DefaultMetadataUpdater:582] - Error while fetching metadata with correlation id 0 : {0085000=LEADER_NOT_AVAILABLE} 2016-10-29 14:52:56.612 WARN [pool-6-thread-1][org.apache.kafka.clients.NetworkClient$DefaultMetadataUpdater:582] - Error while fetching metadata with correlation id 1 : {0085000=LEADER_NOT_AVAILABLE} When create a new topic using command,it is ok. ./kafka-topics.sh --zookeeper localhost:2181 --create --topic test1 --partitions 1 --replication-factor 1 --config max.message.bytes=64000 --config flush.messages=1 This is the producer code using Java: public void create() { Properties props = new Properties(); props.clear(); String producerServer = PropertyReadHelper.properties.getProperty("kafka.producer.bootstrap.servers"); String zookeeperConnect = PropertyReadHelper.properties.getProperty("kafka.producer.zookeeper.connect"); String metaBrokerList = PropertyReadHelper.properties.getProperty("kafka.metadata.broker.list"); props.put("bootstrap.servers", producerServer); props.put("zookeeper.connect", zookeeperConnect);//声明ZooKeeper props.put("metadata.broker.list", metaBrokerList);//声明kafka broker props.put("acks", "all"); props.put("retries", 0); props.put("batch.size", 1000); props.put("linger.ms", 10000); props.put("buffer.memory", 10000); props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer"); producer = new KafkaProducer<String, String>(props); } Where is wrong?
I faced a similar issue. The problem was when you start your Kafka broker there is a property associated with it, "KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR". If you are working with a single node cluster make sure you set this property with the value '1'. As its default value is 3. This change resolved my problem. (you can check the value in Kafka.properties file) Note: I was using base image of confluent kafka version 4.0.0 ( confluentinc/cp-kafka:4.0.0)
Looking at your logs the problem is that cluster probably don't have connection to node which is the only one know replica of given topic in zookeeper. You can check it using given command: kafka-topics.sh --describe --zookeeper localhost:2181 --topic test1 or using kafkacat: kafkacat -L -b localhost:9092 Example result: Metadata for all topics (from broker 1003: localhost:9092/1003): 1 brokers: broker 1003 at localhost:9092 1 topics: topic "topic1" with 1 partitions: partition 0, leader -1, replicas: 1001, isrs: , Broker: Leader not available If you have single node cluster then broker id(1001) should match leader of topic1 partition. But as you can see the only one known replica of topic1 was 1001 - which is not available now, so there is no possibility to recreate topic on different node. The source of the problem can be an automatic generation of broker id(if you don't have specified broker.id or it is set to -1). Then on starting the broker(the same single broker) you probably receive broker id different that previously and different than was marked in zookeeper (this a reason why partition deletion can help - but it is not a production solution). The solution may be setting broker.id value in node config to fixed value - according to documentation it should be done on produciton environment: broker.id=1 If everything is alright you should receive sth like this: Metadata for all topics (from broker 1: localhost:9092/1001): 1 brokers: broker 1 at localhost:9092 1 topics: topic "topic1" with 1 partitions: partition 0, leader 1, replicas: 1, isrs: 1 Kafka Documentation: https://kafka.apache.org/documentation/#prodconfig
Hi you have to keep your kafka replicas and replication factor for your code same. for me i keep 3 as replicas and 3 as replication factor.
The solution for me was that I had to make sure KAFKA_ADVERTISED_HOST_NAME was the correct IP address of the server.
We had the same issue and replicas and replication factors both were 3. and the Partition count was 1 . I increased the partition count to 10 and it started working.
We faced same issue in production too. The code was working fine for long time suddenly we got this exception. We analyzed that there is no issue in code. So we asked deployment team to restart the zookeeper. Restarting it solved the issue.