Broker Recovery Process: Panduan Rekonstruksi dan Sinkronisasi Log #
Dalam mengelola kluster Apache Kafka berskala besar, salah satu momen paling menegangkan bagi kita sebagai administrator sistem adalah saat menghidupkan kembali (booting) node broker yang baru saja mengalami mati mendadak. Kematian tidak bersih (unclean shutdown) akibat pemadaman listrik, crash JVM, atau kegagalan sistem operasi dapat meninggalkan data di dalam disk dalam kondisi tidak konsisten.
Ketika broker booting kembali, ia tidak dapat langsung melayani trafik baca-tulis dari klien. Broker harus masuk ke dalam fase Broker Recovery Process (Proses Pemulihan Broker). Selama fase ini, broker akan memeriksa kesehatan setiap file segmen log pada disk data, merekonstruksi berkas indeks yang rusak, memangkas offset yang tidak konsisten (log truncation), dan menyinkronkan datanya dengan leader aktif sebelum diizinkan masuk kembali ke dalam kelompok In-Sync Replicas (ISR). Jika kita tidak memahami proses ini, kita mungkin akan panik melihat proses booting yang memakan waktu lama dan tidak sengaja mematikan paksa server yang sedang melakukan pemulihan, yang justru akan memperparah kerusakan data.
Dalam panduan ini, kita akan membedah perbandingan controlled shutdown vs unclean shutdown, mempelajari bagaimana Kafka mendeteksi kegagalan menggunakan file penanda khusus, memahami langkah-langkah rekonstruksi berkas indeks .index dan .timeindex secara mendalam, serta menelusuri proses pemotongan log dan sinkronisasi replika pasca-restart.
Controlled Shutdown vs Unclean Shutdown #
Cara kita mematikan broker Kafka menentukan seberapa cepat broker tersebut dapat dihidupkan kembali di kemudian hari.
+-------------------------------------------------------------------------------+
| PERBANDINGAN PROSES SHUTDOWN KAFKA |
| |
| 1. CONTROLLED SHUTDOWN (Bersih / Graceful): |
| * Pemicu: Perintah SIGTERM / systemctl stop kafka |
| * Langkah: |
| - Alihkan kepemimpinan partisi (Leader) ke broker follower sehat. |
| - Siram (Flush) seluruh page cache memori ke disk fisik. |
| - Tulis file penanda "clean-shutdown" ke direktori data. |
| * Booting Berikutnya: Instan (Detik) karena data dijamin bersih. |
| |
| 2. UNCLEAN SHUTDOWN (Tidak Bersih / Sudden Crash): |
| * Pemicu: Listrik padam, JVM OOM Crash, systemctl kill / SIGKILL |
| * Langkah: |
| - Broker langsung mati tanpa sempat mengalihkan leader. |
| - Ada data di page cache RAM yang belum sempat disiram ke disk. |
| - Tidak ada file penanda "clean-shutdown" di disk. |
| * Booting Berikutnya: Lama (Menit/Jam) karena wajib memindai & rebuild. |
+-------------------------------------------------------------------------------+
1. Proses Controlled Shutdown #
Ketika kita menghentikan proses Kafka secara bersih menggunakan perintah systemctl stop kafka (yang mengirimkan sinyal SIGTERM):
- Migrasi Leader: Broker akan berkomunikasi dengan controller untuk memindahkan semua status kepemimpinan partisi (leader) yang dipegangnya saat ini ke broker follower lainnya secara damai. Klien diarahkan ke leader baru tanpa ada gangguan interupsi.
- Penyiraman Cache (Flush): Broker menyiram seluruh isi memori page cache OS yang berisi data transaksi ke disk fisik secara tersinkronisasi.
- Pemberian Penanda: Setelah seluruh I/O disk selesai ditulis dengan aman, broker menulis sebuah file kosong bernama
clean-shutdowndi setiap direktori penyimpanan data (log.dirs).
Untuk mengaktifkan fitur ini, pastikan parameter berikut selalu disetel di server.properties:
controlled.shutdown.enable=true
controlled.shutdown.max.retries=3
controlled.shutdown.retry.backoff.ms=5000
2. Bencana Unclean Shutdown #
Sebaliknya, jika broker mati mendadak akibat crash JVM (OOM) atau server mati listrik:
- Broker mati seketika tanpa sempat menyiram data page cache RAM ke disk.
- Tidak ada proses migrasi leader, sehingga partisi-partisi tersebut langsung kehilangan leadernya sampai controller memindahkan kepemimpinan secara darurat.
- File penanda
clean-shutdowntidak terbentuk di direktori penyimpanan. Kondisi ketiadaan file inilah yang dibaca oleh sistem Kafka saat booting berikutnya sebagai sinyal untuk memicu proses pemulihan log kotor (unclean log recovery).
Proses Pemulihan Log Saat Booting (Log Recovery Process) #
Ketika broker Kafka dihidupkan kembali, class LogManager internal Kafka akan memindai seluruh direktori data yang terdaftar di properti log.dirs.
1. Deteksi Awal dan Pembacaan File Penanda #
Langkah pertama yang dilakukan broker adalah memeriksa keberadaan file bernama clean-shutdown pada setiap direktori data:
- Jika file
clean-shutdownADA: Broker berasumsi seluruh data di disk dalam kondisi konsisten dan aman. Broker akan memintas (bypass) fase pemindaian log dan langsung membuka file log segment secara instan. Broker siap online dalam hitungan detik. - Jika file
clean-shutdownTIDAK ADA: Broker mendeteksi bahwa shutdown sebelumnya tidak bersih. Broker otomatis memicu prosedur Unclean Log Recovery untuk memverifikasi setiap segmen log pada disk.
2. Langkah Pemulihan Log Kotor #
Untuk setiap partisi data di dalam direktori log kotor:
- Temukan Segmen Log Teraktif: Broker mencari segmen log aktif terakhir (segmen yang sedang ditulis saat crash terjadi).
- Validasi Checksum Pesan: Broker memindai record pesan di dalam segmen aktif tersebut satu per satu dari awal segmen, memverifikasi nilai checksum CRC dari setiap pesan.
- Pemangkasan Data Kotor (Truncation): Jika broker menemukan pesan yang memiliki checksum rusak (akibat penulisan terputus saat listrik padam) atau menemukan pesan yang ditulis di luar batas offset High Watermark, broker akan memotong file
.logtersebut tepat pada posisi offset sebelum kerusakan terjadi (corrupted record truncation). - Rekonstruksi Berkas Indeks: File indeks posisi (
.index) dan indeks waktu (.timeindex) yang digunakan Kafka untuk pencarian cepat sering kali tidak sinkron dengan data file.logsaat crash terjadi. Kafka akan menghapus kedua file indeks lama tersebut, lalu membaca ulang keseluruhan file payload.logdari awal segmen untuk membangun ulang file.indexdan.timeindexdari nol.
Catatan: Proses rekonstruksi indeks ini memakan waktu yang sangat lama jika ukuran segmen log kita sangat besar dan jumlah partisi pada broker mencapai ribuan.
Mempercepat Pemulihan: Konfigurasi Thread Pemulihan Paralel #
Secara default, proses inisialisasi log segment pada disk dilakukan secara berurutan (sequential) untuk setiap direktori data. Jika kita menggunakan konfigurasi multi-disk JBOD dan menampung ratusan partisi kotor, proses booting akan memakan waktu berjam-jam jika hanya dikerjakan oleh satu thread tunggal.
Kita dapat melipatgandakan kecepatan pemulihan log dengan menyetel parameter num.recovery.threads.per.data.dir di berkas server.properties:
# Optimasi thread pemulihan log per direktori data JBOD
num.recovery.threads.per.data.dir=4
Analisis Setelan Thread Recovery: #
- Parameter ini menentukan jumlah thread paralel yang dialokasikan broker untuk setiap direktori yang terdaftar di properti
log.dirs. - Jika kita memiliki 4 disk JBOD dan menyetel
num.recovery.threads.per.data.dir=4, broker akan menjalankan total $4 \times 4 = 16$ thread pemulihan secara bersamaan saat booting. - Thread paralel ini akan melakukan pemindaian segmen log kotor dan membangun ulang file indeks
.indexsecara paralel untuk beberapa partisi sekaligus. - Rekomendasi: Setel parameter ini ke nilai 2 hingga 4 (sesuaikan dengan jumlah core CPU server fisik kita) untuk memotong waktu downtime pemulihan hingga $75%$.
Pemulihan Khusus: Log Compaction dan Transaksi Aktif #
Selain rekonstruksi berkas indeks segmen log biasa, Kafka juga harus memulihkan status khusus dari dua komponen log internalnya saat terjadi unclean shutdown:
1. Rekonstruksi Checkpoint Pemadatan Log (Log Compaction Recovery) #
Pada topik yang menggunakan kebijakan retensi compact, Kafka menggunakan berkas cleaner-offset-checkpoint di dalam setiap direktori log untuk melacak batas offset yang telah dibersihkan oleh thread Log Cleaner.
- Saat terjadi unclean shutdown, perubahan pemadatan terakhir kemungkinan belum sempat ditulis ke checkpoint.
- Langkah Pemulihan: Broker akan memindai kembali data tidak bersih (dirty portion) dari log topik terkompresi sejak posisi offset terakhir di checkpoint, lalu membangun ulang tabel hash kunci (deduplication offset map) di memori untuk memastikan tidak ada pesan duplikat dengan kunci yang sama yang terlewat dari pemadatan.
2. Pemulihan Transaksi Menggunakan Last Stable Offset (LSO) #
Untuk topik yang melayani transaksi produser secara Exactly-Once, broker mengelola penanda Last Stable Offset (LSO)—batas offset di mana seluruh pesan di bawahnya telah ter-commit atau dibatalkan (aborted).
- Jika broker crash saat ada transaksi aktif yang belum diselesaikan (berstatus ongoing transaction), log transaksi pada partisi
__transaction_statekemungkinan mengalami kerusakan parsial. - Langkah Pemulihan: Broker akan membaca ulang seluruh riwayat transaksi dari segmen log transaksional aktif guna merekonstruksi memori status produser (Producer State).
- Jika ditemukan transaksi gantung (aborted/uncommitted transactions) akibat kematian produser saat crash, broker akan memotong data tidak stabil tersebut ke posisi LSO untuk memastikan konsumen transaksional (
isolation.level=read_committed) tidak membaca data kotor yang dibatalkan.
Sinkronisasi Replika Pasca-Restart: Log Truncation & High Watermark #
Setelah proses rekonstruksi indeks lokal selesai, broker siap terhubung kembali dengan kluster. Namun, broker tersebut belum dapat melayani penulisan data karena status datanya kemungkinan berada di belakang leader saat ini.
1. Inisialisasi Thread Penarik (Replica Fetcher Threads) #
Broker yang baru pulih akan berstatus sebagai follower untuk sebagian besar partisi. Broker segera mengaktifkan thread ReplicaFetcherThread untuk menghubungi broker leader aktif dari setiap partisi guna meminta sinkronisasi data.
2. Proses Penyelarasan Offset (Log Truncation) #
Sebelum follower dapat mengunduh data baru dari leader, ia harus menyelaraskan posisi offset miliknya terlebih dahulu agar tidak terjadi divergensi data (data divergence). Proses ini ditunjukkan pada diagram alur di bawah:
sequenceDiagram
participant B1 as "Follower Baru Pulih (Broker 1)"
participant B2 as "Leader Partisi (Broker 2)"
Note over B1, B2: Kondisi Awal: HW = 103, B1 LEO = 106 (ada data tidak valid)
B1->>B2: 1. Minta posisi Epoch Leader terakhir
B2-->>B1: 2. Balas High Watermark terakhir = 103
Note over B1: 3. Lakukan TRUNCATION log dari offset 104 ke atas
Note over B1: 4. Log menyusut kembali menjadi sampai offset 103
B1->>B2: 5. Mulai FETCH data baru dari offset 104
Dengan memotong data lokal yang berada di atas High Watermark leader, Kafka menjamin bahwa seluruh replika memiliki catatan sejarah data yang identik dan mencegah terjadinya konflik offset di masa mendatang.
Memantau Proses Pemulihan Broker Lewat Log Server #
Saat menghidupkan kembali broker yang mengalami unclean shutdown, tim SRE dapat memantau estimasi kemajuan proses pemulihan dengan menyaring log server menggunakan perintah grep berikut:
# Pantau inisialisasi Log Manager dan deteksi unclean shutdown
tail -f /var/log/kafka/server.log | grep -E "LogManager|Recovering log|Loading producer state"
Output Contoh Log Pemulihan:
[2026-06-09 05:40:12,102] INFO [LogManager] Found unclean shutdown file marker for directory /var/lib/kafka/data - triggering recovery (kafka.log.LogManager)
[2026-06-09 05:40:13,405] INFO [LogManager] Recovering log payment.orders-0 (kafka.log.LogManager)
[2026-06-09 05:40:15,910] INFO [LogManager] Loading producer state from offset 104210 for partition payment.orders-0 (kafka.log.LogManager)
[2026-06-09 05:40:18,502] INFO [LogManager] Completed recovery of payment.orders-0. New Log End Offset is 104215 (kafka.log.LogManager)
Dengan memantau log ini, kita dapat memperkirakan seberapa cepat broker akan menyelesaikan pemulihan indeks sebelum diizinkan melayani trafik kembali.
Alur Logika Inisialisasi Booting Broker Kafka #
Berikut adalah diagram alur keputusan komprehensif dari sistem internal Kafka saat memproses inisialisasi boot server untuk melakukan pemulihan log:
flowchart TD
Start["Booting Broker Kafka"] --> ReadDirs["LogManager: Baca direktori data (log.dirs)"]
ReadDirs --> CheckMarker{"Apakah file 'clean-shutdown' ada?"}
CheckMarker -- "Ya (Clean Shutdown)" --> MountInstant["Pasang log segment secara instan"]
MountInstant --> FetcherStart["Aktifkan Replica Fetcher Threads"]
CheckMarker -- "Tidak (Unclean Shutdown)" --> ScanLogs["Mulai Pemindaian Log Kotor (Unclean Recovery)"]
ScanLogs --> FindActiveSeg["Cari file segmen aktif terakhir (.log)"]
FindActiveSeg --> CRCCheck{"Verifikasi Checksum CRC setiap record"}
CRCCheck -- "Rusak / Bad CRC" --> TruncateCorrupt["Potong log segment tepat sebelum record rusak"]
CRCCheck -- "Semua OK" --> DeleteIndices["Hapus file .index & .timeindex kotor"]
TruncateCorrupt --> DeleteIndices
DeleteIndices --> RebuildIndices["Membaca ulang berkas .log dari awal segmen<br/>Rebuild file .index & .timeindex baru"]
RebuildIndices --> FetcherStart
FetcherStart --> CompareEpoch{"Bandingkan Epoch & LEO dengan Leader"}
CompareEpoch --> CheckTruncate{"Apakah ada data di atas HW Leader?"}
CheckTruncate -- "Ya" --> TruncateHW["Lakukan Log Truncation ke High Watermark Leader"]
CheckTruncate -- "Tidak" --> CatchUp["Fetch data baru dari Leader untuk mengejar ketertinggalan"]
TruncateHW --> CatchUp
CatchUp --> JoinISR["Masuk kembali ke kelompok In-Sync Replicas (ISR)"]
JoinISR --> Ready["Broker Siap Melayani Klien"]
Checklist Audit Kepatuhan Recovery Broker #
Lakukan evaluasi arsitektur kita menggunakan checklist berikut untuk menjamin proses pemulihan broker berjalan dengan andal dan efisien di produksi:
| No | Item Kepatuhan Recovery Broker | Metode Verifikasi | Status |
|---|---|---|---|
| 1 | Controlled Shutdown Aktif | Verifikasi bahwa parameter controlled.shutdown.enable=true dikonfigurasi pada berkas server.properties. |
[ ] |
| 2 | Heap JVM Terbatasi | Pastikan alokasi Heap JVM disetel kecil (4-6 GB) agar RAM tersisa penuh untuk mempercepat proses page cache recovery. | [ ] |
| 3 | Pembersihan File Penanda | Verifikasi bahwa file clean-shutdown otomatis terhapus saat Kafka dinyalakan dan terbentuk kembali saat dimatikan secara bersih. |
[ ] |
| 4 | Log Segment Sizing Tepat | Batasi ukuran maksimal log segment log.segment.bytes pada default 1 GB (jangan dibuat terlalu besar) untuk membatasi durasi rebuild indeks. |
[ ] |
| 5 | Thread Fetcher Cukup | Setel parameter num.replica.fetchers minimal 2 atau 4 pada server multi-core untuk mempercepat proses sinkronisasi paralel pasca-booting. |
[ ] |
| 6 | Antrean I/O Longgar | Pastikan parameter OS disk scheduler diatur dengan benar agar tidak memblokir thread LogManager saat melakukan scanning log. | [ ] |
Ringkasan #
- Wajib Controlled Shutdown — Selalu gunakan perintah shutdown bersih (
SIGTERM) agar broker sempat mengalihkan status kepemimpinan partisi dan menulis file penandaclean-shutdownguna mempercepat proses booting berikutnya.- Pahami Rebuild Indeks — Ketiadaan file penanda
clean-shutdownmemaksa Kafka memindai seluruh file log segment dan membangun ulang berkas indeks.index/.timeindexdari awal yang memakan waktu lama.- Log Truncation Menjaga Konsistensi — Follower baru yang terhubung kembali akan memotong datanya (log truncation) menyelaraskan posisi offset dengan High Watermark leader untuk menghindari divergensi data.
- Batasi Ukuran Segmen — Batasi ukuran maksimum segmen log (
log.segment.bytes=1GB) agar waktu pemindaian dan rekonstruksi file indeks kotor saat terjadi unclean recovery tetap rasional.
← Sebelumnya: Production Failure Scenarios Berikutnya: Rolling Upgrade & Maintenance →