"Önüne bir yük dengeleyici koy" sistem tasarımında en sık kurulan cümledir ve üretimde önemli olan bir avuç kararı gizler: hangi katmanda çalıştığı, bir backend'i nasıl seçtiği, bir backend'in sağlıklı olduğunu nasıl anladığı ve biri çıkarıldığında yoldaki isteklere ne olduğu.
Bu yazı bu kararları tek tek ele alıyor ve büyük kurulumların çoğunun sonunda vardığı iki katmanlı yapıyı çiziyor: bir katman 7 proxy filosunun önünde bir katman 4 dengeleyici.
Katman 4 ve katman 7
| Katman 4 | Katman 7 | |
|---|---|---|
| Ne görür | IP adresleri, portlar, TCP ya da UDP bağlantıları | HTTP istekleri: host, yol, header'lar, çerezler |
| Neyi dengeler | Bağlantıları | İstekleri |
| TLS | Olduğu gibi geçirir ya da sonlandırır | Genellikle sonlandırır |
| Neye göre yönlendirebilir | Port, kaynak adres | Yol, host, header, metot |
| Başka neler yapabilir | Çok yüksek verim, düşük gecikme | Yeniden deneme, zaman aşımı, yeniden yazma, kimlik doğrulama, hız sınırı |
| Örnekler | Bulut ağ yük dengeleyicileri, IPVS, Maglev tarzı dengeleyiciler | Envoy, NGINX, HTTP modunda HAProxy, bulut uygulama yük dengeleyicileri |
Can yakan fark şu: katman 4 dengeleyici istekleri değil bağlantıları dengeler. HTTP/2 ya da gRPC ile bir istemci uzun ömürlü tek bir bağlantı açar ve üzerinden binlerce istek gönderir; hepsi aynı backend'e düşer. gRPC'yi iyi dengelemek için bir katman 7 proxy ya da istemci tarafında yük dengeleme gerekir.
Neden iki katman
Büyük kurulumlar genellikle ikisini üst üste koyar. Katman 4 katmanı genel IP adreslerini tutar, bağlantı sellerini emer ve her akışı (flow) hash'leyerek bağlantıları bir katman 7 proxy filosuna dağıtır. Proxy'ler TLS'i sonlandırır, yönlendirme kurallarını uygular ve tek tek istekleri backend havuzlarına dengeler.
Her katman kendi başına ölçeklenir: katman 4 katmanı paketlere ve bağlantılara göre, proxy filosu isteklere ve TLS el sıkışmalarına göre. Bunları ayırmak etki alanını da sınırlar; kötü bir proxy yapılandırma değişikliği, kullanıcıların bağlandığı adresleri değil, bir katmanın arkasındaki proxy'leri etkiler. Proxy'ler durumsuz olduğu ve tek bir yapılandırmayı paylaştığı için bir tane daha eklemek yalnızca kapasite eklemek demektir.
Dengeleme algoritmaları
| Algoritma | Nasıl seçer | Uygun olduğu durum | Dikkat edilecek nokta |
|---|---|---|---|
| Round robin | Sıradaki backend | Özdeş backend'ler, benzer istekler | Yavaş istekler yavaş backend'lerde birikir |
| Ağırlıklı round robin | Ağırlıklarla orantılı round robin | Farklı boyutlu örnekler, kademeli geçişler | Ağırlıklar statiktir |
| Least connections | En az açık bağlantı | Uzun ömürlü bağlantılar | Dengeleyicide küresel durum gerektirir |
| Least request (iki seçeneğin gücü) | Rastgele iki tane seç, daha az meşgul olana gönder | Çoğu HTTP servisi | Backend başına istek sayıları gerekir |
| Tutarlı hashing | Kullanıcı kimliği gibi bir anahtarın hash'i | Önbellekler, sabit eşleşme | Sıcak anahtarlarla dengesiz yük |
Rastgele iki seçenekli least request, HTTP servisleri için iyi bir varsayılandır. Envoy'un yük dengeleyici belgeleri bunu şöyle anlatır: rastgele iki host seç (varsayılan iki), isteği daha az aktif isteği olana gönder. Mitzenmacher ve diğerlerinin araştırmaları bunun, maliyetine katlanmadan, neredeyse her backend'i kontrol etmek kadar iyi olduğunu gösterir. Ring hash ya da Maglev algoritması gibi tutarlı hashing, aynı anahtarı aynı backend'de tutar ve backend'ler değiştiğinde anahtarların yalnızca küçük bir kısmını taşır; önbelleklerin istediği de budur.
Sağlık kontrolleri
Bir dengeleyici, hizmet veremeyen backend'lere trafik göndermeyi bırakmalıdır. İki mekanizma birlikte çalışır:
- Aktif kontroller: dengeleyici bir sağlık uç noktasını çağırır, örneğin her 5 saniyede bir
GET /healthz, ve art arda belirli sayıda başarısızlıktan sonra backend'i çıkarır. - Pasif kontroller (outlier detection): dengeleyici gerçek yanıtları izler, hata döndüren ya da zaman aşımına uğrayan bir backend'i dışarı atar ve bir soğuma süresinden sonra geri alır.
Sağlık uç noktasını dürüst ama ucuz tutun. Her bağımlılığı kontrol ederse, tek bir yavaş veritabanı bütün backend'leri aynı anda sağlıksız gösterir ve dengeleyicinin trafiği gönderecek yeri kalmaz. Bu örneğin istek karşılamak için neye ihtiyaç duyduğunu kontrol edin, ortak bağımlılıkları uygulamanın kendi hata yönetimine bırakın.
Draining ve sticky oturumlar
Bir backend dağıtım ya da küçültme için çıkarıldığında yeni istek almayı bırakmalı ama yoldaki istekleri bitirmelidir. En yavaş normal isteğinizden uzun bir draining süresi (bulut dengeleyicileri buna deregistration delay der) yapılandırın ve uygulamanın kapanırken yeni iş kabul etmeyi bırakmasını sağlayın.
Sticky oturumlar bir kullanıcıyı her seferinde, genellikle bir çerezle, aynı backend'e gönderir. Durum bir sunucunun belleğinde yaşıyorsa işe yarar, geri kalan her şeye zarar verir: dengesiz yük, bir backend öldüğünde kaybolan oturumlar, daha zor dağıtımlar. Oturum durumunu ortak bir depoya taşıyın ve yapabildiğiniz yerde sticky ayarını kapatın.
Tek bir bölgenin ötesi
Yukarıdaki her şey tek bir sahanın içinde olur. Kullanıcıları bölgelere yaymak ayrı bir katmandır: en yakın sağlıklı bölgeyle yanıt veren DNS tabanlı yönlendirme (gecikmeye ya da coğrafi konuma göre yönlendirme) veya birçok sahanın aynı IP adresini duyurduğu ve internet yönlendirmesinin her kullanıcıyı yakındaki bir sahaya ulaştırdığı anycast. Küresel dengeleme bölgeyi seçer; bu yazıdaki iki katman sunucuyu seçer. Sağlık sinyallerinin yukarı doğru akmasını sağlayın; böylece proxy'leri havuzlarına ulaşamayan bir bölge, kullanıcılara hata döndürmek yerine kullanıcı almayı bırakır.
Mimari diyagram
Diyagram içeriği
- Clients
- DNS: one name
- Layer 4 load balancer
- Layer 7 proxy 1
- Layer 7 proxy 2
- Orders pool: 6 instances
- Search pool: 4 instances
- Static files bucket
- Proxy fleet, same config
- resolve
- TCP 443
- flow hash
- /api/orders
- /api/search
- /static
Nasıl okunur:
- Sol: istemciler tek bir DNS adını çözer ve 443 numaralı porttan katman 4 yük dengeleyiciye TCP bağlantıları açar.
- Orta: katman 4 katmanı bağlantıları flow hash ile proxy filosuna dağıtır. Çerçeve, her proxy'nin aynı yapılandırmayı çalıştırdığını gösterir.
- Sağ: proxy'ler TLS'i sonlandırır ve her isteği yola göre yönlendirir:
/api/ordersve/api/searchkendi havuzlarına,/staticbir bucket'a. - Markdown bloğu yönlendirme tablosunu, havuz başına algoritmayı ve sağlık kontrolü ayarlarını içerir; bunlar genellikle yalnızca bir yapılandırma dosyasında yaşayan ayrıntılardır.
Yük dengeleyici diyagramında neler etiketlenmeli
- Her adımdaki katman ve protokol: TCP 443, HTTP/2, gRPC.
- TLS'in nerede sonlandığı. Her katmanın neyi görebileceğini ve sertifikaların nerede durduğunu bu belirler.
- Havuz başına algoritma, hash kullanıyorsanız hash anahtarıyla birlikte.
- Sağlık kontrolü yolu, aralığı ve eşiği.
- Varsa draining ve sticky oturum ayarları.
API ağ geçidi mimari diyagramı yönlendirmenin üstüne oturan katman 7 özelliklerini ele alıyor, Kubernetes ingress diyagramı aynı fikirleri bir cluster'ın içinde gösteriyor, ağ topolojisi diyagramı ise yük dengeleyicileri daha geniş ağın içine yerleştiriyor.
Archboard'da oluşturun
- Google ya da GitHub ile giriş yapın ve bir diyagram oluşturun.
- İstemciler için C4 Modeli paketinden bir Kişi, Ağ paketinden de bir DNS ve bir Yük dengeleyici ekleyin.
- Proxy filosu için Temel paketinden bir Çerçeve ekleyin ve içine iki Konteyner düğümü koyun.
- Havuzlar ve bucket için Bulut paketinden iki Hesaplama düğümü ve bir Nesne depolama düğümü ekleyin.
- Kenarları protokoller ve yollarla etiketleyin ve yönlendirme tablosu ile sağlık kontrollerini içeren, Temel paketinden bir Markdown bloğu ekleyin.
Örnek 10 diyagram düğümü kullanıyor ve Free planın sınırları içinde kalıyor.
SSS
Katman 4 ile katman 7 yük dengeleyici arasındaki fark nedir? Katman 4 dengeleyici TCP ya da UDP bağlantılarını içlerine bakmadan dağıtır. Katman 7 dengeleyici HTTP'yi anlar; bu yüzden yola ya da host'a göre yönlendirebilir ve tek tek istekleri dengeleyebilir.
Hangi yük dengeleme algoritmasını kullanmalıyım? Rastgele iki seçenekli least request, HTTP için güçlü bir varsayılandır. Önbelleklerde olduğu gibi aynı anahtarın aynı backend'e ulaşması gerektiğinde tutarlı hashing kullanın.
gRPC servisim neden tüm trafiği tek bir pod'a gönderiyor? Çünkü gRPC uzun ömürlü HTTP/2 bağlantıları kullanır ve katman 4 dengeleyici istekleri değil bağlantıları dengeler. Araya bir katman 7 proxy koyun ya da istemci tarafında yük dengeleme kullanın.
Bir sağlık kontrolü uç noktası neyi kontrol etmeli? Bu örneğin istek karşılayabildiğini: sürecin ayakta olduğunu ve kendi kritik kaynaklarının erişilebilir olduğunu. Bütün backend'leri aynı anda başarısız kılacak ortak bağımlılıkları kontrol etmekten kaçının.
Sticky oturumlar iyi bir fikir mi? Yalnızca durum sunucudan çıkamıyorsa. Dengesiz yüke ve arızalarda kaybolan oturumlara yol açarlar; ortak bir oturum deposu genellikle daha iyidir.