Load Balancing — System Design

Load Balancer mendistribusikan traffic masuk ke beberapa server agar tidak ada satu server yang kelebihan beban. Tanpa load balancer: 10.000 requests → Server…

Load balancer adalah pintu masuk yang membagi request ke beberapa server supaya gak ada satu server yang kewalahan, sekaligus menjauhkan request dari server yang sakit. Bayangin petugas antrean di stasiun yang punya tiga loket tiket. Dia mengarahkan tiap orang ke loket, memperhatikan loket mana yang antreannya panjang, dan berhenti mengirim orang ke loket yang petugasnya menghilang.

🧪 Tebakan cepat: app-2 tiba-tiba lambat empat kali lipat, tapi round robin tetap memberinya sepertiga request. Request paling lama jadi berapa: tetap 400 ms, sekitar 1.000 ms, atau 2.450 ms? Tebak dulu, jawabannya ada di bagian "Server lambat: least connections".

TiketNada di belakang load balancer

Satu server aplikasi gak cukup untuk war tiket, jadi TiketNada menjalankan tiga: app-1, app-2, app-3. Pengguna cuma tahu satu alamat, tiketnada.test, yang menunjuk ke load balancer lb. lb yang memilih server untuk tiap request.

Model contoh di lesson ini: 24 request datang satu tiap 50 ms dari 8 pengguna (budi, siti, dewi, maya, rina, tono, joko, bayu). Tiap request keempat adalah checkout (400 ms kerja), sisanya "lihat konser" (100 ms). Tiap server mengerjakan 2 request sekaligus; sisanya antre.

Round robin

Round robin membagi bergiliran: request 1 ke app-1, 2 ke app-2, 3 ke app-3, 4 ke app-1 lagi, dan seterusnya. Gak perlu tahu apa-apa tentang server, jadi sederhana dan cepat. Kalau ketiga server sama sehatnya, hasilnya rapi: tiap server dapat 8 request, dan request paling lama 400 ms, yaitu sebuah checkout.

Server lambat: least connections

Sekarang disk app-2 bermasalah, dan semua kerjanya jadi 4 kali lebih lama. Round robin gak peduli. app-2 tetap dapat 8 request, antreannya menumpuk, dan checkout maya yang masuk di ms 950 baru selesai di ms 3.400.

Least connections memilih server yang koneksi aktifnya paling sedikit saat itu, yaitu request yang sudah dikirim tapi belum dijawab. Server lambat menahan koneksinya lebih lama, jadi dia otomatis dapat lebih sedikit.

app-2 lambat ×4 Request ke app-1 / app-2 / app-3 Rata-rata Paling lama
Round robin 8 / 8 / 8 473 ms 2.450 ms
Least connections 8 / 5 / 11 238 ms 400 ms

Jadi jawaban tebakannya 2.450 ms. Least connections cocok kalau lama request bervariasi atau ada server yang melambat, misalnya checkout, upload, atau WebSocket.

Health check: buang server yang sakit

Lebih parah dari lambat: proses di app-3 macet. Dia masih menerima koneksi tapi gak pernah menjawab. lb menunggu sampai batas timeout server 1s, lalu menjawab pengguna 504 Gateway Timeout. Round robin tanpa pengecekan terus mengirim sepertiga request ke app-3: 8 dari 24 request gagal.

Health check adalah lb yang rajin bertanya ke tiap server, misalnya GET /health tiap 200 ms. Ini config HAProxy-nya:

backend tiketnada_app
    balance roundrobin
    option httpchk GET /health
    timeout server 1s
    server app-1 10.0.1.11:8000 check inter 200ms fall 2 rise 2
    server app-2 10.0.1.12:8000 check inter 200ms fall 2 rise 2
    server app-3 10.0.1.13:8000 check inter 200ms fall 2 rise 2

Di model ini app-3 ditandai DOWN di ms 400, jadi cuma 2 request yang sempat kena 504, bukan 8.

Hash: pengguna yang sama ke server yang sama

Kadang kamu mau pengguna yang sama selalu ke server yang sama, misalnya kalau session masih disimpan di memori server. Itu disebut sticky session. Cara paling sederhana: IP hash, yaitu hash(IP client) % jumlah server. Hash adalah fungsi yang mengubah teks jadi angka besar yang selalu sama untuk teks yang sama. Di Lab, kuncinya ID pengguna, karena banyak pengguna HP berganti IP dan satu kantor bisa berbagi satu IP.

Pengguna hash % 3 (3 server) % 2 (app-3 dilepas)
budi 2.387.817.240 0 → app-1 0 → app-1
siti 2.885.968.911 0 → app-1 1 → app-2, pindah
dewi 3.025.318.762 1 → app-2 0 → app-1, pindah
tono 2.267.695.823 2 → app-3 1 → app-2, pindah

Masalahnya, begitu jumlah server berubah, modulo-nya berubah dan hampir semua pengguna pindah: dari 8 pengguna di Lab, 6 pindah server waktu app-3 dilepas, dan session mereka hilang. Consistent hashing menaruh server dan pengguna di satu lingkaran angka (tiap server punya 100 titik); tiap pengguna jatuh ke titik server berikutnya searah jarum jam. Kalau app-3 dilepas, cuma pengguna yang tadinya di app-3 yang pindah: 2 dari 8. Di HAProxy: balance hdr(X-User-Id) ditambah hash-type consistent.

Sticky session menambal server stateful, bukan menyembuhkannya: kalau server itu mati, session-nya tetap hilang. Lebih baik server stateless dengan session di Redis.

Layer 4 dan Layer 7

🎯 Memilih algoritma

Situasi Algoritma
Server sama kuat, request seragam round robin
app-1 8 CPU, app-2 4 CPU weighted round robin (weight per server)
Lama request bervariasi, WebSocket, server bisa melambat least connections
Pengguna harus tetap di server yang sama hash (IP atau ID pengguna), consistent

⚠️ Jebakan yang sering ketemu

TL;DR: Load balancer membagi request ke beberapa server dan menjauhkannya dari server yang sakit. Round robin bergiliran, cocok untuk server dan request yang seragam. Least connections memilih server dengan koneksi aktif paling sedikit, jadi server lambat dapat lebih sedikit: di model TiketNada request terlama turun dari 2.450 ms ke 400 ms. Health check (GET /health tiap 200 ms, fall 2) mengeluarkan server yang macet dari pool, jadi 504 turun dari 8 ke 2. IP hash mengirim client yang sama ke server yang sama (sticky session); consistent hashing membuat cuma pengguna server yang hilang yang pindah. Layer 4 melihat IP dan port, Layer 7 membaca URL, header, dan cookie. Load balancer-nya sendiri harus redundant.

Yang akan kamu pelajari