kafka-proxy exposes Apache Kafka as a generated gRPC service, grpcdc.kafka.v1.Kafka, so any grpc-over-datachannels client — including a browser tab — can produce and consume without a Kafka client library. The interesting engineering is not the produce path; it is consumer groups, where Kafka's protocol is a distributed-systems negotiation. This post walks through how the proxy holds that state.
Sessions live on the proxy
Kafka group membership is stateful: joins, syncs, heartbeats, offset commits, and generation ids that fence off zombie members. Browser and thin native clients should not each reimplement that, so producer and consumer-group sessions live on the proxy. A client opens a stream and subscribes; the proxy joins the group, distributes assignments, and heartbeats on the client's behalf, against both Apache Kafka (KRaft) and Redpanda.
Rebalances are the hard part
When group membership changes, the coordinator bumps the generation and in-flight commits from the old generation are rejected. The proxy treats that as weather, not failure: broker connections reconnect once after transport errors, offset commits retry inside the session window until the new generation accepts them, and members rejoin without tearing down the client's stream. The end-to-end suite (21 tests per broker) races commits against forced rebalances precisely because that interleaving is where offsets get lost.
Restart resume
The newest test replaces the entire proxy process mid-group: a new instance comes up, the group reforms, and consumption resumes exactly at the committed offset — no redelivery storm, no skipped records. That property is what makes the proxy deployable as a stateless-ish sidecar in front of a broker: run it as ghcr.io/browser-grpc/kafka-proxy, point it at Kafka or Redpanda, and generated clients in sixteen languages can treat Kafka as just another gRPC service.
No comments:
Post a Comment