Zero Downtime Release: Disruption-free Load Balancing of a Multi-Billion User Website
Kurzfassung
-
Server werden häufig neu gestartet: Upgrades, Bugfixes, Sicherheitspatches
-
Durch die Einführung von Continuous Release
→ wurden bei Facebook aus einmal pro Woche im Jahr 2007 mehr als 100 Deployments pro Woche
→ werden täglich Millionen von Servern neu gestartet
→ gilt das Gleiche für AWS, Atlassian, Yelp, Ebay und Uber
→ schlagen Health Checks intermittierend fehl
- Traditionelle Deployment-Methoden
- Blue/Green Deployment (AWS CodeDeploy, Kubernetes): Aufteilung in zwei Maschinengruppen, und der Load Balancer leitet den Traffic für das Update zunächst auf eine Seite um
→ teuer. Für Edge-Umgebungen mit sehr vielen Maschinen ungeeignet
- Rolling Updates (Envoy, NGINX, Apache, Kubernetes, AWS): schrittweise Aktualisierung Maschine für Maschine, während der Load Balancer den Traffic anpasst
→ geringere CPU-Auslastung während des Updates, langsame Iteration.
- Hot Restart (HAProxy, Envoy): Auf derselben Maschine wird ein Prozess der neuen Version gestartet, und sobald der Traffic des bestehenden Prozesses nach und nach endet, übernimmt der neue Prozess den Traffic (SO_REUSEPORT, CMSG, SCM_RIGHTS)
→ nur für TCP geeignet, bei UDP kann es zu falschem Routing kommen
"Wie kann man Release-Updates ohne Downtime, mit schneller Iteration und ohne Unterbrechung durchführen?"
- Facebooks Traffic-Infrastruktur
- Edge PoP (L7 LB, ProxyGen) - Data Center (L7 LB, ProxyGen) - App Server (HHVM, MQTT)
→ Neustarts pro Tier, um Unterbrechungen zu vermeiden
→ Die Maschinen an Edge und im Data Center starten jeweils ein neues ProxyGen für "Socket TakeOver"
→ "Downstream Connection Reuse" zwischen Edge und Data Center
→ Für Verbindungen zwischen Data Center und App Server: "Partial Post Replay"
- Socket Takeover: Start eines neuen Prozesses, der per SCM_RIGHTS und CMSG TCP-Listening- und UDP-VIP-Sockets übernimmt
→ SCM_RIGHTS: Socket-Typ, der die Übergabe von File Descriptors eines anderen Prozesses ermöglicht
→ CMSG: ermöglicht mit der Funktion sendmsg() das Senden von Kontrollnachrichten zwischen lokalen Prozessen
→ Für QUIC, eine UDP-basierte Verbindung, fragt der neue Prozess bei bestehenden Verbindungen den alten Prozess nach der QUIC ConnectionID und leitet das jeweilige Paket an den alten Prozess weiter
- Partial Post Replay (Neustart des App-Servers)
→ Der App-Server hat zwei Arten von Workloads: kurze API-Aufrufe und lange HTTP-POST-Aufrufe (Upload)
→ Da auf diesem App-Server keine freien Ressourcen vorhanden sind, ist es nicht möglich, wie bei Socket Takeover eine neue Instanz zu starten und den Socket zu übergeben; zudem ist die lange Upload-Zeit ein Problem
→ Wenn der App-Server während eines langen Uploads aktualisiert wird, hat der Proxy den gesamten Inhalt nicht vorliegen; daher bricht er den betreffenden POST ab und gibt zusammen mit dem Code 379 die bis dahin empfangenen Daten an den Proxy zurück
→ Der Proxy kombiniert die vom bestehenden App-Server erhaltenen Daten mit den verbleibenden Daten und versucht dann, sie erneut an die neue Maschine zu senden
- Vorteile von Zero Downtime Release
→ etwa 20 % höhere CPU-Auslastung im Vergleich zu Rolling Update
→ im Gegensatz zu Hot Restart, das bis zu 20K QUIC-Pakete falsch geroutet hat, gibt es nahezu kein Fehlrouting
→ Socket TakeOver wird bei Facebook seit 2013 eingesetzt, der Rest seit 2015
1 Kommentare
Der obige Inhalt ist eine Zusammenfassung auf Basis dieses 20-minütigen Erklärungsvideos: https://dl.acm.org/action/downloadSupplement/…
ProxyGen: Facebooks C++-HTTP-Bibliothek https://github.com/facebook/proxygen