Replikasi

Leader, follower, ISR, dan peran min.insync.replicas dalam menjaga partisi tetap tersedia dan tahan fault.

Daftar isi

Replikasi adalah mekanisme Kafka untuk menyimpan lebih dari satu salinan setiap partisi sehingga data tetap aman ketika salah satu broker gagal. Topik ini membahas pembagian peran leader dan follower, daftar salinan sinkron yang disebut ISR, tiga pengaturan yang menentukan ketahanan sebuah topic, serta cara menetapkan min.insync.replicas lewat CLI. Demo pada bagian akhir dijalankan pada satu broker, sehingga perilaku multi-broker dijelaskan melalui diagram dan prosa.

Peran leader dan follower#

Unit replikasi di Kafka adalah partisi, bukan topic atau broker. Setiap partisi memiliki satu leader, yaitu satu-satunya salinan yang menerima tulisan, dan nol atau lebih follower, yaitu salinan yang menyalin log dari leader. Jumlah seluruh salinan termasuk leader disebut replication factor. Follower mengambil pesan dari leader seperti consumer biasa, lalu menambahkan pesan tersebut ke lognya sendiri dengan urutan dan offset yang persis sama. Seluruh tulisan diterima leader, sedangkan pembacaan dapat diarahkan ke leader maupun follower, dengan pembacaan dari leader sebagai praktik yang paling umum.

Diagram berikut memperlihatkan satu partisi dengan dua salinan. Producer menulis ke broker 1 selaku leader, broker 2 menyalin lognya selaku follower, dan keduanya menjadi anggota ISR.

partisi 0 dengan dua salinanProducerproduksiISR: broker 1 dan broker 2Broker 1 (leader)012replikasiBroker 2 (follower)012konsumsiConsumer
Replikasi satu partisi: producer menulis ke leader, follower menyalin lognya

Pembagian peran ini membuat replikasi transparan bagi producer. Producer tidak perlu mengetahui jumlah salinan atau letak follower karena tanggung jawab penyalinan sepenuhnya berada di broker. Ketika leader gagal, salah satu follower yang masih sinkron dipromosikan menjadi leader baru dan producer melanjutkan pengirimannya ke broker tersebut. Pesan yang sudah dikonfirmasi dengan acks=all tidak hilang selama masih ada salinan sinkron yang tersisa.

ISR dan ketahanan partisi#

Leader mencatat daftar salinan yang masih sinkron dengannya, dan daftar itu disebut ISR (In-Sync Replicas). Sebuah salinan dianggap sinkron apabila sesinya dengan controller masih aktif, yang pada cluster KRaft dijaga lewat heartbeat berkala, dan kecepatan menyalinnya tidak tertinggal terlalu jauh dari leader. Apabila salah satu syarat itu tidak terpenuhi, misalnya follower mati atau kewalahan, leader mengeluarkannya dari ISR. Ambang ketertinggalannya ditetapkan oleh konfigurasi replica.lag.time.max.ms, yaitu durasi maksimum follower boleh tertinggal dari ujung log leader. Follower yang pulih dan berhasil mengikuti log leader dimasukkan kembali ke ISR.

Hubungan ISR dengan ketahanan data berada pada aturan pesan committed. Sebuah pesan dianggap committed hanya setelah seluruh salinan di ISR menerapkannya ke log, dan pesan yang sudah committed tidak hilang selama minimal satu salinan di ISR tetap hidup. Di sinilah trade-off antara ketersediaan dan konsistensi muncul. Bila jumlah salinan di ISR turun di bawah min.insync.replicas, tulisan dengan acks=all ditolak dengan error NOT_ENOUGH_REPLICAS sampai ISR pulih, sehingga topic berhenti menerima tulisan alih-alih menyimpan pesan tanpa salinan yang cukup.

Konfigurasi replikasi pada topic#

PengaturanNilai defaultPeran
replication.factor1Jumlah salinan partisi termasuk leader, ditetapkan saat topic dibuat.
min.insync.replicas1Jumlah minimum salinan sinkron yang wajib mengonfirmasi sebelum tulisan dengan acks=all dianggap selesai.
unclean.leader.election.enablefalseIzin untuk memilih leader dari salinan yang tidak sinkron.

Nilai replication.factor ditetapkan pada pembuatan topic, misalnya lewat opsi --replication-factor 3 di CLI, dan perubahannya dilakukan lewat pemindahan replika antar broker, bukan lewat perubahan konfigurasi biasa. Konfigurasi min.insync.replicas dan unclean.leader.election.enable dapat diatur per topic secara dinamis dengan bin/kafka-configs.sh. Pada topic dengan replication.factor 3, kombinasi min.insync.replicas=2 membuat tulisan tetap diterima selama paling banyak satu salinan yang gagal, sehingga keseimbangan kedua pengaturan ini menjadi keputusan desain utama.

Pengaturan unclean leader election menentukan sisi yang diprioritaskan ketika seluruh salinan sinkron hilang. Nilai false membiarkan partisi tanpa leader sampai satu salinan sinkron kembali, sehingga data tidak hilang tetapi partisi tidak tersedia. Nilai true mengizinkan salinan yang tertinggal dipromosikan demi ketersediaan, dengan konsekuensi pesan yang belum tersalin dianggap hilang selamanya.

Mencoba replikasi pada broker tunggal#

Broker di lingkungan penulisan berjalan sendirian, sehingga replication factor di atas 1 tidak dapat dibuat karena Kafka menolak menempatkan dua salinan pada broker yang sama. Meski begitu, mekanisme yang dibahas tetap terlihat dari keluaran --describe, yang selalu menampilkan kolom Leader, Replicas, dan Isr per partisi. Topic demo m4-replikasi-demo dibuat baru pada setiap eksekusi agar jumlah partisinya selalu sama, dan keluaran describe disaring dengan grep "Partition:" karena baris kepala deskripsi memuat identitas topic yang berubah setiap kali topic dibuat ulang.

bash
(
  cd /home/kal/my-project/kafka-runtime/kafka
  bin/kafka-topics.sh --bootstrap-server localhost:9092 --delete --if-exists --topic m4-replikasi-demo 2>/dev/null
  sleep 2
  bin/kafka-topics.sh --bootstrap-server localhost:9092 --create --topic m4-replikasi-demo --partitions 1 --replication-factor 1
  bin/kafka-topics.sh --bootstrap-server localhost:9092 --describe --topic m4-replikasi-demo | grep "Partition:" | expand
)
text Keluaran
Created topic m4-replikasi-demo.
        Topic: m4-replikasi-demo        Partition: 0    Leader: 1       Replicas: 1     Isr: 1  Elr:    LastKnownElr: 

Baris partisi memuat nilai yang sama untuk ketiga kolom utama, yaitu Leader: 1, Replicas: 1, dan Isr: 1, karena hanya ada satu broker bernomor 1 di cluster. Pada cluster tiga broker dengan replication factor 3, kolom Replicas memuat tiga nomor broker, misalnya 1,2,3, dan kolom Isr memuat salinan yang benar-benar sinkron, yang bisa lebih pendek saat ada broker yang bermasalah. Dua kolom terakhir memuat daftar salinan yang memenuhi syarat menjadi leader, data yang digunakan broker saat memilih penggantinya.

Menetapkan min.insync.replicas lewat CLI#

Nilai min.insync.replicas dapat ditimpa per topic secara dinamis tanpa menjalankan ulang broker. Perintah bin/kafka-configs.sh --alter menetapkannya, dan --describe dengan --entity-type topics menampilkan nilai dinamis yang aktif. Demo berikut menetapkan nilai 1, nilai yang sesuai untuk broker tunggal, sedangkan pada topic produksi dengan replication factor 3 nilai yang lazim adalah 2. Bagian synonyms= pada keluaran describe, yang mencantumkan rantai sumber nilai dari level topic, level broker, sampai default, dihilangkan dengan sed karena isinya bergantung pada kondisi cluster saat perintah dijalankan.

bash
(
  cd /home/kal/my-project/kafka-runtime/kafka
  bin/kafka-configs.sh --bootstrap-server localhost:9092 --alter --entity-type topics --entity-name m4-replikasi-demo --add-config min.insync.replicas=1
  bin/kafka-configs.sh --bootstrap-server localhost:9092 --describe --entity-type topics --entity-name m4-replikasi-demo | sed 's/ synonyms=.*//'
)
text Keluaran
Completed updating config for topic m4-replikasi-demo.
Dynamic configs for topic m4-replikasi-demo are:
  min.insync.replicas=1 sensitive=false

Baris pertama mengonfirmasi perubahan, sedangkan dua baris berikutnya menunjukkan bahwa nilai itu kini tersimpan sebagai konfigurasi dinamis milik topic. Setiap tulisan dengan acks=all pada topic ini mulai diukur terhadap ambang 1 salinan sinkron sejak saat itu, sedangkan tulisan dengan acks=1 tidak terpengaruh karena tidak pernah menunggu salinan lain sejak awal. Isi log dan pembacaan consumer juga tidak berubah sama sekali, sehingga perubahan hanya berlaku pada sisi konfirmasi producer. Perubahan ini membutuhkan waktu seket dan tidak memulai ulang broker maupun producer yang sedang berjalan, sehingga pembatasan jumlah salinan sinkron dapat diperketat atau dilonggarkan saat operasi berlangsung.

Kesalahan umum#

  1. Menetapkan min.insync.replicas sama dengan replication.factor membuat partisi berhenti menerima tulisan begitu satu broker gagal, karena ISR pasti lebih kecil dari ambangnya. Producer dengan acks=all mendapatkan error NOT_ENOUGH_REPLICAS. Tetapkan nilai yang satu angka lebih kecil daripada replication factor agar satu kegagalan broker masih ditoleransi.
  2. Mengaktifkan unclean.leader.election.enable demi ketersediaan tanpa menyadari risikonya. Salinan yang dipromosikan bisa jadi salinan yang tertinggal, dan pesan yang belum tersalin hilang tanpa pesan error apa pun. Aktifkan hanya untuk data yang boleh kehilangan sebagian isi, seperti metrik performa, dan hindari pada data yang saling bergantung.
  3. Menganggap topic dengan replication factor 3 otomatis tahan kegagalan sementara producer masih menggunakan acks=1. Konfirmasi dari leader saja bisa hilang bila leader gagal sebelum follower menyalinnya, dan salinan tambahan tanpa konfirmasi tambahan hanya menambah penggunaan penyimpanan. Naikkan acks menjadi all bersama min.insync.replicas yang memadai seperti dibahas pada topik Ketahanan producer.
  4. Membiarkan salinan yang tertinggal tanpa pemeriksaan. Follower yang lambat keluar dari ISR secara diam-diam, dan topic berpindah dari tiga salinan sinkron ke satu tanpa peringatan bila tidak dipantau. Jadikan jumlah partisi yang ISR-nya kurang lengkap sebagai metrik yang diperiksa berkala.

Ringkasan#

  • Setiap partisi memiliki satu leader yang menerima tulisan dan nol atau lebih follower yang menyalin log, dan jumlah salinannya adalah replication factor.
  • Leader mengelola ISR, yaitu daftar salinan yang sesinya aktif dan tidak tertinggal jauh, dan pesan dianggap committed setelah seluruh ISR menerapkannya.
  • replication.factor ditetapkan saat topic dibuat, sedangkan min.insync.replicas dan unclean.leader.election.enable dapat diubah per topic secara dinamis.
  • acks=all memberikan jaminan penuh hanya bila min.insync.replicas lebih besar dari 1, dan ISR di bawah ambang itu menolak tulisan dengan error NOT_ENOUGH_REPLICAS.

Referensi#