Jawaban singkat untuk pertanyaan yang paling sering diajukan pembaca tentang topik ini.
01Algoritma load balancing mana yang terbaik?
Tidak ada satu algoritma yang selalu menang; semuanya bergantung pada apa yang bervariasi di traffic Anda. Round robin cocok untuk server identik dengan request pendek dan seragam, least connections cocok untuk durasi request campuran atau koneksi berumur panjang, dan hashing cocok bila klien harus kembali ke server yang sama. Mulai dari round robin atau least_conn dan ganti hanya bila pilihan sederhana itu terbukti bermasalah.
02Apa perbedaan round robin dan least connections?
Round robin bergiliran melewati server dan menghitung request, sehingga tidak peduli berapa lama setiap request berjalan. Least connections mengirim request berikutnya ke server dengan koneksi aktif paling sedikit, yang lebih dekat dengan beban nyata saat durasi request berbeda. Di nginx, yang kedua diaktifkan dengan direktif least_conn di dalam blok upstream.
03Apakah ip_hash memberi sticky session?
Sebagian besar ya. Dokumentasi nginx menyebut ip_hash mengirim request dari klien yang sama ke server yang sama kecuali server itu tidak tersedia, dengan tiga oktet pertama alamat IPv4 sebagai kunci. Artinya satu blok /24 penuh berbagi satu server dan klien di belakang proxy atau NAT terlihat sama. Menyimpan sesi di Redis menghilangkan kebutuhan akan stickiness.
04Apa perbedaan load balancing layer 4 dan layer 7?
Balancing layer 7 terjadi setelah balancer mem-parse request HTTP, sehingga bisa memakai URL, header dan cookie serta terminate TLS. Balancing layer 4 bekerja pada koneksi TCP dan tidak bisa melihat isi request. Di nginx yang pertama adalah blok http dan yang kedua blok stream, yang menyediakan hash, least_conn, least_time dan random.
05Apa yang terjadi pada load balancing saat server backend mati?
Itu bergantung pada health check. Nginx open source memakai passive check: setelah max_fails respons gagal (default 1) ia menghindari server selama fail_timeout (default 10 detik), lalu mengujinya dengan request nyata. Sebelum kegagalan terdeteksi, round robin dan ip_hash tetap mengirim traffic ke server yang mati, sedangkan least connections cenderung menjauh dari server yang lambat.
Algoritma Load Balancing: Round Robin, Least Conn, IP Hash
Round robin, least connections atau IP hash? Kapan tiap algoritma load balancing cocok, lengkap dengan snippet upstream nginx, layer 4 vs 7 dan health check.
Pakai round robin untuk server yang identik dengan request pendek dan seragam, least connections saat durasi request bervariasi, dan hash dari kunci klien (ip_hash atau hash dengan consistent) hanya jika satu klien harus selalu ke server yang sama. Tambahkan weight untuk mesin yang tidak setara, dan pasangkan setiap algoritma dengan health check agar server yang gagal tidak menerima traffic.
Menambah replika kedua dari container API di belakang nginx memaksa kita memutuskan hal yang selama ini dijawab diam-diam oleh config default: server mana yang mendapat request berikutnya. Nginx menjawab dengan round robin kecuali diatur lain, dan untuk sementara jawaban itu cukup bagus sehingga tidak ada yang memeriksanya.
Post ini membahas algoritmanya sendiri dan kapan masing-masing cocok: round robin, least connections, IP hash dan consistent hashing, weight, serta power of two choices. Setiap algoritma punya snippet upstream nginx, dan perbedaan layer 4 dengan layer 7 serta health check juga dibahas. Setiap klaim perilaku merujuk ke dokumentasi nginx, blog engineering HAProxy atau Wikipedia, dan setiap angka dikutip dari sana atau dihitung langsung di halaman ini. Untuk config pendukungnya, lihat post terpisah tentang load balancer nginx di production.
Apa sebenarnya yang diputuskan algoritma load balancing?
Load balancer punya satu tugas per request atau per koneksi: memilih satu server dari pool. Algoritma hanyalah aturan untuk pilihan itu. Wikipedia mengelompokkan aturan umum menjadi round robin, weighted round robin, least connections dan assignment berbasis hash, dan mencatat bahwa dua yang pertama bisa diberi bobot agar mesin yang lebih kuat menerima lebih banyak.
Aturan-aturan itu berbeda dalam hal apa yang perlu diketahui. Round robin hanya butuh counter. Least connections butuh jumlah koneksi terbuka per server secara live. Hash butuh kunci dari request, seperti alamat klien atau cookie. Makin banyak yang diketahui sebuah aturan, makin baik ia beradaptasi, dan makin banyak state yang harus disimpan balancer.
Kapan round robin sudah cukup?
Round robin mengirim request 1 ke server 1, request 2 ke server 2, lalu kembali ke awal setelah server terakhir. Panduan load balancing nginx menyebut bahwa bila tidak ada metode yang dikonfigurasi, defaultnya adalah round robin, dan menyertakan syarat yang penting: pembagian baru merata hanya jika request diproses seragam dan selesai cukup cepat.
# Round robin is the default: no method directive at all.
upstream api_pool {
server 10.0.0.11:3000;
server 10.0.0.12:3000;
server 10.0.0.13:3000;
}
server {
listen 80;
location / {
proxy_pass http://api_pool;
}
}
Karena itu round robin adalah default yang tepat untuk replika stateless yang identik dengan biaya request serupa, misalnya API NestJS yang hampir semua endpointnya berupa query Postgres singkat dengan index. Ia tidak lagi tepat begitu biaya request sangat bervariasi, seperti ditunjukkan hitungan di bagian berikut.
Kapan sebaiknya memakai least connections?
Least connections mengirim request berikutnya ke server dengan koneksi aktif paling sedikit, dan nginx memperhitungkan weight server, dengan fallback ke weighted round robin bila beberapa server seri. Panduan nginx merekomendasikannya saat sebagian request memakan waktu lebih lama, supaya server yang sibuk tidak diberi beban berlebih.
Berikut worked example mengapa. Ambil dua server dan delapan request yang bergantian berat (900 ms) dan ringan (100 ms), dimulai dari yang berat. Pergiliran yang ketat menaruh semua request berat di server yang sama.
# 8 requests, alternating heavy (900 ms) and light (100 ms)
# Round robin over servers A and B:
# A gets requests 1,3,5,7 (all heavy): 4 x 900 = 3600 ms of work
# B gets requests 2,4,6,8 (all light): 4 x 100 = 400 ms of work
# total 4000 ms, fair share 2000 ms each, A carries 90 percent
# Conceptually, least_conn picks the server with the fewest open
# connections (weights considered, ties broken by weighted round robin).
# A, stuck on a 900 ms request, keeps its connection open, so the next
# request goes to B, which finishes its 100 ms ones quickly.
upstream api_pool {
least_conn;
server 10.0.0.11:3000;
server 10.0.0.12:3000;
}
Polanya sengaja ekstrem, tetapi mekanismenya nyata: round robin menghitung request, bukan kerja. Least connections mengukur sesuatu yang lebih dekat ke kerja, karena server yang tersangkut di request lambat menahan koneksinya tetap terbuka dan berhenti terlihat menarik. Koneksi berumur panjang seperti upload, WebSocket dan server-sent events adalah kasus paling jelas untuknya.
Jika ragu, least_conn adalah default yang lebih aman daripada round robin untuk API dengan endpoint beragam. Dengan request seragam ia berperilaku mirip round robin, dan dengan request tidak seragam ia mengoreksi dirinya sendiri. Biayanya, nginx harus melacak jumlah koneksi per server.
Apakah IP hash memberi sticky session, dan apa yang bisa rusak?
ip_hash memetakan klien ke server dengan meng-hash alamatnya. Panduan nginx menyebut bahwa request dari klien yang sama selalu ke server yang sama kecuali server itu tidak tersedia. Referensi upstream module menambahkan bahwa tiga oktet pertama alamat IPv4, atau seluruh alamat IPv6, menjadi kunci hash, dan bahwa server yang dicabut sementara sebaiknya ditandai down agar hashing saat ini tetap terjaga.
# Wrong for a pool that resizes or sits behind a proxy:
upstream api_pool {
ip_hash; # key = first three octets of the IPv4 address
server 10.0.0.11:3000;
server 10.0.0.12:3000;
server 10.0.0.13:3000 down; # "down" keeps the hashing of the others intact
}
# Modulo hashing, 12 keys, pool grows from 3 to 4 servers:
# key mod 3 == key mod 4 only for keys 0, 1, 2 -> 3 keep their server
# 9 of 12 keys (75 percent) move
# Right: hash a session identifier, with ketama consistent hashing.
# Requests with no cookie yet all hash the same empty key.
upstream api_sticky {
hash $cookie_sid consistent;
server 10.0.0.11:3000;
server 10.0.0.12:3000;
server 10.0.0.13:3000;
}
Dua konsekuensi muncul dari detail itu. Pertama, hashing tiga oktet berarti satu blok /24 penuh, 256 alamat, dipetakan ke satu server, sehingga satu jaringan kantor atau operator seluler bisa menumpuk di satu replika. Kedua, hashing modulo biasa memindahkan sebagian besar klien saat ukuran pool berubah. Dengan kunci 0 sampai 11 dan pool tumbuh dari 3 ke 4 server, hanya kunci 0, 1 dan 2 yang tetap di server yang sama di bawah key mod N, jadi 9 dari 12 kunci, 75 persen, pindah. Parameter consistent pada hash memakai ketama hashing, yang menurut dokumentasi hanya memindahkan sedikit kunci saat server ditambah atau dicabut.
Meng-hash alamat mentah juga kunci yang salah bila ada sesuatu di depan nginx. Di belakang CDN atau proxy lain, setiap request datang dari alamat proxy, sehingga semua orang ter-hash ke server yang sama. Hash hal yang mengidentifikasi sesi, seperti di bawah. Lebih baik lagi, simpan state sesi di Redis sehingga tidak ada request yang butuh server tertentu; Wikipedia mencatat bahwa persistence kehilangan sesi bila servernya gagal, dan database bersama menghindari hal itu.
ip_hash tidak membuat pool tahan gangguan. Klien yang terpaku tetap terpaku sampai nginx menandai servernya tidak tersedia, dan saat rolling deploy setiap restart menghilangkan sesi di server itu kecuali sesinya ada di Redis atau penyimpanan bersama lain.
Bagaimana weight dan power of two choices berperan?
Weight menangani mesin yang tidak setara dan bisa digabung dengan metode di atas. Contoh di panduan nginx memakai weight=3 pada satu server dengan dua lainnya di default 1, sehingga dari setiap 5 request baru, 3 ke server pertama dan 1 ke masing-masing lainnya. Untuk node 4 vCPU di samping node 2 vCPU, weight=2 berbanding weight=1 memberi pembagian dua pertiga dan sepertiga. Anggap weight sebagai tebakan awal, bukan hasil pengukuran.
# 3 of every 5 new requests go to the first server (3 + 1 + 1 = 5)
upstream api_weighted {
server 10.0.0.11:3000 weight=3;
server 10.0.0.12:3000;
server 10.0.0.13:3000;
}
# Power of two choices: pick two at random, keep the one with fewer
# active connections (least_conn is the default tie-break method).
upstream api_p2c {
random two;
server 10.0.0.11:3000;
server 10.0.0.12:3000;
server 10.0.0.13:3000;
}
Power of two choices adalah jalan tengah antara random dan least connections. Nginx menyediakannya sebagai random two: ia memilih dua server secara acak lalu memilih yang koneksi aktifnya lebih sedikit secara default. Blog engineering HAProxy menjelaskan intinya: balancer tidak perlu memeriksa setiap server, yang paling berguna saat beberapa balancer memutuskan secara independen, karena least connections di masing-masing bisa sama-sama memilih server yang sepi. Pada tes HAProxy sendiri dengan contention sedang, puncak jumlah koneksi sekitar 30 persen lebih rendah dibanding random biasa atau round robin, dan least connections sekitar 4 persen lebih baik lagi. Untuk satu nginx di depan beberapa container, least_conn biasa lebih sederhana dan sudah cukup.
Layer 4 atau layer 7: apakah algoritmanya berubah?
Di blok http, nginx melakukan balancing layer 7: ia sudah mem-parse request HTTP, sehingga bisa meng-hash cookie, routing berdasarkan URL atau terminate TLS sebelum memilih. Di blok stream, ia melakukan balancing layer 4: hanya melihat koneksi TCP. Stream upstream module menyediakan hash, least_conn, least_time dan random, serta memakai weighted round robin bila tidak ada yang disebut. Tidak ada direktif ip_hash di sana, jadi padanannya adalah hash $remote_addr, opsional dengan consistent.
# Layer 4: a stream block, TCP only. No ip_hash here; use hash on the address.
stream {
upstream pg_replicas {
least_conn; # long-lived connections: count them
server 10.0.0.21:5432;
server 10.0.0.22:5432;
}
server {
listen 5432;
proxy_pass pg_replicas;
}
}
# Layer 7 stays in the http block, where cookies, headers and URLs are visible.
Layer 4 cocok untuk protokol yang tidak perlu di-parse nginx, seperti traffic database ke read replica. Koneksi di sana berumur panjang, jadi menghitung koneksi dengan least_conn lebih bermakna daripada bergiliran. Apa pun yang butuh URL, header atau cookie, termasuk routing berdasarkan path, membutuhkan layer 7.
Bagaimana health check mengubah algoritma yang cocok?
Algoritma hanya memilih di antara server yang ia yakini hidup, jadi health check menentukan keyakinan itu. Nginx open source memakai passive check: saat respons dari sebuah server gagal, nginx menandainya gagal dan menghindarinya untuk sementara. Parameter max_fails default 1 dan 0 mematikan penghitungan, sedangkan fail_timeout default 10 detik. Setelah waktu itu nginx menguji server dengan request klien yang sebenarnya dan memulihkannya bila berhasil.
upstream api_pool {
least_conn;
# After 3 failed attempts, skip the server for 30 s, then probe it
# with live requests. Defaults are max_fails=1 and fail_timeout=10s.
server 10.0.0.11:3000 max_fails=3 fail_timeout=30s;
server 10.0.0.12:3000 max_fails=3 fail_timeout=30s;
# Only receives traffic when the primary servers are unavailable.
server 10.0.0.13:3000 backup;
}
Passive check memakan satu request pengguna nyata per deteksi, jadi perketat untuk production dan siapkan cadangan. Halaman upstream module mencantumkan direktif health_check aktif sebagai bagian dari commercial subscription, sehingga di build open source yang tersedia adalah setelan passive plus server backup. Algoritma bereaksi berbeda terhadap server yang buruk: least_conn menjauh dari server yang lambat dengan sendirinya, round robin terus memberinya jatah sampai ditandai gagal, dan ip_hash menjaga klien tetap terpaku padanya sampai saat itu. Endpoint /health di aplikasi, seperti di post NestJS Terminus health checks, tetap berguna untuk deploy dan monitoring.
Algoritma load balancing mana yang sebaiknya dipilih?
Cocokkan algoritma dengan apa yang bervariasi di traffic Anda. Tabel merangkum direktif nginx, situasi yang cocok dan cara kegagalannya.
Algoritma
Direktif nginx
Cocok saat
Gagal saat
Round robin
tidak ada (default)
Server stateless identik, request pendek dan seragam
Biaya request bervariasi, sehingga satu server menampung yang lambat
Weighted round robin
weight=N pada server
Server dengan ukuran berbeda
Weight hanyalah tebakan yang bergeser seiring workload berubah
Least connections
least_conn
Durasi request campuran, koneksi berumur panjang
Jumlah koneksi bukan proxy yang baik untuk beban bila biaya per koneksi sangat berbeda
IP hash
ip_hash
Stickiness cepat tanpa session store bersama
Klien berbagi alamat, ada proxy di depan, atau ukuran pool berubah
Hash dengan consistent
hash $cookie_sid consistent
Stickiness berdasarkan sesi atau cache key, pool yang berubah ukuran
Kuncinya kosong atau miring, sehingga traffic menumpuk
Power of two choices
random two
Beberapa balancer memutuskan secara independen
Satu balancer dengan pool kecil, di mana least_conn lebih sederhana
Sebagai checklist, telusuri berurutan dan berhenti di baris pertama yang berlaku:
Server identik dan biaya request serupa: round robin, yang sudah menjadi default.
Server berukuran berbeda: tambahkan weight pada yang lebih besar.
Durasi request bervariasi, atau koneksi terbuka lama: least_conn.
Klien harus kembali ke server yang sama: pindahkan sesi ke Redis dulu. Jika tidak mungkin, hash session identifier dengan consistent, bukan IP mentah.
Dalam semua kasus: atur max_fails dan fail_timeout, dan siapkan server backup.
Pada satu VPS dengan beberapa replika Docker dari API NestJS, checklist itu berakhir di least_conn dengan sesi di Redis, yang akan saya pakai untuk backend ERP atau POS. Beralih ke yang lebih rumit hanya setelah aturan sederhana terbukti bermasalah.
Pilih algoritma berdasarkan apa yang bervariasi: ukuran server, biaya request, atau kebutuhan stickiness. Default ke round robin untuk kerja seragam, least_conn untuk kerja tidak seragam, dan hashing hanya saat state memaksa. Apa pun pilihannya, health check yang menentukan apakah ia tetap bekerja saat server gagal.