Apa itu Kafka?

Log kejadian sebagai model data Kafka dibandingkan dengan antrean pesan tradisional dan basis data, beserta alasan modelnya penting.

Daftar isi

Apache Kafka memandang data yang mengalir di dalamnya sebagai log kejadian (event log) yang hanya dapat ditambah, bukan sebagai antrean yang mengosongkan dirinya sendiri maupun tabel yang terus dimutakhirkan. Topik ini menjelaskan model log kejadian itu terlebih dahulu, kemudian membandingkannya dengan antrean pesan dan basis data, lalu menunjukkan alasan modelnya menentukan banyak perilaku Kafka di lapangan. Setelah membaca topik ini, perbedaan antara sistem yang menghapus pesan setelah diambil dan sistem yang menyimpannya untuk dibaca ulang dapat dinyatakan dengan tepat.

Log kejadian sebagai model data#

Kafka menyimpan pesan dalam bentuk log kejadian, yaitu urutan pesan yang hanya dapat ditambah di ujung dan tidak dapat disunting maupun dihapus satu per satu. Setiap pesan menempati satu posisi bernomor yang disebut offset, dan nomor posisi itu tetap berlaku selama pesannya tersimpan. Penulisan selalu terjadi di ujung log, sedangkan pembacaan dapat dimulai dari posisi mana pun tanpa mengubah isi log. Model ini dijalankan secara terdistribusi, sehingga satu log bisa saja terpecah ke beberapa server sekaligus.

Diagram berikut memperlihatkan perbedaan perilaku pada situasi yang sama, yaitu dua consumer (aplikasi pembaca pesan) membaca tiga pesan. Pada antrean pesan, setiap pesan diberikan kepada satu consumer dan langsung dihapus. Pada log kejadian, kedua consumer membaca dari posisinya masing-masing, sedangkan isi log tetap utuh.

antrean pesanpesan 1pesan 2pesan 3consumer Aconsumer Bpesan dihapus setelah diambillog kejadian di Kafkaoffset 0pesanan-101offset 1pesanan-102offset 2pesanan-103consumer Aconsumer Bpembacaan independen, log tetap utuh
Antrean pesan dan log kejadian saat dua consumer membaca tiga pesan

Offset bersifat permanen, sehingga sebuah consumer dapat berhenti dan dijalankan ulang, lalu melanjutkan pembacaan dari posisi semula. Broker (server Kafka) menyimpan pesan sesuai periode retensi yang ditetapkan, misalnya tujuh hari, tanpa memandang apakah pesan itu sudah dibaca atau belum. Sifat-sifat tersebut menjadikan Kafka lebih mirip arsip berurutan yang dapat dibaca ulang daripada angkutan pesan yang mengosongkan dirinya.

Perbedaan dengan antrean pesan#

Antrean pesan tradisional memperlakukan satu pesan sebagai satu pekerjaan yang hanya boleh dikerjakan sekali. Consumer yang mengambil pesan dari kepala antrean memicu penghapusannya, sehingga dua consumer pada antrean yang sama saling membagi pekerjaan dan tidak ada yang membaca seluruh isi. Model ini tepat untuk antrean tugas yang tidak perlu diulang, tetapi menghilangkan kemampuan membaca ulang pesan yang sudah diambil.

Demo berikut mensimulasikan kedua model dengan Python murni tanpa broker. Sebuah antrean diisi tiga pesanan dan dibaca oleh dua consumer, kemudian log dengan isi yang sama dibaca dari posisi yang berbeda.

python log-dan-antrean.py
# Simulasi dua model data: antrean yang menghapus pesan dan log yang menyimpannya.

PESAN = ["pesanan-101", "pesanan-102", "pesanan-103"]

def jalankan_antrean():
    print("model antrean: pesan dihapus begitu diambil")
    antrean = list(PESAN)
    for nama in ("consumer A", "consumer B"):
        print(f"{nama} mengambil {antrean.pop(0)}")
    print(f"isian antrean tersisa: {antrean}")

def jalankan_log():
    print("model log: pesan tetap ada, pembacaan bergerak lewat offset")
    log = list(PESAN)
    posisi_awal = {"consumer A": 0, "consumer B": 1}
    for nama, offset in posisi_awal.items():
        while offset < len(log):
            print(f"{nama} membaca offset {offset}: {log[offset]}")
            offset += 1
    print(f"isian log tersisa: {log}")

jalankan_antrean()
jalankan_log()
text Keluaran
model antrean: pesan dihapus begitu diambil
consumer A mengambil pesanan-101
consumer B mengambil pesanan-102
isian antrean tersisa: ['pesanan-103']
model log: pesan tetap ada, pembacaan bergerak lewat offset
consumer A membaca offset 0: pesanan-101
consumer A membaca offset 1: pesanan-102
consumer A membaca offset 2: pesanan-103
consumer B membaca offset 1: pesanan-102
consumer B membaca offset 2: pesanan-103
isian log tersisa: ['pesanan-101', 'pesanan-102', 'pesanan-103']

Keluaran memperlihatkan perbedaan yang menentukan. Pada antrean, consumer A mengambil pesanan-101 dan consumer B mengambil pesanan-102, sehingga tidak ada satu consumer pun yang membaca semua pesan. Pada log, consumer A membaca seluruh urutan mulai dari offset 0, sedangkan consumer B melompat ke offset 1 dan membaca sisanya. Baris terakhir menegaskan bahwa isi log tetap utuh karena pembacaan tidak menghapus apa pun.

Perbedaan dengan basis data#

Basis data relasional menyimpan keadaan terkini dan mengizinkan perubahan data melalui perintah pembaruan, sedangkan log kejadian menyimpan sejarah kejadian yang tidak dapat diubah. Kafka tidak menyediakan bahasa kueri, indeks berdasarkan nilai pesan, maupun penggabungan antar tabel, sehingga pencarian acak atas isi pesan bukan pekerjaan Kafka. Meskipun begitu, pesan tersimpan di diska dan bertahan sesuai retensi, sehingga peran Kafka sebagai tempat penyimpanan tetap nyata. Tabel berikut merangkum perbedaan antrean pesan, basis data, dan log kejadian Kafka.

AspekAntrean pesanBasis dataLog kejadian Kafka
Nasib pesan setelah dibacaDihapusTetap adaTetap ada sesuai retensi
Model dataPekerjaan tunggalKeadaan terkiniSejarah kejadian
Cara mengaksesMengambil dari kepala antreanKueri bebasMembaca berurutan per partisi
Mengubah data lamaTidak ada datanyaDapat diubahTidak dapat diubah

Perbedaan itu menjelaskan posisi Kafka dalam arsitektur sistem. Kafka mengalirkan sejarah kejadian dari sistem sumber ke banyak pembaca, sedangkan basis data menerima keadaan terkini yang dihitung dari sejarah tersebut. Keduanya saling melengkapi, dan pemilihan tempat penyimpanan bergantung pada pertanyaan yang ingin dijawab.

Mengapa model log penting#

Model log memisahkan waktu penulisan pesan dari waktu pembacaannya. Producer menulis pesan dan langsung berlanjut tanpa menunggu consumer siap, sedangkan consumer baru yang muncul beberapa jam kemudian tetap dapat membaca seluruh pesan sejak offset 0 selama retensi topic (kategori pesan) belum habis. Aplikasi yang gagal juga dapat diputar ulang (replay), yaitu membaca kembali urutan pesan lama untuk menghitung ulang hasilnya.

Contoh sederhananya adalah pencatatan suhu ruangan. Topic menerima pengukuran dari producer setiap menit, dan tiga aplikasi berbeda membaca topic yang sama untuk tiga tujuan berbeda, yaitu papan status, peringatan batas suhu, dan rekap harian. Ketiganya membaca data yang sama dari posisi masing-masing tanpa saling mengganggu. Perilaku semacam ini tidak dapat dicapai oleh antrean yang menghapus pesan setelah diambil, dan itulah alasan model log dipilih sebagai dasar Kafka.

Kesalahan umum#

Dua kesalahan berikut muncul ketika model log belum terpahami sepenuhnya. Keduanya berakar pada kebiasaan yang dibawa dari antrean pesan.

  1. Menganggap pesan hilang setelah dibaca. Consumer yang sudah membaca seluruh topic kadang dianggap membersihkan isinya, padahal penghapusan hanya diatur oleh retensi. Akibatnya, consumer baru yang membaca dari awal menemukan data lama yang tidak diharapkan. Perbaikannya adalah mengatur retention.ms atau retention.bytes pada topic bila data lama memang perlu disingkirkan.
  2. Menggunakan Kafka untuk pencarian acak atas isi pesan. Kafka menyimpan data tetapi tidak menyediakan kueri, sehingga kebutuhan pencarian dikerjakan sistem lain. Perbaikannya adalah menyalin data ke basis data atau mesin pencarian yang mendukung kueri, dengan Kafka tetap menjadi sumber sejarahnya.

Ringkasan#

  • Kafka menyimpan pesan sebagai log kejadian yang hanya dapat ditambah, dan setiap pesan menempati posisi offset yang tetap.
  • Antrean menghapus pesan setelah diambil, sedangkan log menyimpannya sehingga banyak consumer membaca secara independen.
  • Kafka bukan pengganti basis data karena tidak menyediakan kueri, tetapi menyimpan sejarah kejadian di diska sesuai retensi, dan sejarah itu dapat dibaca ulang.

Referensi#