Dieser Post ist Teil der Serie Stream Processing Entwicklungsumgebung, und das ist der 1. Artikel in der Serie. Einen Überblick über alle Artikel der Serie findest du hier.

Kafka stellt neuerdings ein Docker Image bereit, also kann ich meinen eigenen Server auch in Containern betreiben. Das gefällt mir!

Ich habe ein Dev-Setup das ich recht oft nutze, also möchte ich das aufschreiben.

Motivation

Hauptsächlich in der Arbeit nutze ich Kafka viel. Für schnelle Tests oder ähnliches benötige ich ein System das sich selbst genügt, das ich schnell aufstellen und dann auch wieder einstampfen kann. Im Wesentlichen möchte ich ein System haben, das einfach geht™.

Ich habe in diesem Zusammenhang einige Entscheidungen getroffen, die in einem Dev-Setup Sinn machen:

  • Ich habe nur einen Broker. In einem typischen Setup sind drei oder mehr empfohlen um Redundanzen und hohe Verfügbarkeit zu gewährleisten. Für meinen Anwendungsfall genügt aber einer.
  • Ich interessiere mich auch nicht für separate Controller, da ich in einem Development-Setup unterwegs bin.
  • Ich benötige keine Daten-Persistenz. Meine Idee ist, dass ich mit docker compose up -d einen Cluster für Entwicklungszwecke aufsetze, und mit docker compose down das System wieder schließe. Ich möchte keine Artefakte in die nächste Entwicklungs-Session mitnehmen.

Mein Compose File

So schaut mein Docker Compose File aus:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
services:
  broker:
    image: apache/kafka:4.0.0
    container_name: broker
    ports:
      - 9092:9092
    environment:
      KAFKA_NODE_ID: 1
      KAFKA_PROCESS_ROLES: broker,controller
      KAFKA_LISTENERS: PLAINTEXT_HOST://0.0.0.0:9092,CONTROLLER://broker:9093,PLAINTEXT://broker:29092
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://broker:29092,PLAINTEXT_HOST://127.0.0.1:9092
      KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT_HOST:PLAINTEXT,PLAINTEXT:PLAINTEXT,CONTROLLER:PLAINTEXT
      KAFKA_CONTROLLER_QUORUM_VOTERS: 1@broker:9093
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
      KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
      KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
      KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
      KAFKA_NUM_PARTITIONS: 3
  schema-registry:
    image: confluentinc/cp-schema-registry
    hostname: schema-registry
    container_name: schema-registry
    depends_on:
      - broker
    ports:
      - 8081:8081
    environment:
      SCHEMA_REGISTRY_HOST_NAME: schema-registry
      SCHEMA_REGISTRY_KAFKASTORE_BOOTSTRAP_SERVERS: broker:29092
      SCHEMA_REGISTRY_LISTENERS: http://0.0.0.0:8081

Und damit bekomme ich:

  • Einen Kafka Broker der als kombinierter Controller und Broker arbeitet und keine weiteren Abhängigkeiten hat.
    Die meisten Konfigurationen sollten verständlich sein, wenn Kafka grundsätzlich bekannt ist; daher möchte ich nicht allzu sehr ins Detail gehen. Nur einige Kleinigkeiten die das Docker-Setup betreffen möchte ich besprechen:
    • Listeners und advertised Listeners: Der CONTROLLER Listener ist uninteressant.
      • Der PLAINTEXT Listener ist für Applikationen, die im gleichen Docker Netzwerk laufen (heißt im Wesentlichen: Die im gleichen Compose File definiert sind). Diese erreichen Kafka über den Port 29092. Entsprechend sollte in diesen Applikationen gesetzt werden bootstrap.servers = broker:29092.
      • Eine Applikation die außerhalb von Docker läuft, kann per bootstrap.servers = localhost:9092 den Broker immer noch erreichen und alles klappt so wie erwartet.
    • Die Standard-Anzahl an Partitionen für ein Topic ist $3$. Mache daraus was du möchtest.
    • Der Topic Replication Factor wird auf $1$ gesetzt - das ist der Abwesenheit von mehreren Brokern geschulded.
  • Die Schema Registry macht eigentlich nicht viel.
    • Kommunikation ist über http://localhost:8081 möglich, bzw. über http://schema-registry:8081 aus Containern heraus.
    • Der Broker wird für Daten-Persistenz genutzt.

Achtung!

  • Wie bereits diskutiert, gibt es nur einen Broker - das ist kein Fehler, sondern ein Feature.
  • Die Schema Registry von Confluent steht unter der Confluent Community Lizenz, die keine anerkannte FOSS-Lizenz ist. Ich arbeite an einer Alternative, die existiert aber noch nicht. Vorerst ist das für mich gut genug.
  • Wiederum ein Feature: Es gibt keine Daten-Persistenz! Wenn der Broker neu gestartet oder auf eine neue Version aktualisiert wird, ist alles weg.

Erweiterungen

Dieses Setup ist bei weitem nicht vollständig, und es gibt eine Menge Erweiterungen, die ich mir vorstelle. Einige Gedanken:

  • Ich denke darüber nach, meinen Cluster im Heimnetzwerk auf Docker umzustellen; das würde das Dependency Management sehr erleichtern. Mir ist klar dass die Images nicht für Produktion gedacht sind, aber fürs Heimnetzwerk könnte das genügen. Wenn ich das mache, werde ich sicher darüber bloggen.
  • Ich habe auch mit drei Brokern auf einer Maschine herumgespielt, aber das bringt nicht viel Mehrwert für ein Dev-Setup. Trotzdem werde ich das vielleicht einmal publizieren.
  • Es gibt noch eine ganze Menge Services, die ich noch hinzufügen möchte. Spontan fällt mir ein: Kafka Connect, Apache Flink oder ksql, eine UI, und einiges anderes. Ich werde voraussichtlich bloggen, wenn ich das gut genug formalisiert und korrekt aufgesetzt habe.

Trotzdem ist das ein gutes minimales Setup um auf einem Kafka Cluster zu entwickeln.

Fazit

Es ist wirklich cool, dass Kafka eigene Images baut! Ich freue mich darauf, das Container-Setup zu erweitern.