Dokumen arsitektur merangkum keputusan struktural proyek kejadian sebelum implementasi dimulai, sehingga seluruh layanan mengikuti keputusan yang sama. Topik ini menyusun dokumen arsitektur untuk proyek sensor suhu yang lingkupnya sudah ditetapkan, mulai dari peta topic, skema payload, kontrak pengiriman, sampai keputusan yang dicatat beserta alasannya. Dokumen yang sama menjadi pegangan saat layanan diimplementasikan dan saat arsitektur ditinjau ulang di kemudian hari. Setelah membaca topik ini, keempat bagian dokumen dapat ditulis dengan angka dan alasan yang menyertainya.
Isi dokumen arsitektur#
Dokumen arsitektur kejadian memuat empat bagian yang saling menopang. Setiap bagian menyatakan keputusannya, sedangkan alasan yang menyertainya membuat keputusan dapat ditinjau ulang dengan memahami konteksnya. Empat bagian tersebut dirangkum di bawah.
- Peta topic, yaitu daftar topic proyek beserta jumlah partisi, retensi, key, dan tujuan masing-masing.
- Skema payload, yaitu bentuk kejadian yang disepakati producer dan consumer pada setiap topic.
- Kontrak pengiriman, yaitu semantik pengiriman per alur beserta cara mengatasi kejadian yang terkirim dua kali.
- Keputusan yang dicatat, yaitu catatan singkat yang memuat alasan dan alternatif yang ditinggalkan pada setiap keputusan besar.
Keempat bagian itu ditulis sebelum kode pertama karena keputusan yang hanya disampaikan secara lisan mudah berubah tanpa jejak. Dokumen memberi semua pihak teks yang sama untuk dibaca, sehingga perbedaan pemahaman muncul lebih awal dan tidak menunggu kegagalan saat integrasi. Dokumen juga menjadi acuan saat audit, karena pemeriksa dapat membandingkan sistem yang berjalan dengan keputusan yang tertulis. Perubahan arsitektur kemudian dikerjakan dengan merevisi dokumen lebih dahulu, lalu kode menyesuaikan diri setelahnya.
Peta topic#
Peta topic menyatakan setiap topic yang digunakan proyek beserta parameter utamanya, yaitu jumlah partisi, retensi, key, dan tujuannya. Tabel berikut memuat peta topic proyek sensor suhu, dan jumlah topic dijaga tetap dua sesuai lingkup minimum yang ditetapkan sebelumnya. Parameter pada tabel menjadi batas yang menyertai setiap topic selama proyek berjalan.
| Topic | Partisi | Retensi | Key | Tujuan |
|---|---|---|---|---|
m8-suhu-kejadian | 3 | 7 hari | id_perangkat | Kejadian pembacaan suhu mentah dari seluruh perangkat |
m8-suhu-rangkuman | 1 | 30 hari | id_perangkat | Rangkuman per jam hasil layanan perekap yang dibaca antrean tampilan |
Key dipilih berupa id_perangkat karena pembacaan satu perangkat paling bermakna bila dibaca berurutan, misalnya ketika rangkuman dihitung per perangkat. Kardinalitas key cukup tinggi karena jumlah perangkat yang terpasang adalah 20 buah, sehingga sebarannya ke semua partisi relatif merata. Topic rangkuman menggunakan satu partisi karena beban yang melewatinya hanya ratusan rangkuman per hari dan pembacanya berjumlah satu. Jumlah partisi dan retensi pada kedua topic berasal dari keputusan yang dicatat pada bagian akhir.
Diagram berikut memperlihatkan peta topic beserta layanan di sekitarnya. Layanan perekam menulis ke topic kejadian, layanan perekap membaca topic kejadian dan menulis rangkuman, sedangkan antrean tampilan membaca topic rangkuman. Kotak topic menampilkan jumlah partisinya beserta batas retensinya, sehingga gambar dan tabel menyatakan keputusan yang sama.
Peta yang sama menyebut dua consumer group, yaitu grup perekap dan grup tampilan, sehingga kedua pembaca menerima seluruh aliran topic masing-masing. Topic tambahan hanya masuk ke peta setelah kebutuhannya dinyatakan pada dokumen ini, dan setiap tambahan ikut menyebut partisi, retensi, serta keynya. Peta topic dengan demikian menjadi sumber kebenaran tunggal untuk seluruh topic milik proyek.
Skema payload#
Skema payload menetapkan bentuk kejadian yang mengalir pada setiap topic. Kejadian pada kedua topic menggunakan bentuk envelope, yaitu bungkus metadata standar yang memisahkan identitas kejadian dari isinya, sebagaimana ditetapkan pada topik Desain pesan. Contoh berikut menunjukkan satu kejadian pembacaan suhu yang sesuai dengan peta topic di atas.
{
"event_id": "a3f8e1d2-7b4c-4e2a-9c1d-5e6f7a8b9c0d",
"event_type": "sensor.suhu.terbaca",
"occurred_at": "2026-11-07T08:30:00Z",
"data": {
"id_perangkat": "sensor-07",
"lantai": 3,
"suhu_c": 24.5
}
}Field event_id menjadi dasar pengenalan kejadian yang terkirim dua kali, sehingga nilainya ditetapkan di sumber dan tetap sama pada setiap pengiriman ulang. Field event_type mengikuti pola objek.aksi, dan nilai sensor.suhu.terbaca menyatakan kejadian pembacaan suhu. Field occurred_at menyimpan waktu kejadian pada sumber dalam format ISO 8601 dengan zona UTC, sedangkan field data memuat isi teknis proyek berupa id_perangkat, lantai, dan suhu_c dalam derajat Celsius. Field id_perangkat sekaligus menjadi key topic, sehingga pola penamaannya berupa sensor- diikuti dua angka, dan pola itu ditegakkan pada skema.
Skema hanya berguna bila pemeriksaannya dilakukan oleh mesin dan tidak bergantung pada kehati-hatian penulisnya. Skrip berikut memeriksa contoh kejadian terhadap struktur envelope dan skema proyek, meliputi pola id_perangkat, rentang suhu_c, dan rentang lantai. Skrip dijalankan dari folder topik dengan perintah python3 -B validasi-kejadian.py.
# validasi kejadian sensor suhu terhadap envelope dan skema proyek
import json
import re
from datetime import datetime
def cek_envelope(pesan):
"""Kembalikan daftar field envelope yang melanggar aturannya."""
error = []
if not re.fullmatch(r"[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}", str(pesan.get("event_id", ""))):
error.append("event_id")
if not re.fullmatch(r"[a-z0-9]+(\.[a-z0-9]+)+", str(pesan.get("event_type", ""))):
error.append("event_type")
try:
datetime.fromisoformat(str(pesan.get("occurred_at", "")).replace("Z", "+00:00"))
except ValueError:
error.append("occurred_at")
return error
def cek_skema(data):
"""Kembalikan daftar field proyek yang melanggar skema kejadian suhu."""
error = []
if not re.fullmatch(r"sensor-[0-9]{2}", str(data.get("id_perangkat", ""))):
error.append("id_perangkat")
suhu = data.get("suhu_c")
if not isinstance(suhu, (int, float)) or not (-40 <= suhu <= 60):
error.append("suhu_c")
lantai = data.get("lantai")
if not isinstance(lantai, int) or not (1 <= lantai <= 10):
error.append("lantai")
return error
with open("kejadian-suhu.json", encoding="utf-8") as f:
kejadian = json.load(f)
error = cek_envelope(kejadian) + cek_skema(kejadian["data"])
if error:
print("kejadian TIDAK valid:", ", ".join(error))
else:
print("envelope : valid")
print("skema : valid")envelope : valid
skema : validContoh kejadian lolos kedua pemeriksaan karena strukturnya mengikuti envelope dan nilainya berada dalam rentang skema. Pemeriksaan semacam ini dipasang pada layanan perekam sebelum pengiriman, sehingga kejadian yang bentuknya menyimpang ditahan di sumber dan tidak pernah mencemari topic. Bagian kontrak pengiriman berikutnya menetapkan apa yang terjadi setelah kejadian yang valid dikirim.
Kontrak pengiriman#
Kontrak pengiriman menyatakan semantik pengiriman yang dipilih untuk setiap alur beserta cara mengatasi kejadian yang terkirim dua kali. Proyek sensor suhu memilih semantik at-least-once untuk seluruh alur, yaitu kejadian tidak boleh hilang dan boleh tiba lebih dari sekali. Pilihan ini dipadukan dengan dedupe, yaitu penyaringan kejadian yang sudah pernah diproses, sehingga hasil akhirnya setara tepat sekali tanpa menuntut transaksi Kafka.
| Alur | Semantik | Penanganan kejadian ganda |
|---|---|---|
Perekam menulis ke m8-suhu-kejadian | at-least-once dengan producer idempoten | Broker menolak ulangan nomor urut yang sama |
| Perekap menghitung rangkuman | commit offset setelah rangkuman tersimpan | Kejadian yang sudah diproses dikenali lewat event_id |
Perekap menulis ke m8-suhu-rangkuman | at-least-once | Nilai rangkuman per perangkat dan jam ditulis ulang dengan nilai yang sama |
| Antrean tampilan membaca rangkuman | at-least-once | Tampilan menyajikan nilai terakhir per perangkat dan jam |
Producer idempoten pada alur pertama menahan duplikat di dalam log, tetapi jaminan itu berhenti di log Kafka. Consumer yang commit offset setelah pemrosesan masih dapat memproses kejadian yang sama ketika pemrosesannya berhasil tetapi commitnya gagal, dan keadaan itu diatasi dengan memeriksa event_id sebelum menghitung. Rangkuman yang ditulis dua kali tidak berbahaya karena nilainya ditentukan oleh perangkat dan jam kejadian, sehingga penulisan ulang menghasilkan nilai yang sama. Prinsip yang sama berlaku pada antrean tampilan, yang menyajikan nilai terakhir per perangkat dan jam.
Kontrak ini memengaruhi konfigurasi klien pada saat implementasi, misalnya acks=all dan pengiriman ulang yang aktif pada producer, serta commit offset yang dilakukan setelah penyimpanan selesai pada consumer. Angka ambang lag pada kontrak keberhasilan dipantau pada kedua group agar deviasi terlihat sebelum rangkuman tertinggal jauh. Apabila kebutuhan pemrosesan atomik muncul di kemudian hari, kontrak diperbarui dengan semantik transaksi dan alasannya dicatat pada dokumen.
Keputusan yang dicatat#
Keputusan besar pada dokumen arsitektur dicatat dengan format ADR, yaitu architecture decision record berupa catatan singkat yang menyimpan satu keputusan, alasannya, dan alternatif yang ditinggalkan. Format singkat itu cukup berupa beberapa kalimat per keputusan, sepanjang alasannya dan alternatifnya jelas. Catatan yang lebih pendek daripada itu biasanya tidak memuat alternatif yang ditolak, sehingga pembaca berikutnya mengulangi perdebatan yang sudah selesai. Dua keputusan pertama proyek sensor suhu dicatat di bawah, dan keputusan berikutnya ditambahkan dengan bentuk yang sama.
Tiga partisi pada topic kejadian#
Topic m8-suhu-kejadian ditetapkan berjumlah tiga partisi. Throughput yang dihitung pada topik pemilihan proyek hanya sekitar 0.33 kejadian per detik, sehingga satu partisi sebenarnya sudah menampung seluruh beban hari ini. Tiga partisi dipilih karena consumer group perekap dapat tumbuh sampai tiga anggota tanpa mengubah topic, dan karena jumlah partisi tidak dapat dikurangi setelah topic dibuat. Penambahan partisi pada topic berkunci mengubah pemetaan key, sehingga ruang tumbuh ditetapkan sejak awal, sedangkan biaya tiga partisi pada volume ini hanya berupa tiga berkas log aktif per topic. Alternatif satu partisi ditolak karena mengunci paralelisme pembacaan, sedangkan alternatif jumlah partisi yang lebih besar ditolak karena tidak ada beban yang menuntutnya.
Retensi tujuh hari pada topic kejadian#
Topic m8-suhu-kejadian ditetapkan menyimpan kejadian selama tujuh hari. Angka itu mengikuti kontrak replay yang menjanjikan penghitungan ulang satu minggu ke belakang, dan volume yang dihasilkannya hanya 50.4 MB sehingga biayanya dapat diabaikan. Topic m8-suhu-rangkuman menyimpan tiga puluh hari karena menyajikan data lama bagi antrean tampilan, sehingga pembaca yang membutuhkan sejarah panjang tidak bergantung pada topic mentah. Alternatif retensi lebih panjang pada topic kejadian ditolak karena rangkuman sudah menanggung kebutuhan sejarah, sedangkan retensi lebih pendek melanggar kontrak replay. Batas ini diubah secara dinamis melalui retention.ms apabila kontraknya direvisi, dan perubahan itu dicatat sebagai revisi dokumen.
Ringkasan#
- Dokumen arsitektur kejadian memuat peta topic, skema payload, kontrak pengiriman, dan keputusan yang dicatat beserta alasannya.
- Peta topic proyek sensor suhu berisi
m8-suhu-kejadiandengan tiga partisi dan retensi tujuh hari sertam8-suhu-rangkumandengan satu partisi dan retensi tiga puluh hari. - Kejadian menggunakan envelope standar dengan
event_idyang stabil, dan skemanya diperiksa mesin sebelum pengiriman. - Kontrak pengiriman memilih at-least-once untuk seluruh alur yang dipadukan dedupe, sedangkan keputusan partisi dan retensi dicatat dengan alasan dan alternatifnya.
Referensi#
- Apache Kafka documentation — Apache Software Foundation — dokumentasi versi 4.4 yang menjadi rujukan konfigurasi topic dan perilaku klien pada dokumen arsitektur.
- Design: message delivery semantics — Apache Software Foundation — definisi resmi semantik pengiriman yang menjadi dasar kontrak pengiriman proyek.
- Topic configs — Apache Software Foundation
— konfigurasi
retention.msdan pengaturan topic lain yang dicatat pada peta topic.