Kenapa Distributed System Sulit? — System Design

Sebelum kita membahas arsitektur canggih seperti load balancer, CDN, atau microservices, kita harus paham satu hal: kenapa menambah server bisa membuat sistem j

Sebelum kita membahas arsitektur canggih seperti load balancer, CDN, atau microservices, kita harus paham satu hal: kenapa menambah server bisa membuat sistem jauh lebih rumit?

Dari 1 Server: Sederhana dan Predictable

Bayangkan aplikasi dengan satu server:

[User] ──► [Server + Database]

Sederhana. Bisa dipercaya. Tapi tidak tahan beban — kalau 10.000 user datang sekaligus, server akan meledak. Dan kalau server itu mati, aplikasi mati juga.

Jadi Kita Tambah Server: Masalah Mulai Muncul

Solusi klasik: tambah server kedua (atau ke-5, ke-10).

         ┌──► [Server A]
[User] ──┤
         └──► [Server B]

Sekilas terlihat seperti "cuma tambah box". Tapi sekarang muncul 6 pertanyaan sulit yang tidak ada di 1-server setup:

1. Partial Failure — Bagaimana kalau HANYA satu server mati?

Di 1-server: sistem mati atau hidup, simple. Di multi-server: Server A mati tapi B masih jalan. User dapat response tidak konsisten — kadang sukses (via B), kadang error (via A). Bagaimana mendeteksi dan mengarahkan traffic menjauhi A yang mati?

2. Data Divergence — Datanya ada di mana?

Kalau user update profil di Server A, apakah Server B langsung tahu? Kalau tidak, user yang hit B selanjutnya akan lihat data lama. Ini masalah consistency.

Pilihan:

3. Network is Unreliable — Request bisa hilang di jalan

Server A kirim "update ke user 42" ke Server B. Kalau paket hilang? Kalau sampai tapi B mati sebelum ack? Kalau ack hilang di jalan pulang? A tidak tahu apakah operasi sukses atau gagal.

Aturan pahit distributed system: network selalu bisa fail, dan kamu tidak bisa bedakan antara "pesan hilang" vs "pesan sampai tapi ack hilang".

4. Coordination — Siapa yang jadi bos?

Untuk operasi yang butuh keputusan tunggal (misal "assign nomor invoice berikut"), siapa yang memutuskan kalau ada 5 server? Kalau dua server sama-sama mengira dirinya bos (karena disconnect sebentar), bisa terjadi split brain — dua keputusan yang bertentangan.

5. Time — Jam tiap server berbeda

Di 1 server, timestamp selalu terurut. Di multi-server, jam tiap server bisa berbeda (clock drift). Event yang terjadi pukul 10:00:01 di A mungkin tampak "sebelum" event pukul 10:00:00 di B.

6. Debugging — Bug bisa dari mana saja

Di 1 server: error? Buka log. Di multi-server: request lewat 5 service → ada yang lambat → mana yang salah? Butuh distributed tracing, ID request yang menyambung antar service, dan budaya observability yang jauh lebih disiplin.

Time & Ordering — Kenapa Jam Komputer Berbohong

Masalah #5 di atas (jam beda) ternyata lebih dalam dari sekedar "geser beberapa detik". Mari lebih rinci:

NTP dan Batasnya

NTP (Network Time Protocol) mencoba sinkronisasi jam antar server via request ke time server. Tapi NTP hanya akurat sampai beberapa milidetik — dan jam masih bisa drift (bergeser) beberapa mikrodetik per detik karena ketidaksempurnaan kristal.

Di aplikasi biasa ini cukup. Tapi di sistem terdistribusi:

Server A: event terjadi pukul 10:00:00.123
Server B: event terjadi pukul 10:00:00.089

Siapa duluan? Mustahil tahu dari timestamp saja. Jam B bisa saja ketinggalan 50ms dari jam A.

Kenapa Physical Clock Berbohong

Mengandalkan System.currentTimeMillis() untuk ordering antar server = bug yang menunggu.

Logical Clock — Lamport Timestamp

Alih-alih jam fisik, gunakan counter logis yang monoton naik per event (Leslie Lamport, 1978):

Setiap node punya counter lokal.
Saat event terjadi lokal: counter++
Saat kirim pesan: sertakan counter.
Saat terima pesan: counter = max(localCounter, receivedCounter) + 1

Hasilnya: kalau event X terjadi sebelum Y (causally), timestamp X < timestamp Y. Tapi bukan sebaliknya — timestamp lebih kecil tidak selalu berarti lebih dulu.

Vector Clock — Lebih Kaya

Vector clock memperluas Lamport: setiap node menyimpan vector counter (satu entry per node) bukan cuma satu angka.

[A=3, B=5, C=2]  ← timestamp di node A

Dengan vector clock kamu bisa mendeteksi concurrent events (yang tidak causally terkait) — sesuatu yang Lamport tidak bisa bedakan. Ini berguna untuk conflict resolution di sistem AP seperti Dynamo dan Riak.

Trade-off: vector clock tumbuh linear dengan jumlah node — tidak cocok untuk cluster sangat besar.

Hybrid Logical Clock (HLC)

Gabungan yang terbaik dari dua dunia: combine physical timestamp + logical counter.

HLC = (physicalMillis, logicalCounter)

Kalau dua event punya physical time sama, logical counter memecah tie. Kalau physical time berbeda, ordering tetap mendekati waktu nyata. CockroachDB, YugabyteDB, MongoDB pakai HLC untuk global ordering transaksi distributed — kombinasi akurat dan kompatibel dengan wall clock.

Yang Penting

Pelajaran Utama

Menambah server tidak menyelesaikan masalah skala begitu saja — ia memindahkan masalah dari "terlalu banyak beban di satu tempat" ke "terlalu banyak koordinasi antar tempat".

Setiap pattern dalam system design — load balancer, cache, message queue, CDN, CQRS, konsensus — adalah jawaban terhadap salah satu dari 6 masalah di atas.

Kalau kamu tidak paham masalahnya, solusinya terlihat seperti magic (atau over-engineering). Kalau kamu paham, setiap pattern jadi masuk akal — karena kamu bisa menghubungkannya ke tekanan nyata yang menciptakannya.

Yang Akan Kita Pelajari Berikutnya

Di 20 lesson setelah ini, kamu akan melihat bagaimana industri menyelesaikan (atau menerima trade-off dari) 6 masalah di atas:

Tiap lesson akan kembali ke akar: "masalah apa yang dipecahkan pattern ini?" Kalau kamu bingung, kembali ke 6 masalah di atas — itu kompasnya.

Catatan Format

Di kategori ini, tidak ada exercise coding. System design bukan tentang menulis kode — melainkan tentang trade-off arsitektur. Kamu akan belajar lewat teori, contoh kasus nyata, dan pertanyaan quiz yang menguji pemahamanmu terhadap alasan di balik setiap pilihan desain.

🎭 Analogi sehari-hari: 1 server = warung kecil kelola sendiri. Tahu pelanggan, stok, kasir, semuanya. Mau buka 5 cabang? Tiba-tiba muncul masalah baru: stok beda antar cabang, kasir 1 sibuk yang lain kosong, kalau cabang A tutup pelanggan harus tau, dst. Distributed system = kompleksitas koordinasi, bukan sekadar "tambah box".

⚠️ Mindset shift wajib pemula:

🎯 Compass 6 masalah saat lihat pattern apapun:

  1. Partial failure → load balancer + health check
  2. Data divergence → replication + consistency model
  3. Network unreliable → message queue + retry idempotent
  4. Coordination → consensus (Raft/Paxos) atau leader election
  5. Time → logical clock (Lamport/Vector/HLC)
  6. Debugging → distributed tracing + correlation ID

TL;DR: Tambah server bukan cuma scaling — bawa kompleksitas baru: partial failure, divergence, unreliable network, coordination, time, debugging. Setiap pattern arsitektur = jawaban salah satu dari 6 masalah ini. Paham masalah dulu, baru solusinya jadi masuk akal.