Errata

Kafka: The Definitive Guide

Errata for Kafka: The Definitive Guide, Second Edition

Submit your own errata for this product.

The errata list is a list of errors and their corrections that were found after the product was released.

The following errata were submitted by our customers and have not yet been approved or disproved by the author or editor. They solely represent the opinion of the customer.

Color Key: Serious technical mistake Minor technical mistake Language or formatting error Typo Question Note Update

Version Location Description Submitted by Date submitted
PDF, Page Ch6 Kafka Internals, Replication
n/a

"If a replica hasn’t requested a message in more than 10 seconds [...]"

replica.lag.time.max.ms default value since 2.5.0 https://issues.apache.org/jira/browse/KAFKA-9102 is 30s instead of 10s. According to Chapter 2 (installing kafka) examples are for Kafka 2.7.0. If you intend to keep values consistent with version across the book you might consider updating this value.

Lukasz R-i  Jul 19, 2022 
Chapter 1, Producers and Consumers
Paragraph 3

> Each message in a given partition has a unique offset, and the following message has a greater offset (though not necessarily monotonically greater).

It is not clear how every following message could have a greater offset and yet the offsets would not be monotonically greater.

"Monotonically greater" does not mean that each value in a sequence of values would increase by a fixed amount. "Monotonically greater" means that each value in a sequence is greater than the previous value; the next value cannot be the same as or less than the previous value.

Ben Ellis  Aug 02, 2023 
O'Reilly learning platform Page chapter 3, Message Delivery Time, delivery.timeout.ms
place where delivery.timeout.ms is defined

Following are the exact lines written on delivery.timeout.ms in chapter 3(kafka producers), 2nd edition, kafka, the definitive guide.

delivery.timeout.ms >=linger.ms +retry.backoff.ms +request.timeout.ms
If producer exceeds delivery.timeout.ms while the record batch was still waiting to be sent, the callback will be called with a timeout exception.

However, in reality, prod application is showing a different behavior.
Here is an exact details from my prod config and the details of how it behaves:
delivery.timeout.ms = 120000( = 2mins=default)
linger.ms=0
request.timeout.ms=3600000 (60 mins)
I am observing a timeout exception :
org.apache.kafka.common.errors.TimeoutException: Expiring 14 records for topic1 3600008 ms has passed since batch creation.
As you can see here the producer is still waiting for 60 mins(= request.timeout.ms ) regardless of the value of delivery.timeout.ms
This contradicts what is explained in the book.
The book says the producer will throw TimeoutException as soon as the delivery.timeout.ms seconds has elapsed.
In this case, delivery.timeout.ms=2 mins ,so i should have got an exception in 2 mins instead of getting it after 60 mins.
I think the thread that's trying to submit the record does not care about delivery.timeout.ms ; rather it's looking for request.timeout.ms value.
Does the TimeoutException gets triggered only when producers try to add new records to a previous batch that is still waiting to be sent ?
Looks like there is no way for the client/producer to wait for the current batch to be sent successfully to brokers before sending the next batch as the send() method is returning without making sure the messages are sent successfully to broker.

Can you explain how it works ?

himansu dash  May 29, 2024 
O'Reilly learning platform Page Chapter 3 Synchronous send
Paragrah where "Synchronous send" is defined

Below is the definition of synchronous send from your book:
Technically, Kafka producer is always asynchronous—we send a message and the send() method returns a Future object. However, we use get() to wait on the Future and see if the send() was successful or not before sending the next record.

However, even if the get() method return is successful , the producer still throws "org.apache.kafka.common.errors.TimeoutException: Expiring 14 records for topic1 3600008 ms has passed since batch creation"
Below are the configuration:
delivery.timeout.ms = 120000( = 2mins)
linger.ms=0
request.timeout.ms=3600000 (60 mins)

question:
what is the best way to wait for the producer to wait for the batch to be sent successfully before moving onto the next batch ?
My understanding was future.get() returns success only when the broker receives it but it seems like my assumption is not true.
can you explain more on what is going on here ?

himansu dash  May 30, 2024 
PDF Page 1
Whole book

Sir,

I had gone through Kafka - The Definitive Guide (2nd Ed) and found it to be a great book. However, I do have a suggestion for the authors. Can you please highlight it to them?

The codes for the entire book is in Java. However, now days, even Python is being used in entire Data Science. Keeping this in mind, can the authors come out with an edition of this great book which will have Python codes as well, along with Java. Also, as of now, they can update the Github repo of this book with compliant Python codes.

I hope my suggestion is good enough keeping in mind about the future.

Anonymous  Feb 28, 2023 
Printed, PDF, ePub, Mobi, , Other Digital Version Page 9
3rd Paragraph

The paragraph here around multi-data center is mentioning MirrorMaker 1 which has already been superceded by MirrorMaker 2 distributed with Apache Kafka. Confluent also has Replicator and Cluster Linking which could be mentioned here but at the very least, Mirror Maker 2 should be the one referred to here rather than MirrorMaker 1.

Sarwar Bhuiyan  Dec 06, 2021 
PDF Page 19
3 paragraph - Standalone Server --> CLI commands

# cp > /usr/local/zookeeper/conf/zoo.cfg << EOF


should be (I guess)


# cat > /usr/local/zookeeper/conf/zoo.cfg << EOF


instead of using the command cp, I would "rather" use cat.

Thank you.

Jan Lesch  Sep 02, 2021 
Printed, PDF, ePub, Mobi, , Other Digital Version Page 33
2nd paragraph

In the section "Coordinating Message Size Con€gurations" it states that consumers will fail to receive results. This is no longer true in the later versions of Apache Kafka and they will receive the messages regardless of fetch.message.max.bytes

Sarwar Bhuiyan  Dec 06, 2021 
PDF Page 35
2nd Paragraph

Regarding whether the Kafka broker always decompresses and recompresses compressed message batches even if the compression codec is the same:

In the book it states that message batches are always decompressed & recompressed:

"Ideally, clients should compress messages to optimize network and disk usage. The Kafka broker must decompress all message batches, however, in order to validate the checksum of the individual messages and assign offsets. It then needs to recompress the message batch in order to store it on disk."

However the Apache Kafka Docs state the batch is only decompressed by the consumer:

"A batch of messages can be clumped together compressed and sent to the server in this form. This batch of messages will be written in compressed form and will remain compressed in the log and will only be decompressed by the consumer."

Rob Golder  Jun 20, 2023 
Printed Page 117
Second paragraph

Should "expend" actually read "expand"?

Anonymous  Jun 13, 2022 
PDF Page 118
3rd paragraph

`topics.name()` -> `topics.names()`

Iskuskov Alexander  Jul 18, 2023 
PDF Page 157
1st paragraph

Configuration property name should be `log.cleaner.enable` instead of `log.cleaner.enabled`

Iskuskov Alexander  Jul 17, 2023 
PDF Page 178
1st paragraph of Monitoring Reliability in Production

'Chapter 12' -> 'Chapter 13'

Iskuskov Alexander  Jul 17, 2023 
PDF Page 188
2nd paragraph of How Do Transactions Guarantee Exactly-Once

Topic name should be `__consumer_offsets` instead of `_consumer_offsets`

Iskuskov Alexander  Jul 17, 2023 
Other Digital Version 727
Chapter 2 - Configuring the Broker - Topic Defaults - log.roll.ms

"By default, there is no setting for log.roll.ms, which results in only closing log segments by size."

This is true, but reading the Kafka documentation you see that: "If not set, the value in log.roll.hours is used" and that one is set to 168 (1 week)

Which results in segments closed by size or after 1 week

Anonymous  Mar 31, 2022