Pada mode KRaft, cluster Kafka terdiri atas dua kelompok peran proses, yaitu broker yang menyimpan partisi dan melayani klien serta controller yang mengelola metadata cluster. Topik ini membahas pembagian kedua peran, metadata quorum yang menjadi pusat keputusan cluster, serta sebaran partisi antar broker beserta pemilihan leadernya. Keadaan kedua peran dibaca langsung dari cluster hidup menggunakan kafka-metadata-quorum dan pembacaan direktori log, sehingga setiap pernyataan dapat diverifikasi pada broker lokal. Setelah membaca topik ini, struktur internal cluster Kafka dapat diterangkan dari konfigurasi process.roles dan keluaran alat bawaan distribusinya.
Dua peran pada mode KRaft#
KRaft adalah mode arsitektur Kafka yang menempatkan pengelolaan metadata di dalam cluster Kafka sendiri, tanpa perangkat koordinasi tambahan. ZooKeeper yang sebelumnya wajib mendampingi Kafka sudah tidak didukung sejak Kafka 4.0 karena mode ZooKeeper dihapus dari distribusi, sedangkan KRaft dinyatakan siap untuk produksi sejak Kafka 3.3 lewat KIP-833. Penggantian ini diusulkan lewat KIP-500, yang menjadikan metadata cluster sebagai log internal yang direplikasi antar controller, bukan data yang disimpan oleh sistem terpisah. Konsekuensinya, seluruh proses Kafka dijalankan dari distribusi yang sama dan dikonfigurasi lewat properti yang sama.
Peran setiap proses ditetapkan oleh konfigurasi process.roles, yang nilainya broker, controller, atau broker,controller. Broker menerima tulisan producer, menyajikan data kepada consumer, dan menyimpan log partisi di direktori log.dirs. Controller menjadi anggota quorum metadata, memilih leader untuk setiap partisi, dan menyimpan metadata cluster pada direktori metadata tersendiri. Proses yang menjalankan kedua peran sekaligus disebut proses gabungan (combined), bentuk yang digunakan broker lokal pada jalur ini, sedangkan deployment produksi memisahkannya agar controller terisolasi dari beban data.
Broker sandbox pada jalur ini menjalankan kedua peran dalam satu proses dengan identitas node 1, sebagaimana potongan konfigurasi berikut.
process.roles=broker,controller
node.id=1
controller.quorum.bootstrap.servers=localhost:9093
listeners=PLAINTEXT://:9092,CONTROLLER://:9093Baris process.roles memuat kedua peran, sehingga satu proses Java melayani klien pada listener PLAINTEXT dan komunikasi quorum pada listener CONTROLLER. Properti controller.quorum.bootstrap.servers berisi alamat controller yang dicari setiap proses ketika bergabung, fungsi yang setara dengan bootstrap.servers pada klien. Pemisahan peran tetap relevan untuk dipahami karena keputusan penskalaan kedua peran berbeda, yaitu jumlah controller mengikuti toleransi kegagalan yang diinginkan, sedangkan jumlah broker mengikuti beban data.
Metadata quorum#
Controller membentuk metadata quorum, yaitu himpunan controller yang masing-masing menyimpan salinan metadata log dan memilih satu anggota aktif menggunakan protokol konsensus Raft. Metadata log mencatat setiap perubahan cluster, misalnya pembuatan topic, penetapan leader partisi, dan perubahan konfigurasi, lalu direplikasi ke seluruh controller seperti partisi biasa direplikasi antar broker. Controller aktif melayani seluruh operasi metadata, sedangkan anggota lain menjadi standby yang siap mengambil alih apabila anggota aktifnya gagal. Mayoritas controller harus tetap hidup agar cluster mampu memilih controller aktif baru.
Keadaan quorum dibaca dengan bin/kafka-metadata-quorum.sh describe --status. Keluarannya memuat identitas cluster, controller aktif beserta epochnya, posisi metadata log, serta daftar pemilih dan pengamat. Blok berikut menjalankan perintah itu pada broker lokal dan menyaring keluarannya dengan grep agar hanya kolom yang stabil yang ditempel.
(
cd /home/kal/my-project/kafka-runtime/kafka
bin/kafka-metadata-quorum.sh --bootstrap-server localhost:9092 describe --status | grep -E "^(LeaderId|MaxFollowerLag|MaxFollowerLagTimeMs|CurrentObservers):"
)LeaderId: 1
MaxFollowerLag: 0
MaxFollowerLagTimeMs: 0
CurrentObservers: []Baris yang tidak ditempel memuat nilai yang berubah setiap kali cluster dibentuk atau dimulai ulang, sehingga tidak dapat dijadikan keluaran tetap. ClusterId dibangkitkan acak saat penyimpanan diformat, LeaderEpoch naik setiap kali controller aktif terpilih ulang, HighWatermark maju setiap kali ada metadata baru yang ditulis, dan directoryId pada daftar pemilih bersifat acak pula. Baris yang tersisa justru memperlihatkan keadaan yang stabil pada broker tunggal ini, yaitu controller aktif bernomor 1 sesuai node.id, lag pemilih bernilai nol karena hanya ada satu pemilih, dan daftar pengamat kosong karena broker berperan gabungan ikut menjadi pemilih. Pada cluster dengan controller terpisah, broker muncul sebagai pengamat yang mengikuti quorum, sebagaimana dilaporkan pada CurrentObservers.
Cluster dengan peran terpisah#
Diagram berikut memisahkan kedua peran pada cluster produksi berisi tiga controller dan tiga broker. Tiga controller membentuk quorum pada bagian atas diagram dengan masing-masing menyimpan salinan metadata log, dan salah satunya aktif pada satu waktu. Broker di bawah menerima aliran metadata dari quorum, menyimpan partisi, dan melayani producer serta consumer.
Broker sandbox berbeda dari gambar karena kedua perannya digabungkan dalam satu proses. Pada proses gabungan, controller tetap menjadi anggota quorum dan broker tetap mengikuti metadata, tetapi keduanya berbagi satu node.id, satu proses Java, dan dua listener berbeda. Port 9092 melayani klien, sedangkan port 9093 hanya digunakan untuk komunikasi quorum controller, dan keduanya berada di satu proses yang sama.
Pemahaman kedua bentuk saling melengkapi karena mekanisme metadata kedua bentuk sama, sehingga perbedaannya hanya pada penempatan proses, bukan pada protokol yang dijalankan. Bentuk gabungan disarankan untuk lingkungan pengembangan, sedangkan lingkungan produksi yang kritis memisahkan peran agar controller tidak terganggu beban data. Jumlah pemilih metadata juga ditentukan oleh desain keandalan cluster, bukan oleh jumlah broker yang berjalan.
Sebaran partisi antar broker#
Ketika sebuah topic dibuat, controller menempatkan salinan setiap partisi ke beberapa broker dan menetapkan salinan pertama pada daftar sebagai preferred leader, yaitu kandidat leader utama partisi tersebut. Penempatan diupayakan merata agar beban tulis dan baca tidak menumpuk pada broker yang sama. Leader setiap partisi dipilih controller dari anggota ISR, dan apabila leader gagal, salinan sinkron berikutnya dipromosikan. Kafka juga menjaga agar leader kembali ke kandidat utamanya melalui pemilihan ulang berkala yang dikendalikan konfigurasi broker auto.leader.rebalance.enable.
Sebaran salinan dapat dibaca dari cluster hidup melalui alat kafka-log-dirs pada CLI atau metode describe_log_dirs pada klien Python, yang keduanya mengembalikan posisi partisi per broker beserta ukuran lognya. Skrip berikut membuat topic tetap m7-sebaran-demo dengan empat partisi baru, lalu mencetak broker pemilik setiap salinannya. Topic dibuat ulang pada setiap eksekusi agar jumlah partisinya selalu sama.
# Menampilkan sebaran salinan partisi sebuah topic tetap yang dibuat baru
from kafka.admin import KafkaAdminClient, NewTopic
from kafka.errors import UnknownTopicOrPartitionError
import time
topic = "m7-sebaran-demo"
admin = KafkaAdminClient(bootstrap_servers="localhost:9092")
try:
admin.delete_topics([topic])
time.sleep(2)
except UnknownTopicOrPartitionError:
pass
admin.create_topics([NewTopic(name=topic, num_partitions=4, replication_factor=1)])
time.sleep(2)
for broker in admin.describe_log_dirs(topic_partitions=[topic]):
for logdir in broker["log_dirs"]:
for info in logdir["topics"]:
for p in sorted(info["partitions"], key=lambda x: x["partition_index"]):
print(f"{info['name']}-{p['partition_index']} -> broker={broker['broker']} ukuran={p['partition_size']} offsetLag={p['offset_lag']}")
admin.close()m7-sebaran-demo-0 -> broker=1 ukuran=0 offsetLag=0
m7-sebaran-demo-1 -> broker=1 ukuran=0 offsetLag=0
m7-sebaran-demo-2 -> broker=1 ukuran=0 offsetLag=0
m7-sebaran-demo-3 -> broker=1 ukuran=0 offsetLag=0Keempat partisi berada di broker 1 karena cluster hanya memiliki satu broker, dan ukuran lognya nol karena topic baru saja dibuat. Pada cluster dengan beberapa broker, penempatan awal bergilir antar broker sehingga keempat salinannya biasanya berada di broker yang berbeda, dan keluaran metode yang sama menunjukkannya tanpa perubahan kode. Angka offsetLag mengukur ketertinggalan salinan terhadap ujung log, nilai yang berguna saat salinan baru dibuat atau broker pulih dari kegagalan. Sebaran yang sudah ditetapkan tidak berpindah sendiri ketika broker baru bergabung, sehingga penyeimbangannya dilakukan dengan pemindahan replika melalui kafka-reassign-partitions.
Kesalahan umum#
- Menjalankan ZooKeeper sebagai pendamping cluster Kafka 4.x. Mode ZooKeeper sudah dihapus sejak 4.0, sehingga proses itu tidak digunakan oleh cluster sama sekali dan hanya menambah pemeliharaan. Tetapkan
process.rolesdan bentuk penyimpanan KRaft dengankafka-storagesebagaimana dilakukan pada penyiapan broker lokal. - Mengubah
node.idatau identitas cluster pada direktori data yang sudah terformat. Nilai yang berubah membuat proses menolak bergabung karena data penyimpanan tidak cocok dengan identitas yang dinyatakan, dan pesan errornya memuat ketidakcocokan tersebut. Jaganode.idtetap, dan format ulang hanya pada direktori yang memang kosong. - Menganggap controller menyimpan data pesan. Controller hanya mengelola metadata, sedangkan log partisi seluruhnya berada di broker, sehingga penambahan kapasitas diska untuk data dilakukan di sisi broker.
- Mengharapkan partisi berpindah otomatis ke broker yang baru bergabung. Penempatan lama tetap apa adanya sampai dipindahkan, sehingga broker baru dapat menganggur bila pemindahan tidak direncanakan. Gunakan
kafka-reassign-partitionssaat cluster dikembangkan.
Ringkasan#
- Mode KRaft menjadikan Kafka mengelola metadata sendiri tanpa ZooKeeper, dan peran setiap proses ditetapkan lewat
process.rolesberupabroker,controller, atau keduanya sekaligus. - Controller membentuk metadata quorum berbasis Raft dengan satu anggota aktif dan sisanya standby, sedangkan broker menyimpan partisi dan melayani klien.
- Controller menempatkan salinan partisi saat topic dibuat, salinan pertama pada daftar menjadi preferred leader, dan pemilihan ulang berkala mengembalikan leader ke kandidat utamanya.
kafka-metadata-quorum describe --statusdan pembacaan direktori log menampilkan keadaan kedua peran pada cluster hidup, termasuk sebaran partisi antar broker.
Referensi#
- KRaft operations — Apache Software Foundation
— konfigurasi
process.roles, manajemen quorum controller, dan alatkafka-metadata-quorum. - KRaft vs ZooKeeper — Apache Software Foundation — perbedaan perilaku mode KRaft terhadap mode ZooKeeper yang sudah dihapus.
- Upgrade — Apache Software Foundation — catatan bahwa Kafka 4.0 hanya mendukung mode KRaft dan KRaft siap produksi sejak 3.3.
- KIP-500: Replace ZooKeeper with a Self-Managed Metadata Quorum — Apache Software Foundation — usulan awal menjadikan metadata cluster sebagai quorum mandiri tanpa ZooKeeper.