Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kafka::Client#deliver_message does not refresh metadata of a stale cluster #900

Closed
wamaral opened this issue May 6, 2021 · 0 comments · Fixed by #901
Closed

Kafka::Client#deliver_message does not refresh metadata of a stale cluster #900

wamaral opened this issue May 6, 2021 · 0 comments · Fixed by #901

Comments

@wamaral
Copy link
Contributor

wamaral commented May 6, 2021

When using Kafka::Client#deliver_message, the producer is not able to recover when the broker who is the leader of the partition goes offline, even after the Kafka cluster assigns a new leader for the partition. This is true even if the method is called with retries enabled - all retries will be exhausted and finally an error will be raised

I noticed the Kafka::Producer interface does not have this issue: when the leader broker goes offline, subsequent retries are able to fetch the new topology from the cluster, and the producer is able to target the newly assigned leader

Upon inspection, both Kafka::Client#deliver_message and Kafka::Producer#deliver_messages_with_retries will mark the cluster as stale whenever they are not able to connect to the broker:

After the cluster is marked as stale, and upon subsequent retries, Kafka::Producer#deliver_messages_with_retries will trigger a metadata refresh on the cluster, as expected:

However, Kafka::Client#deliver_message does not trigger the metadata refresh:

This means that retries in Kafka::Client#deliver_message will always try to hit the leader broker that it can find in the current cache in memory, and this does not account for the situation where the broker is no longer available


I have a working fix which consists of merely adding @cluster.refresh_metadata_if_necessary! just before this line, I will submit it in a PR after I run more extensive tests in our live cluster


Steps to reproduce

Not so trivial. You should have a cluster with at least 3 brokers running, so that it's able to run an election when one of the brokers is killed.

Leave this code running, and kill the broker who is the leader of the partition 0:

kafka = Kafka.new(...)
1.upto(1000).to_a.each do |i|
  kafka.deliver_message(i.to_s, topic: "test_topic", retries: 5, partition: 0)
  sleep 1
end
Expected outcome

deliver_message retries, fetching the new topology from the cluster, and resume producing messages to the newly elected leader

Actual outcome

deliver_message retries always trying to produce messages to the broker that was killed, eventually raising an error

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant