-
Notifications
You must be signed in to change notification settings - Fork 3.2k
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
No error callback and hanging when publishing to non existent partition #39
Comments
Actually looks like eventually (5 minutes but I believe configurable) you get a msg delivery callback with a 'Local: Message timed out'. So I guess I the end I'm requesting to get a callback as soon as it's known the partition is wrong |
The thing is that the partition might not be available because the broker is down or connectivity to the broker is down, librdkafka cant really know, so it will hold on to the message for as long as the local message timeout is configured (message.timeout.ms, defaults to 5 minutes), before failing the message. If you provide your own partitioner function you can use rd_kafka_topic_partition_available() to check if a partition is available (has a leader broker) before producing to it. |
I haven't looked too deeply into librdkafka's metadata information, but is it able to get from the broker the number of partitions that have been configured for a particular topic? If so, I might be able to use that. Right now, I force the user of my app to tell me the number of partitions there are - I'd rather it be more dynamic/automatic. |
If you configure a custom partitioner with rd_kafka_topic_set_partitioner_cb() it will be called for each message, and one of its arguments is Partitioning is usually done for one of two reasons:
In the latter case the partitioner must have some kind of information to make its partition decision on, and that information is the optional |
To be clear, is 'partition_cnt' the number of partitions that are currently available (as in the servers are up and running) or configured on the broker. I was hoping for the latter but having a feeling it's the former? My use case is that I need to make sure certain streams always go to the same partition and don't want it to be random. I don't care which partition is initially chosen for a stream, but I do care that no matter what, once chosen it stays there. |
You can use |
So here's where I'm confused. My original question was whether or not librdkafka could be enhanced to reject my produce attempt when it I attempt to send to a particular partition # if it's actually beyond the number configured for that topic (remember the 0-9 vs. #10 example). It would seem then (based on your response about partition_cnt) that librdkafka does know the number configured and therefore could in fact be enhanced to reject it. Did I get that right? |
librdkafka is asynchronous by nature: an appplication does not need to care or know about the current state of brokers, connectivty, etc. librdkafka takes care of queuing messages when brokers are down, resending when broker leaders change, and reporting back to the application when all attempts have failed. It is thus not safe to discard a message at produce() time because a partition is not available: the application might have started to produce message's before the initial broker connection has been set up, or before all relevant brokers have been connected to - rejecting a message at this point is not helpful for the application and just leads to timing issues. So, in your case, if you produce to a partition that is not available, that message will eventually time out (message.timeout.ms) because during the messages lifetime the desired partition did not materialise on any broker. This could be optimised of course; librdkafka could fail the message as soon as it has received an updated metadata list from brokers. What you seem to be asking for is a synch interface that blocks until the message is delivered or would fail delivery. This is possible to implement both in librdkafka (issue #32) and the application (by doing a single produce() and then waiting for the delivery report by doing poll()). So my suggestion to you is to construct your application with asynchronisity and late failures in mind. Solutions:
Hope this clears things up a bit. |
I'm still confused in this regard: Based on the above, how are you able to reliably provide the partition_cnt
|
The partitioner callback is not called until the partition count has been retrieved from the broker (metadata response). In the current implementation messages that are produced to a partition that doesnt exist will linger in the internal queue until they time out. But I will change that behaviour to fail those messages as soon as the metadata is received from the broker, and failing them with a proper error code (no such partition) instead of timeout. It would also be possible to reject messages at produce() time by using the last cached metadata information, even though this information may be outdated (migrating from a a separated broker to a broker that is properly connected to the cluster - but this is a rare case). I will add support for this aswell. The problem here is with the messages produced before a connection to a broker has been established - are these messages to be dropped immediately or queued until a metadata response has been received? I would say the latter. So to sum it up:
|
Sounds great. Thanks very much On Monday, December 30, 2013, Magnus Edenhill wrote:
|
Two error paths: - produce() will fail with errno set to ESRCH - dr_cb() will provide err RD_KAFKA_RESP_ERR__UNKNOWN_PARTITTION
The way msgtimeout test was implemented will not work any more with the fix for issue #39
Please update your local master branch and give it a go, producing to unknown partitions should now fail in one of two ways (depending on if the metadata has been fetched from the broker yet): Two error paths:
Please close this issue if you are able to verify the fix. Thank you. |
Is there any way you can have it fail also if the topic doesn't exist and aio create is false? Right now it times out. |
Good point, I'll look into it. |
The invalid partition check didn't seem to work. It ends up calling my partitioner function multiple times and then failed with a local message timeout. |
Could you reproduce this with "debug" config property set to "broker,metadata,topic,msg" ? |
In rdkafka_performance the invalid partition checks works. Just need the invalid topic check now (immediate fail rather than timeout) |
Will be looking at this the coming days. |
Correct On Friday, January 17, 2014, Magnus Edenhill notifications@github.com
|
Hey Magnus - just checking if you've had a chance to look at this one yet? |
… problem for produced messages. rd_kafka_produce() will now return -1 and set errno to ENOENT when the topic is unknown in the cluster, and the DR callback will use new error code RD_KAFKA_RESP_ERR__UNKNOWN_TOPIC to indicte the same. This also fixes an issue where messages could be produced out of order during initial broker setup in some circumstances.
Unknown partitions and topics should now fail as soon as possible, both through rd_kafka_produce() and the dr_cb. Could you please verify this in your setup aswell? |
The topic one works, but unfortunately I have to specifically check for ENOENT and log appropriately myself because strerror(errno) will indicate 'no such file or directory' which will be misleading to my users. |
Also, could we also enhance to error out early (and not timeout) if the required acks flag is > ISR's? |
Yeah, using errno for error propagation was a mistake. It will be fixed in the next version of the API.
What would your preference be? |
On Monday, January 27, 2014, Magnus Edenhill notifications@github.com
|
The client does not know about the ISR count, this will have to be enforced by the broker but doesn't seem to be. |
…ors (issue #39) This also changes the behaviour of rd_kafka_consume*() to set errno to ESRCH for unknown partitions (was ENOENT) to be in line with rd_kafka_produce() behaviour.
There, rd_kafka_errno2err(), give it a go. |
Please verify this on your side and close the issue. |
Reopen if still an issue. |
my topic is defined as having 10 partitions. (0-9) When I attempt to send to partition 10, I expected to get an error callback. However, the poll (which I set to -1) just hangs. Shouldn't I get an error callback? I know the API is aware this is a bad partition because my log callback is being called and includes this detail:
27-Dec-2013 11:44:21:918 [T07][3828] kafka/kafka.cc:23 fac:'PART' name:'LARA#producer-0' log:'LaraReplicator_kafkacluster2 partition [10] not currently available'^M
The text was updated successfully, but these errors were encountered: