Topic #

Di dalam ekosistem Apache Kafka, topic (topik) adalah konsep paling mendasar yang bertindak sebagai wadah logis atau kategori untuk mengelompokkan aliran event yang sejenis. Jika kita menganalogikan Kafka dengan database relasional tradisional, topik mirip dengan sebuah tabel. Jika kita menganalogikannya dengan sistem berkas, topik bertindak seperti sebuah folder penyimpanan. Memahami bagaimana topik dirancang secara logis, dikelola secara fisik di tingkat broker, dan dikonfigurasi secara optimal adalah kunci utama untuk mencegah kegagalan arsitektur data kita di masa mendatang.


Konsep Dasar: Apa itu Topic? #

Secara logis, sebuah topik di Apache Kafka berfungsi sebagai saluran (channel) atau pipa data tempat produsen (producer) mengirimkan event dan konsumen (consumer) membaca data tersebut. Topik bersifat multi-produsen dan multi-konsumen. Artinya, sebuah topik dapat menerima kiriman aliran data dari banyak aplikasi produsen yang berbeda secara bersamaan, dan di saat yang sama, data di dalam topik tersebut dapat dibaca secara independen oleh banyak kelompok konsumen dengan tujuan bisnis yang berbeda-beda.

Karakteristik paling unik dari topik di Kafka adalah sifat pembacaannya yang non-destructive. Pada sistem broker pesan tradisional seperti JMS (Java Message Service) atau RabbitMQ, ketika sebuah aplikasi membaca pesan dari antrean, pesan tersebut akan dihapus dari antrean sehingga tidak dapat dibaca oleh aplikasi lain.

Di Kafka, event yang ditulis ke dalam topik bersifat permanen dan tidak langsung dihapus setelah dibaca. Data akan terus berada di dalam topik hingga batas waktu penyimpanan (retensi) yang kita tentukan terlampaui. Hal ini memungkinkan satu aliran data yang sama (misalnya, aliran transaksi penjualan) dikonsumsi oleh Layanan Keuangan untuk pembukuan, Layanan Inventaris untuk memperbarui stok barang, dan Layanan Analitik untuk dasbor bisnis secara real-time tanpa saling mengganggu.


Struktur Internal Topik: Logis vs Fisik #

Penting bagi kita untuk memahami perbedaan antara representasi logis sebuah topik dengan implementasi fisik penyimpanannya di dalam kluster Kafka. Secara logis, kita melihat topik sebagai satu kesatuan aliran data linier yang utuh dari awal hingga akhir. Namun, secara fisik di balik layar, Kafka memecah topik menjadi beberapa bagian kecil yang disebut Partisi (Partition).

Mari kita visualisasikan bagaimana sebuah topik tunggal dibagi menjadi beberapa partisi fisik yang didistribusikan ke berbagai broker server di dalam kluster Kafka:

flowchart TD
    subgraph Logis ["Tampilan Logis (Aplikasi Klien)"]
        TopicLogis["Topik: transaksi-pembayaran <br/> (Aliran Event Terpadu)"]
    end

    subgraph Fisik ["Tampilan Fisik (Kluster Kafka)"]
        subgraph Broker1 ["Broker 1 (Server A)"]
            Partisi0[("Partisi 0 <br/> (Log File 0)")]
        end
        subgraph Broker2 ["Broker 2 (Server B)"]
            Partisi1[("Partisi 1 <br/> (Log File 1)")]
        end
        subgraph Broker3 ["Broker 3 (Server C)"]
            Partisi2[("Partisi 2 <br/> (Log File 2)")]
        end
    end

    TopicLogis --> Partisi0
    TopicLogis --> Partisi1
    TopicLogis --> Partisi2

Pembagian fisik ke dalam partisi-partisi ini adalah rahasia utama mengapa Apache Kafka memiliki performa throughput yang sangat luar biasa dan skalabilitas horizontal yang hampir tak terbatas. Setiap partisi adalah sebuah berkas log append-only terurut yang disimpan di disk lokal salah satu server broker Kafka.

Dengan membagi topik menjadi beberapa partisi, Kafka dapat mendistribusikan beban penyimpanan dan pemrosesan data ke seluruh server broker di dalam kluster. Kita tidak lagi dibatasi oleh kapasitas penyimpanan disk atau kemampuan I/O dari satu server tunggal.


Kebijakan Retensi Data Tingkat Topik (Retention Policy) #

Tidak seperti database tradisional yang menyimpan seluruh data secara permanen secara bawaan, Kafka dirancang sebagai sistem pemrosesan aliran data temporal. Kita mengelola siklus hidup data di dalam topik melalui kebijakan retensi (retention policy). Kebijakan ini dapat dikonfigurasi secara independen untuk setiap topik yang ada di dalam kluster kita.

Ada dua metode utama yang digunakan Kafka untuk menentukan kapan data di dalam topik harus dibersihkan:

1. Retensi Berbasis Waktu (Time-Based Retention) #

Kebijakan ini diatur melalui parameter konfigurasi retention.ms. Parameter ini menentukan berapa lama sebuah event boleh menetap di dalam partisi sebelum dihapus. Konfigurasi bawaan kluster biasanya diatur selama 168 jam (7 hari).

Sebagai contoh, jika kita mengatur retention.ms ke 86400000 (24 jam), maka event yang masuk pada hari Senin pukul 08.00 akan secara otomatis dihapus dari disk broker pada hari Selasa pukul 08.00. Kebijakan ini sangat cocok untuk data streaming berulang yang kegunaannya menurun seiring berjalannya waktu, seperti log metrik aplikasi atau data koordinat GPS armada kurir.

2. Retensi Berbasis Ukuran (Size-Based Retention) #

Kebijakan ini diatur menggunakan parameter retention.bytes. Parameter ini membatasi ukuran akumulasi data maksimum dari sebuah partisi di dalam disk. Penting untuk dicatat bahwa batasan ini berlaku per partisi, bukan per topik secara keseluruhan.

Misalnya, jika sebuah topik memiliki 3 partisi dan kita mengatur retention.bytes ke 10737418240 (10 GB), maka batas total ukuran penyimpanan untuk topik tersebut adalah 30 GB di seluruh kluster. Ketika ukuran berkas segmen log di salah satu partisi melebihi 10 GB, Kafka akan menghapus segmen data tertua di partisi tersebut hingga ukurannya kembali di bawah batas aman. Kebijakan ini sangat krusial untuk mencegah server kita kehabisan ruang penyimpanan disk (disk space out-of-memory) akibat lonjakan data yang tidak terduga.

Kebijakan Pembersihan: Delete vs Compact #

Kafka menyediakan parameter cleanup.policy untuk menentukan apa yang harus dilakukan ketika batas retensi tercapai:

  • delete (Bawaan): Kafka akan menghapus seluruh data lama yang sudah melewati batas retensi waktu atau ukuran secara permanen dari disk.
  • compact (Log Compaction): Daripada menghapus data secara mentah-mentah, Kafka akan memindai partisi dan hanya menyisakan satu event dengan nilai terbaru (latest state) untuk setiap Key unik yang ada. Data historis perantara akan dibuang, namun catatan keadaan terakhir dari suatu entitas tidak akan pernah hilang. Kebijakan ini sangat ideal untuk arsitektur event-driven seperti menyimpan profil pengguna atau saldo akun keuangan.

Standarisasi Penamaan Topik (Topic Naming Convention) #

Dalam organisasi skala menengah hingga besar yang mengadopsi arsitektur microservices, jumlah topik Kafka di dalam kluster produksi dapat melonjak dengan sangat cepat hingga ratusan bahkan ribuan topik. Tanpa adanya konvensi penamaan topik (Topic Naming Convention) yang ketat dan disepakati bersama sejak awal, kluster kita akan segera berubah menjadi hutan belantara data yang membingungkan, sulit dikelola, dan rentan terhadap kebocoran keamanan.

Konvensi penamaan yang baik harus bersifat deskriptif, konsisten, mudah dipahami oleh pengembang baru, dan dirancang agar mendukung konfigurasi keamanan berbasis pola wildcard (seperti otorisasi ACL).

Format standardisasi penamingan topik yang direkomendasikan secara luas di industri adalah sebagai berikut:

$$\langle\text{lingkungan}\rangle.\langle\text{domain}\rangle.\langle\text{subdomain}\rangle.\langle\text{tipe_data}\rangle.\langle\text{nama_event}\rangle$$

Mari kita bedah masing-masing komponen pembentuk nama topik tersebut:

  • Lingkungan (Environment): Menandakan kluster tempat topik berada. Contoh: prod (produksi), staging (uji coba), atau dev (pengembangan).
  • Domain Utama (Domain): Nama departemen atau batas konteks (bounded context) utama bisnis kita. Contoh: finance (keuangan), logistic (logistik), atau marketing (pemasaran).
  • Sub-Domain (Sub-domain): Sub-sistem spesifik di bawah domain utama. Contoh: payment (pembayaran), billing (tagihan), atau tracking (pelacakan lokasi).
  • Tipe Data (Data Type): Menjelaskan jenis isi data di dalam topik. Nilai yang umum digunakan adalah:
    • fact: Berisi catatan kejadian masa lalu yang tidak dapat dibantah (fakta) dan biasanya hanya ditambahkan terus (immutable event log).
    • command: Berisi instruksi atau permintaan asinkron untuk melakukan sesuatu.
    • cdc: Hasil rekaman perubahan langsung dari database utama (Change Data Capture).
  • Nama Event (Event Name): Keterangan spesifik dalam bentuk kata kerja lampau yang menjelaskan peristiwa tersebut. Contoh: transaction-completed, user-registered, atau order-dispatched.

Contoh Perbandingan Penamaan Topik: #

  • BURUK (Terlalu generik, tidak ada konteks):
    • transaksi
    • data-user
    • kafka-test
  • BAIK (Terstruktur, deskriptif, dan aman):
    • prod.finance.payment.fact.transaction-completed
    • prod.logistic.tracking.cdc.courier-location
    • staging.marketing.campaign.command.send-newsletter

Dengan menggunakan format terstruktur seperti di atas, tim Administrator Kafka (SRE) dapat dengan sangat mudah menerapkan aturan otorisasi keamanan ACL (Access Control List) secara otomatis. Misalnya, mereka cukup menuliskan satu aturan tunggal: “Layanan Keuangan diperbolehkan membaca semua topik dengan pola awalan prod.finance.*.


Konfigurasi Kritis Tingkat Topik #

Meskipun broker Kafka memiliki konfigurasi bawaan global untuk semua topik, ada banyak use case di mana kita perlu melakukan kustomisasi parameter spesifik per topik untuk menyesuaikan dengan kebutuhan performa atau tingkat keamanan data tertentu.

Tabel di bawah ini merangkum parameter konfigurasi tingkat topik terpenting yang wajib kita ketahui dan kelola secara bijak:

Parameter Konfigurasi Nilai Default Dampak Praktis & Rekomendasi Penggunaan
cleanup.policy delete Menentukan metode pembersihan segmen log. Gunakan delete untuk data transaksi umum, dan gunakan compact untuk topik stateful seperti master data.
min.insync.replicas 1 Menentukan jumlah minimum broker replika yang harus mengonfirmasi penulisan sebelum produsen menerima status sukses. Untuk lingkungan produksi, selalu set ke minimal 2.
compression.type producer Menentukan algoritma kompresi data yang digunakan di disk broker. Set ke lz4 atau zstd untuk menghemat ruang penyimpanan disk dan bandwidth jaringan secara signifikan.
segment.ms 604800000 (7 hari) Menentukan batas waktu maksimum sebelum Kafka memaksa menutup file segmen log aktif dan membuka file baru. Perkecil nilai ini jika kita membutuhkan penghapusan data secara presisi.
max.message.bytes 1048588 (~1 MB) Menentukan ukuran pesan maksimum yang diizinkan masuk ke topik. Hindari menaikkan nilai ini di atas 5 MB; gunakan pola Claim Check untuk file berukuran besar.

Kesalahan Umum (Anti-pattern) dalam Pengelolaan Topik #

Dalam merancang dan mengelola topik di lingkungan produksi kluster Apache Kafka, ada beberapa pola kesalahan umum (anti-pattern) yang sering dilakukan oleh pengembang dan dapat berakibat fatal bagi kestabilan serta performa kluster kita.

1. Mengaktifkan Fitur Auto-Creation Topik secara Liar #

Secara bawaan, broker Kafka dikonfigurasi dengan parameter auto.create.topics.enable = true. Artinya, jika sebuah aplikasi produsen mengirim pesan ke nama topik yang sebenarnya belum pernah dibuat di kluster, broker secara otomatis akan membuat topik tersebut menggunakan parameter default (biasanya hanya memiliki 1 partisi dan replication factor = 1).

Konsekuensi Kegagalan: Pengembang dapat secara tidak sengaja salah mengetik nama topik di dalam kode mereka (misalnya mengirim ke prod.finance.paymment dengan dua huruf ’m’). Kafka akan membuat topik salah ketik tersebut secara otomatis. Hal ini mengotori daftar topik kluster, menurunkan performa, serta yang paling berbahaya adalah data sensitif terkirim ke topik yang tidak memiliki konfigurasi replikasi aman dan tidak dipantau oleh konsumen mana pun.

# ANTI-PATTERN: Bergantung pada auto-creation topik secara dinamis di produksi
# Kesalahan pengetikan nama topik akan memicu pembuatan topik baru yang tidak terkonfigurasi dengan aman.
def kirim_event_auto_create(producer, event_data):
    # Salah mengetik nama topik 'payment' menjadi 'paymeent'
    # Jika auto-create aktif, broker akan membuat topik liar dengan spesifikasi minimal yang tidak aman
    producer.send('prod.finance.paymeent', value=event_data)

# Solusi yang BENAR:
# 1. Nonaktifkan pembuatan otomatis di file server.properties broker: auto.create.topics.enable = false
# 2. Selalu buat topik secara deklaratif menggunakan tool admin (CLI atau Terraform) sebelum aplikasi dijalankan
# 3. Tangani exception kegagalan pengiriman di kode aplikasi jika topik tujuan tidak ditemukan
def kirim_event_aman(producer, event_data):
    try:
        producer.send('prod.finance.payment', value=event_data)
    except Exception as e:
        # Menangani error jika topik belum terdaftar di kluster
        logger.error(f"Gagal mengirim data! Topik tujuan tidak terdaftar di Kafka: {e}")
        simpan_ke_antrean_darurat(event_data)

2. Membuat Terlalu Banyak Topik secara Dinamis (Topik Per Entitas) #

Beberapa tim pengembang yang terbiasa dengan database NoSQL mencoba menerapkan pola desain yang sama ke Kafka dengan membuat satu topik secara dinamis untuk setiap entitas unik (misalnya membuat topik user.topic.ID_USER_123, user.topic.ID_USER_456, dst.).

Konsekuensi Kegagalan: Setiap topik yang terbagi menjadi beberapa partisi membutuhkan alokasi file handle di sistem operasi broker, koordinasi metadata di KRaft/ZooKeeper, dan memori buffer di sisi aplikasi klien. Membuat ribuan hingga jutaan topik secara dinamis akan membuat kluster Kafka kita mati total karena kehabisan resource memori (Out Of Memory) dan memicu kemacetan koordinasi metadata cluster secara parah. Topik harus selalu bersifat statis berdasarkan kategori bisnis, bukan dinamis berdasarkan ID pengguna.


Ringkasan #

  • Definisi Topik — Topik adalah kategori logis pembungkus aliran data event yang sejenis, bersifat multi-producer dan multi-consumer, serta memiliki sifat pembacaan non-destructive (data tidak langsung terhapus setelah dikonsumsi).
  • Logis vs Fisik — Topik adalah abstraksi logis di sisi aplikasi. Secara fisik di dalam kluster broker server, topik dipecah menjadi beberapa Partisi berupa berkas berkas log append-only terurut di disk lokal.
  • Kebijakan Retensi — Siklus hidup data di dalam topik dikelola berdasarkan batas waktu (retention.ms) atau batas ukuran penyimpanan (retention.bytes) per partisi.
  • Kebijakan Pembersihan — Kita dapat menentukan kebijakan pembersihan segmen log melalui cleanup.policy dengan pilihan delete (hapus data lama secara total) atau compact (hanya mempertahankan state terakhir dari setiap key unik).
  • Standarisasi Penamaan — Selalu terapkan konvensi penamaan topik yang terstruktur (contoh: <env>.<domain>.<subdomain>.<type>.<event_name>) untuk memudahkan tata kelola dan konfigurasi keamanan ACL kluster.
  • Matikan Auto-Create — Pastikan parameter auto.create.topics.enable diatur ke nilai false pada kluster produksi untuk mencegah terciptanya topik-topik liar akibat kesalahan penulisan kode aplikasi produsen.

← Sebelumnya: Event   Berikutnya: Partition →

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