Modul 10Term 3 · Reliabilitas dan skala12 item poster

Kebenaran Sistem Terdistribusi

Masuk untuk menyimpan progres Anda di semua perangkat. Sampai saat itu, progres disimpan di browser ini.

Mengapa ini penting

Bug konkurensi tidak muncul saat demo. Bug ini muncul sebagai pelanggan yang membayar dua kali, voucher yang ditukar tiga kali, kursi yang terjual ke dua orang, atau saldo yang tidak cocok di akhir bulan. Di fintech, ini adalah peristiwa regulasi, bukan sekadar bug.

Capaian pembelajaran

  1. Mengenali race condition dan memperbaikinya dengan operasi atomik, constraint, dan lock.
  2. Memahami replikasi, CAP, dan eventual consistency cukup dalam untuk merancang UX di sekitarnya.
  3. Mengetahui kapan distributed lock dan leader election dibutuhkan, beserta jebakannya.
  4. Menghindari deadlock.
  5. Menangani waktu dengan benar meski ada clock skew.
  6. Mendiagnosis memory leak dan jeda garbage collection.

Materi

10.1 Race condition (39, 43)

Bentuk klasiknya adalah check-then-act: baca sebuah nilai, putuskan, tulis. Di antara baca dan tulis, orang lain sudah bertindak. Perbaikan, berurutan dari yang paling disarankan:

  1. Pernyataan atomik: UPDATE accounts SET balance = balance - 100 WHERE id = $1 AND balance >= 100 lalu cek jumlah baris yang terpengaruh.
  2. Constraint database: unique index membuat insert kedua gagal.
  3. Optimistic locking (kolom versi) untuk kontensi rendah.
  4. Pessimistic lock (SELECT ... FOR UPDATE) untuk kontensi tinggi. Di kode aplikasi: state mutable bersama di proses Node yang berumur panjang dipakai bersama oleh semua request; variabel tingkat modul tidak bersifat per pengguna. Thread safety (43) juga penting di Go, Java, Python async, dan worker.

10.2 Deadlock (40)

Dua transaksi masing-masing memegang lock yang dibutuhkan yang lain. Cegah dengan selalu mengunci resource dalam urutan yang konsisten (misalnya berdasarkan ID menaik), menjaga transaksi tetap singkat, dan memasang lock timeout. Postgres mendeteksi deadlock dan membatalkan salah satunya; kode Anda harus melakukan retry.

10.3 Replikasi, CAP, dan eventual consistency (32, 34, 35, 95)

  • Replikasi (32): salinan di banyak node untuk durabilitas dan skala baca. Replika async mengalami lag.
  • Network partition (95) pasti terjadi. Saat itu terjadi, CAP menyatakan sistem harus memilih: menolak sebagian request (consistency) atau menjawab dengan data yang mungkin basi (availability).
  • Eventual consistency (35): replika akan konvergen seiring waktu. Implikasi desain: read-your-own-writes (arahkan pembacaan pengguna ke primary sesaat setelah mereka menulis), tampilkan status "sedang diproses", jangan pernah memutuskan urusan uang dari replika yang tertinggal.
  • Ledger dan saldo: strongly consistent, satu sumber kebenaran, catatan double-entry yang append-only.

10.4 Distributed lock dan leader election (33, 38)

  • Dibutuhkan ketika beberapa instance tidak boleh melakukan hal yang sama secara bersamaan (satu pelari cron, satu consumer per partisi).
  • Utamakan opsi bawaan DB lebih dulu: Postgres advisory lock, job queue dengan SKIP LOCKED.
  • Lock Redis membutuhkan masa berlaku (TTL) dan fencing token: proses yang sempat terhenti bisa bangun setelah lock-nya kedaluwarsa dan tetap menulis. Lapisan storage harus menolak token yang basi.
  • Leader election (Raft, etcd, ZooKeeper, Kubernetes lease) umumnya Anda pakai dari infrastruktur, bukan Anda bangun sendiri.

10.5 Waktu dan clock skew (96)

  • Jam mesin bisa bergeser; jangan pernah memakai wall-clock time dari server yang berbeda untuk mengurutkan event.
  • Gunakan timestamp yang dibuat DB atau nomor urut untuk pengurutan; gunakan monotonic clock untuk mengukur durasi.
  • Pengecekan masa berlaku token dan timestamp webhook membutuhkan toleransi skew kecil.

10.6 Memory leak dan garbage collection (41, 42)

  • Leak di bahasa managed biasanya berupa referensi yang Anda simpan: cache yang terus tumbuh tanpa batas, event listener yang tidak pernah dilepas, array global, stream yang tidak ditutup.
  • Gejala: memori naik terus, lalu restart karena OOM; lonjakan latensi akibat jeda GC yang panjang.
  • Tool: heap snapshot (Chrome DevTools untuk Node), --inspect, metrik memori per instance, cache LRU yang berbatas.

Lab 10: Tantangan double-spend

  1. Bangun dompet digital: top-up, transfer, tarik dana. Tulis test yang menembakkan 200 transfer konkuren. Saksikan versi AI yang naif kehilangan atau menciptakan uang.
  2. Perbaiki dengan update atomik dan constraint; implementasikan sebagai ledger double-entry di mana jumlah semua entri selalu nol.
  3. Picu deadlock dengan dua transfer berurutan terbalik; perbaiki dengan pengurutan lock.
  4. Baca dari replika yang tertinggal (delay simulasi) dan tunjukkan bug read-your-writes; perbaiki.
  5. Temukan memory leak yang sengaja ditanam dengan heap snapshot.

Definition of Done

Paket prompt AI

  • "Temukan setiap urutan check-then-act di codebase ini. Untuk masing-masing, tunjukkan race-nya dan perbaikan atomiknya."
  • "Tulis ulang logika saldo ini sebagai ledger double-entry dengan test invarian."