Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Lazy initialization for RecordHeader was introduced in KAFKA-10438, improving performance but also creating unexpected side effects.
Since the Consumer is not thread-safe, the same assumption naturally extends to ConsumerRecord. However, users often assume that read-only access across threads is safe.
With lazy initialization, this assumption no longer holds, and users may encounter NullPointerException.
So far, three concurrency-related issues (KAFKA-12999, KAFKA-17725, KAFKA-18470) have been reported with respect to RecordHeader data access.
We can ensure that users have thread-safety guarantees when accessing RecordHeader in a read-only manner, eliminating the risk of NullPointerException.
Note that if other threads modify the value field in RecordHeader (a mutable byte[]), thread-safety is not guaranteed.

...

The thread-safe double-checked locking implementation introduces minimal overhead compared to the non-thread-safe version:
key initialization increased from ~0.457 ns/op to ~0.774 ns/op, and value initialization from ~0.451 ns/op to ~0.773 ns/op, which is negligible in practical workloads.negligible overhead (~0.3 ns) only during the first initialization of key or value

Current Implementation (non-thread-safe)

...

Making RecordHeader thread-safe does not break any compatibility.

Test Plan

  • Unit tests will be written to verify that no NullPointerException occurs.

  • The benchmark described above will also be included. Successful completion of the benchmark without any NullPointerException will demonstrate that RecordHeader is thread-safe.

  • Additionally, the benchmark will confirm that the double-checked locking implementation performs significantly better than full-method synchronization.

Rejected Alternatives

Full-Method Synchronization

...