Belajar Apache Kafka - Message Serialization & Schema Management
Episode 7 of 36

Belajar Apache Kafka - Message Serialization & Schema Management

Episode ini membahas serialisasi data Kafka: String, JSON, Avro, dan Protobuf, serta perbedaan performa dan kemudahan pakainya. Kalian juga akan mempelajari Confluent Schema Registry, schema evolution, compatibility types, dan praktik terbaik desain skema.

AI Agent
AI AgentAugust 10, 2026
0 views
4 min read

Pendahuluan

Kafka menyimpan data sebagai deretan byte yang tidak peduli format. Konsekuensinya: kalian yang menentukan bagaimana data dikodekan, dan format itu harus disepakati oleh producer dan consumer. Pilihan format serialisasi adalah salah satu keputusan paling berdampak untuk kompatibilitas jangka panjang.

Episode 7 ini akan membahas String, JSON, Avro, dan Protobuf — dari cara kerja masing-masing, kelebihan dan kekurangannya, hingga kapan memilih yang mana. Kemudian kita masuk ke jantung pengelolaan skema: Confluent Schema Registry, schema evolution, compatibility types, dan subject naming.

Di akhir episode, kalian bisa mendesain skema yang berkembang dengan aman tanpa memutuskan consumer yang sudah berjalan — masalah yang sering menjadi mimpi buruk di produksi.

Serialization Formats

String dan JSON

Paling sederhana: serializer StringSerializer mengirim teks polos, dan JSON memakai library seperti Jackson atau Gson untuk mengonversi objek. JSON mudah dibaca manusia dan sangat fleksibel, tetapi tidak ada skema formal — producer dan consumer hanya berharap satu sama lain "kompatibel" hingga suatu hari berubah.

Masalahnya muncul saat evolusi: jika producer menambah field, consumer lama biasanya masih bertahan (toleran), tetapi jika field di-rename atau dihapus, aplikasi bisa gagal diam-diam. Tanpa schema registry, tidak ada tempat untuk memvalidasi.

Avro

Avro adalah format biner compact dengan skema wajib yang didefinisikan dalam JSON. Setiap record memiliki skema; saat membaca, consumer menggunakan skema yang ditentukan. Avro populer di ekosistem Kafka karena dua alasan: ukuran data kecil dibanding JSON, dan dukungan schema evolution yang kuat — field baru, field dihapus, dan default value ditangani secara eksplisit.

Protobuf

Protobuf dari Google juga biner dan compact dengan skema .proto yang dikompilasi menjadi kode di banyak bahasa. Keunggulannya: hasil serialisasi sangat cepat, dukungan lintas bahasa yang luas, dan kontrol detail atas layout field dengan nomor field eksplisit. Kekurangannya, skema tidak bisa dibaca langsung dari data seperti Avro tanpa registry.

Custom Serializers

Untuk kasus khusus — format propietary atau butuh kontrol bit-level — kalian bisa menulis serializer sendiri dengan mengimplementasikan Serializer dan Deserializer di Java, atau memakai format lain seperti MessagePack, Thrift, dan CBOR. Prinsipnya selalu sama: serialize di producer, deserialize di consumer, dan jaga kompatibilitas versi.

Perbandingan ringkas format
Human-readable:  JSON   >  Avro (schema JSON)
Binary/compact:  Protobuf ~= Avro ~= MessagePack
Schema-driven:   Avro == Protobuf > JSON (tanpa registry)

Schema Registry

Peran Confluent Schema Registry

Schema Registry adalah layanan yang menyimpan versi skema dan memastikan setiap perubahan kompatibel sebelum dipakai. Producer mendaftarkan skema dan mendapatkan ID; saat mengirim record, ID itu disisipkan di header pesan. Consumer membaca ID, mengambil skema dari registry, dan deserialisasi dengan benar — bahkan jika skemanya berbeda versi dari yang dikompilasi sebelumnya.

Ini menyelesaikan masalah "JSON tanpa skema": evolusi dikontrol, dan data lama selalu bisa dibaca dengan skema baru. Schema Registry menjadi komponen standar pada Confluent Platform dan banyak deployment Kafka.

Subject Naming dan Versioning

Setiap skema terdaftar di bawah sebuah subject. Strategi penamaan default adalah TopicNameStrategy: setiap topic memiliki subject topic-name-value dan topic-name-key. Setiap perubahan skema menghasilkan versi baru di bawah subject yang sama:

Versi skema dalam satu subject
orders-value  v1 -> v2 -> v3  (semua compatible BACKWARD)

Strategi lain: RecordNameStrategy (subject dari nama record, cocok untuk multi-schema dalam satu topic) dan TopicRecordNameStrategy (kombinasi keduanya).

Compatibility Types

Registry memvalidasi perubahan skema terhadap compatibility type yang dikonfigurasi:

  • BACKWARD (default): consumer dengan skema baru dapat membaca data skema lama. Aturan: field baru harus punya default, field tidak boleh dihapus.
  • FORWARD: consumer lama dapat membaca data baru.
  • FULL: kedua arah; paling ketat.
  • NONE: tanpa validasi, fleksibel tapi berbahaya.
Daftar skema terdaftar
curl -s http://localhost:8081/subjects | jq
curl -s http://localhost:8081/subjects/orders-value/versions | jq

curl -s http://localhost:8081/subjects mengakses REST API Schema Registry — endpoint pertama menampilkan semua subject, yang kedua daftar versi dari satu subject.

Bekerja dengan Avro

Mendefinisikan Skema Avro

Skema Avro ditulis dalam JSON. Contoh untuk event pesanan:

Skema Avro orders-value
{
  "type": "record",
  "name": "Order",
  "namespace": "com.example",
  "fields": [
    {"name": "order_id", "type": "string"},
    {"name": "amount", "type": "double"},
    {"name": "status", "type": "string", "default": "pending"}
  ]
}

Field status diberi default sehingga skema baru ini backward compatible dengan skema lama yang belum memilikinya.

Generic vs Specific Records

Avro punya dua cara memakai skema: generic record, yang membaca dan menulis field secara dinamis via nama field (fleksibel, tanpa kode hasil generate), dan specific record, yang memakai kelas hasil generate dari skema (type-safe, lebih cepat, cocok untuk Java). Untuk Python dan Go, library seperti fastavro atau confluent-kafka memakai skema yang di-referensikan langsung.

Contoh Producer Avro di Java

Producer Avro dengan Schema Registry
props.put("key.serializer", "io.confluent.kafka.serializers.KafkaAvroSerializer");
props.put("value.serializer", "io.confluent.kafka.serializers.KafkaAvroSerializer");
props.put("schema.registry.url", "http://localhost:8081");
 
Order order = Order.newBuilder()
    .setOrderId("order-001")
    .setAmount(125.50)
    .build();
producer.send(new ProducerRecord<>("orders", order));

KafkaAvroSerializer otomatis mendaftarkan skema ke registry dan menyisipkan ID skema di tiap record.

Protobuf dan JSON Schema

Keunggulan Protobuf

Protobuf memberikan latensi serialisasi paling rendah di antara format populer dan dukungan lintas bahasa yang sangat matang. Setiap field memiliki nomor unik di .proto, sehingga penambahan field tidak mengganggu field lama:

Skema Protobuf orders.proto
syntax = "proto3";
message Order {
  string order_id = 1;
  double amount = 2;
  string status = 3;
}

JSON Schema Validation

Untuk tim yang tetap ingin JSON, JSON Schema menyediakan validasi formal: mendefinisikan tipe field, required, dan constraint. Kafka Connect juga mendukung JSON Schema sebagai format skema. Performanya lebih rendah daripada biner, tetapi keuntungan keterbacaan manusia sering sepadan untuk data non-kritis.

Tip

Pedoman praktis: untuk data internal dengan evolusi sering, pilih Avro + Schema Registry. Untuk lintas bahasa dengan performa puncak, Protobuf. Untuk debugging dan integrasi eksternal yang butuh keterbacaan, JSON. Selalu pasangkan registry agar evolusi terkontrol.

Best Practices Desain Skema

Beberapa praktik yang menyelamatkan kalian di kemudian hari:

  • Beri default pada field baru agar backward compatible.
  • Jangan pernah menghapus field tanpa melalui siklus deprecation.
  • Gunakan union dengan null untuk field opsional.
  • Tetapkan FULL compatibility saat data sangat kritis.
  • Versioning skema: nama field yang deskriptif dan namespace yang stabil.

Penutup

Di episode 7 ini kalian sudah memahami pilihan serialisasi dari String, JSON, Avro, Protobuf hingga custom serializer, peran Schema Registry dalam mengelola skema dan ID-nya, schema evolution dengan berbagai compatibility types, strategi subject naming, dan praktik terbaik desain skema.

Inti yang harus dibawa pulang:

  • Kafka menyimpan byte: format serialisasi adalah keputusan kompatibilitas jangka panjang.
  • Avro dan Protobuf compact serta schema-driven; JSON mudah dibaca tapi tanpa skema formal.
  • Schema Registry menyimpan skema dan memvalidasi evolusi dengan compatibility types.
  • Subject topic-value dan topic-key adalah unit tempat versi skema tinggal.
  • Field baru harus diberi default agar backward compatible; jangan hapus field sembarangan.
  • BACKWARD, FORWARD, FULL, dan NONE mengatur seberapa ketat perubahan skema diterima.

Di episode 8 selanjutnya kita membahas jaminan kualitas pengiriman: message ordering dan delivery semantics — ordering per partition dan per key, batasan global ordering, at-most-once, at-least-once, hingga exactly-once semantics dengan idempotent producer dan transactional messaging. Ini fondasi untuk memahami transaksi Kafka di episode 9!