Rolling Upgrade & Maintenance: Pemeliharaan Kluster Tanpa Downtime #

Dalam mengelola infrastruktur Apache Kafka di skala produksi yang melayani operasi bisnis non-stop 24/7, menghentikan seluruh kluster secara total (offline upgrade) untuk melakukan pemeliharaan perangkat keras atau pembaruan versi perangkat lunak adalah hal yang tidak dapat diterima. Setiap detik downtime kluster Kafka dapat menyebabkan terhentinya aliran data transaksi, hilangnya event bisnis, dan kegagalan sistem hilir yang bergantung padanya.

Untuk itu, kita harus menerapkan strategi Rolling Upgrade (Upgrade Bergilir). Melalui pendekatan ini, kita memperbarui node broker satu per satu secara bergiliran. Kluster tetap aktif melayani penulisan dan pembacaan dari aplikasi klien sepanjang proses pemeliharaan berlangsung. Namun, melakukan rolling upgrade pada sistem stateful terdistribusi seperti Kafka memerlukan disiplin protokol yang ketat. Kita harus memastikan versi biner baru, versi protokol komunikasi antar-broker (inter-broker protocol), dan format penyimpanan pesan pada disk (log message format) diperbarui secara bertahap dan teratur untuk menghindari ketidakcocokan metadata.

Dalam panduan ini, kita akan membahas filosofi rolling upgrade, mengupas 3 tahapan utama peningkatan versi Kafka, mendemonstrasikan perintah CLI untuk mengosongkan partisi broker (drain node) saat pemeliharaan hardware, serta menyusun checklist verifikasi pasca-upgrade untuk menjamin kesehatan kluster.

Filosofi Zero-Downtime Rolling Upgrade #

Tujuan utama dari rolling upgrade adalah mempertahankan ketersediaan kluster tinggi (high availability) di sisi klien sambil meminimalkan risiko kegagalan sistem. Selama proses rolling upgrade berjalan, kluster kita akan berada dalam kondisi hibrida atau Mixed-Version State (Status Versi Campuran), di mana sebagian broker berjalan dengan versi baru dan sebagian lagi masih berjalan dengan versi lama.

flowchart TD
    B1["Broker 1 (v3.7)"] <== "Protokol v3.6" ==> B2["Broker 2 (v3.6)"]
    B1 -- "v3.6 Protocol" --> B3["Broker 3 (v3.6)"]
    B2 -- "v3.6 Protocol" --> B3
  • Broker 1 sudah di-upgrade ke v3.7, tetapi ia dipaksa berbicara menggunakan bahasa protokol v3.6 agar Broker 2 & 3 yang belum di-upgrade tetap saling paham.

Agar broker versi baru dapat berkomunikasi dengan broker versi lama tanpa merusak koordinasi metadata, Kafka menyediakan dua parameter konfigurasi khusus untuk mengunci kompatibilitas protokol:

  1. inter.broker.protocol.version: Membatasi versi protokol komunikasi yang digunakan antar broker dalam berkomunikasi. Selama transisi, parameter ini dikunci pada versi terlama.
  2. log.message.format.version: Membatasi versi format penyimpanan record pesan pada disk. Ini memastikan bahwa struktur byte pesan yang ditulis di disk tetap seragam sehingga dapat dibaca oleh broker versi lama.

Alur Kerja Upgrade Bergilir 3 Tahap #

Proses peningkatan versi Apache Kafka secara aman harus dilakukan melalui tiga tahap utama yang berurutan. Melompati tahapan ini atau menggabungkannya sekaligus di awal akan memicu unclean shutdown atau kegagalan quorum yang fatal.

Tahap 1: Upgrade Biner Perangkat Lunak Broker (Broker-by-Broker) #

Pada tahap ini, kita mengganti kode biner Kafka lama dengan biner versi baru di setiap server, satu demi satu.

Untuk setiap broker di dalam kluster (lakukan satu per satu secara bergilir):

  1. Kunci Protokol: Sebelum mematikan broker pertama, pastikan berkas server.properties di seluruh broker telah mengonfigurasi inter.broker.protocol.version dan log.message.format.version pada versi lama saat ini.
  2. Hentikan Broker: Matikan proses Kafka secara bersih (systemctl stop kafka).
  3. Pembaruan Biner: Instal paket biner Kafka versi baru (misalnya mengganti versi file JAR).
  4. Nyalakan Broker: Hidupkan kembali broker. Broker baru ini akan berjalan menggunakan biner baru, namun dipaksa berkomunikasi menggunakan bahasa protokol lama karena adanya setelan kunci di berkas properti.
  5. Verifikasi: Tunggu hingga broker tersebut selesai melakukan sinkronisasi log (catch up) dan masuk kembali ke seluruh kelompok ISR sebelum melanjutkan ke broker berikutnya.

Tahap 2: Upgrade Versi Protokol Inter-Broker #

Setelah seluruh broker di dalam kluster sukses berjalan menggunakan biner versi baru:

  1. Ubah Konfigurasi Protokol: Perbarui nilai properti inter.broker.protocol.version di berkas server.properties seluruh broker ke versi baru.
  2. Restart Bergilir Kedua: Lakukan restart bergilir (rolling restart) sekali lagi untuk setiap broker agar setelan protokol baru tersebut aktif. Setelah tahap ini selesai, seluruh broker telah berkomunikasi menggunakan protokol versi baru yang lebih efisien.

Tahap 3: Upgrade Versi Format Pesan #

Setelah protokol baru aktif secara stabil di seluruh kluster:

  1. Ubah Format Pesan: Perbarui nilai properti log.message.format.version di berkas server.properties seluruh broker ke versi format pesan baru.
  2. Restart Bergilir Ketiga: Lakukan restart bergilir terakhir pada setiap broker untuk menerapkan format tulis disk baru.

Penting: Mulai versi Kafka 3.0+, format pesan default sudah dikelola secara internal berdasarkan inter-broker protocol untuk sebagian besar konfigurasi. Namun, untuk kluster lama yang dimigrasikan, langkah penalaan eksplisit ini tetap krusial.


Upgrade Fitur Metadata pada Kluster Mode KRaft #

Untuk kluster modern yang berjalan pada mode KRaft (tanpa ZooKeeper), proses penyesuaian kompatibilitas metadata tidak lagi dilakukan dengan menulis parameter statis ke berkas properti. KRaft menyederhanakan proses ini menggunakan fitur Metadata Version yang dikelola secara terpusat di dalam log metadata internal.

Setelah seluruh broker KRaft diperbarui ke biner versi baru (misalnya biner versi 3.7):

  1. Periksa Versi Metadata Saat Ini: Jalankan perintah berikut untuk melihat versi metadata aktif saat ini:
    kafka-features.sh --bootstrap-server localhost:9092 \
      --command-config /etc/kafka/client.properties \
      describe
    
  2. Upgrade Fitur Metadata: Kirim instruksi upgrade metadata ke quorum controller tanpa perlu melakukan restart broker sekali lagi:
    kafka-features.sh --bootstrap-server localhost:9092 \
      --command-config /etc/kafka/client.properties \
      upgrade --metadata 3.7
    

Quorum controller KRaft akan menulis pesan perubahan metadata ini ke log replika internal. Seluruh broker data KRaft akan membaca perubahan ini secara real-time dan langsung mengaktifkan fitur-fitur baru versi 3.7 secara instan.


Modifikasi Parameter: Konfigurasi Dinamis vs Statis #

Saat melakukan pemeliharaan kluster, kita harus membedakan mana parameter konfigurasi yang memerlukan restart bergilir (Read-Only Configs) dan mana parameter yang dapat diubah secara instan tanpa menyentuh tombol restart (Dynamic Configs).

Kita disarankan menggunakan perintah kafka-configs.sh untuk memodifikasi parameter dinamis secara langsung:

+-------------------------------------------------------------------------------+
|                       KLASIFIKASI PARAMETER KONFIGURASI                       |
|                                                                               |
|  1. READ-ONLY CONFIGS (Butuh Rolling Restart):                                |
|     * Properti: zookeeper.connect, listeners, log.dirs, num.io.threads        |
|     * Verifikasi: Wajib diubah di server.properties & restart broker.         |
|                                                                               |
|  2. DYNAMIC CONFIGS (Tanpa Restart):                                          |
|     * Properti: min.insync.replicas, max.message.bytes, log.cleaner.threads   |
|     * Verifikasi: Ubah via kafka-configs.sh --alter --entity-type brokers.    |
+-------------------------------------------------------------------------------+

Contoh mengubah batas ukuran pesan topik secara dinamis tanpa restart kluster:

kafka-configs.sh --bootstrap-server localhost:9092 \
  --command-config /etc/kafka/client.properties \
  --alter \
  --entity-type topics \
  --entity-name payment.orders \
  --add-config max.message.bytes=10485760

Penyeimbangan Kembali Kepemimpinan Partisi (Leader Rebalancing) #

Setelah sebuah broker dinyalakan kembali pasca-maintenance, ia akan bergabung kembali ke kluster sebagai pengikut (follower) untuk seluruh partisi. Kondisi ini membuat beban kepemimpinan (leadership) pada kluster menjadi timpang karena broker-broker yang tidak di-restart menanggung beban I/O tulis-baca klien lebih berat.

Secara default, Kafka mengelola proses ini secara otomatis melalui properti berikut:

  • auto.leader.rebalance.enable=true: Mengaktifkan thread background controller untuk memantau ketidakseimbangan kepemimpinan.
  • leader.imbalance.per.broker.percentage=10: Ambang batas toleransi ketidakseimbangan (default $10%$). Jika persentase partisi yang tidak dipimpin oleh preferred leader pada suatu broker melebihi batas ini, rebalance otomatis akan dipicu.
  • leader.imbalance.check.interval.seconds=300: Seberapa sering controller memeriksa ketidakseimbangan (default 5 menit).

Rekomendasi Skala Besar: Pada kluster dengan lalu lintas data sangat tinggi, rebalance otomatis di siang hari dapat memicu lonjakan latensi jaringan akibat pergeseran rute klien yang mendadak. Kita disarankan menyetel auto.leader.rebalance.enable=false dan memicu preferred leader election secara manual menggunakan penjadwalan cron job di malam hari saat lalu lintas data sepi (off-peak hours).


Otomatisasi Pemeliharaan Menggunakan Cruise Control #

Bagi kita yang mengelola kluster berskala besar dengan puluhan broker dan ribuan partisi, melakukan reassignment partisi dan restart bergilir secara manual menggunakan CLI sangat rawan kesalahan dan lambat. Industri skala besar menggunakan Cruise Control (alat otomatisasi dari LinkedIn) untuk mengelola siklus hidup kluster.

Cruise Control memantau penggunaan resource CPU, memori, I/O disk, dan bandwidth jaringan dari setiap broker secara terus-menerus. Saat kita memicu perintah maintenance, Cruise Control akan:

  • Menghitung rencana reassignment partisi yang optimal untuk mengosongkan server tanpa membebani kartu jaringan.
  • Membatasi throughput replikasi data (bandwidth throttling) secara dinamis agar pemindahan data tidak mengganggu latensi aplikasi klien.
  • Melakukan rolling restart pada broker secara otomatis dengan memeriksa status ISR secara aman.

Prosedur Pemeliharaan Hardware Aman (Drain Node) #

Sering kali kita harus mematikan server broker fisik bukan untuk memperbarui versi Kafka, melainkan untuk melakukan pemeliharaan hardware Bare Metal (seperti menambah RAM, mengganti disk yang rusak, atau merawat motherboard). Untuk melakukan hal ini tanpa memicu degradasi replikasi, kita harus melakukan Drain Node (Pengosongan Partisi) secara terkontrol.

Berikut adalah diagram alur proses drain node sebelum mematikan server target:

flowchart TD
    Start["Mulai Pemeliharaan Broker Target (e.g. Broker 1)"] --> Reassign["1. Siapkan JSON Reassignment Partisi:<br/>Pindahkan replika dari Broker 1 ke broker lain"]
    Reassign --> ExecReassign["2. Jalankan Perintah kafka-reassign-partitions.sh --execute"]
    
    ExecReassign --> CheckProgress{"Apakah progress reassignment 100% selesai?"}
    
    CheckProgress -- "Tidak" --> Wait["Tunggu & Verifikasi dengan --verify"]
    Wait --> CheckProgress
    
    CheckProgress -- "Ya" --> ForceLeader{"3. Pindahkan status kepemimpinan (Leader) sisa<br/>menggunakan preferred leader election"}
    
    ForceLeader --> StopKafka["4. Matikan proses Kafka: systemctl stop kafka"]
    StopKafka --> Maintenance["5. Lakukan Pemeliharaan Fisik Server"]
    
    Maintenance --> StartKafka["6. Hidupkan kembali server dan proses Kafka"]
    StartKafka --> RevertPart["7. Kembalikan partisi data semula jika dibutuhkan"]
    RevertPart --> End["Pemeliharaan Selesai"]

Langkah Kerja Drain Node via CLI: #

1. Evakuasi Partisi Data #

Kita harus memindahkan seluruh replika partisi yang berada di broker target (misalnya Broker 1) ke broker sehat lainnya di dalam kluster. Buat sebuah berkas konfigurasi reassignment bernama reassign.json:

{
  "version": 1,
  "partitions": [
    { "topic": "payment.orders", "partition": 0, "replicas": [2, 3, 4], "log_dirs": ["any", "any", "any"] }
  ]
}

Jalankan proses pemindahan data secara asinkron menggunakan perintah:

kafka-reassign-partitions.sh --bootstrap-server localhost:9092 \
  --command-config /etc/kafka/client.properties \
  --reassignment-json-file reassign.json \
  --execute

Pantau kemajuan pemindahan data hingga selesai $100%$:

kafka-reassign-partitions.sh --bootstrap-server localhost:9092 \
  --command-config /etc/kafka/client.properties \
  --reassignment-json-file reassign.json \
  --verify

2. Alihkan Sisa Kepemimpinan Partisi (Leader Election) #

Setelah pemindahan replika selesai, pastikan tidak ada sisa kepemimpinan partisi aktif yang menunjuk ke broker 1 dengan memicu preferred leader election ke broker lainnya:

kafka-leader-election.sh --bootstrap-server localhost:9092 \
  --command-config /etc/kafka/client.properties \
  --election-type preferred \
  --all-topic-partitions

Setelah seluruh partisi dan kepemimpinan bersih dari Broker 1, kita dapat mematikan server secara aman tanpa memicu alarm kegagalan replikasi di tim SRE.


Kepatuhan Operasional dan Checklist Audit Rolling Upgrade #

Gunakan checklist kepatuhan operasional berikut saat merencanakan pemeliharaan kluster produksi guna meminimalisir resiko downtime:

No Item Kepatuhan Rolling Upgrade Metode Verifikasi Status
1 Kunci Protokol Aktif Verifikasi bahwa parameter inter.broker.protocol.version terkunci pada versi lama di seluruh broker sebelum biner diperbarui. [ ]
2 Status ISR Sehat Jalankan audit status partisi. Pastikan tidak ada Under-Replicated Partitions (URP = 0) sebelum mematikan broker pertama. [ ]
3 Pindahkan Leader Alihkan status leader aktif dari broker sasaran sebelum melakukan controlled shutdown untuk meminimalkan jeda I/O klien. [ ]
4 Batas Waktu Tunggu Cukup Tunggu minimal 10-15 menit antar restart broker untuk memberi kesempatan bagi follower melakukan sinkronisasi data segmen log. [ ]
5 Pantau GC Pause Periksa log GC pasca-restart broker baru untuk memastikan stabilitas heap memori JVM tidak terganggu oleh biner baru. [ ]
6 Reassignment Selesai Jalankan verifikasi reassignment untuk memastikan seluruh replika data telah bermigrasi sempurna sebelum server fisik dimatikan. [ ]

Ringkasan #

  • Terapkan Upgrade 3 Tahap — Selalu lakukan peningkatan versi melalui tiga fase terpisah secara bergilir: peningkatan versi biner, peningkatan versi protokol komunikasi, dan terakhir peningkatan format pesan disk.
  • Kunci Parameter Kompatibilitas — Gunakan setelan inter.broker.protocol.version untuk memblokir broker versi baru agar tidak mengirimkan instruksi yang tidak dipahami oleh broker versi lama selama masa transisi.
  • Lakukan Drain Node Terkontrol — Pindahkan seluruh replika partisi keluar dari broker sasaran menggunakan perintah kafka-reassign-partitions.sh sebelum mematikan server untuk pemeliharaan hardware fisik.
  • Verifikasi ISR Sebelum Lanjut — Jangan pernah merestart broker berikutnya sebelum broker yang baru di-upgrade selesai melakukan pemulihan log dan masuk kembali ke kelompok ISR kluster.

← Sebelumnya: Broker Recovery Process   Berikutnya: Centralized vs Decentralized Clusters →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact