GitHub, autoscaling en de component substitution fallacy

Oorspronkelijk werd dit veroorzaakt door een Istio-sidecar-pod die zijn concurrency-limieten bereikte en niet correct schaalde. Dit kwam door een foutief geconfigureerd beleid dat wel de host-service, maar niet de sidecar-limieten bewaakte.

Wat is autoscaling?

Voor degenen die niet bekend zijn met autoscaling: de hoeveelheid rekenkracht en geheugen die een service nodig heeft, hangt af van de belasting (load) van die service. De relevante bron van belasting is hier de externe aanvragen tegen de service, ook wel bekend als verkeer (traffic). Het volume van dit verkeer varieert in de loop van de tijd; bij een bedrijf als GitHub is de verwachting dat er tijdens kantooruren meer verkeer is dan in de avonden en weekenden.

Omdat de belasting dynamisch verandert, zijn er twee algemene strategieën voor het toewijzen van resources:

  1. De service voorzien van voldoende capaciteit voor de piekbelasting.
  2. De toegewezen resources dynamisch aanpassen op basis van de huidige belasting; dit is wat we autoscaling noemen.

Om autoscaling te gebruiken, moet je een autoscaling-beleid definiëren. Je moet bepalen welke metrieken de belasting representeren en specificeren hoe resources moeten worden toegevoegd of verwijderd wanneer die metrieken veranderen.

De tekortkomingen van CPU-metrieken

CPU-benutting is een veelgebruikte metriek voor autoscaling. Let echter op dat een service verzadigd kan raken, zelfs als de CPU-belasting laag is.

Stel je een scenario voor waarin je een thread-per-request model gebruikt met een threadpool. Als de latentie van downstream-aanvragen toeneemt, kunnen alle threads in de pool geblokkeerd raken. In dit geval is de service verzadigd en zou het opschalen van nieuwe pods helpen, maar de CPU-belasting is feitelijk laag omdat de threads wachten op I/O (dit gebeurde bij Slack in 2021).

Om dit op te lossen, kun je extra regels toevoegen aan het autoscaling-beleid (zoals Slack deed door snel op te schalen op basis van het aantal threads), of je kunt schalen op basis van het volume aan binnenkomende aanvragen in plaats van CPU, mits de service niet CPU-gebonden is.

Op basis van de analyse van GitHub lijkt het erop dat het autoscaling-beleid voor de getroffen service gebruikmaakte van metrieken die alleen rekening hielden met de belasting van de service zelf, en niet met die van de Istio-sidecar.

De operationele complexiteit

Over het algemeen reageert elke service anders op belasting, wat betekent dat elk autoscaling-beleid in feite maatwerk is. Dit houdt in dat het team dat eigenaar is van een service niet alleen verantwoordelijk is voor de bedrijfslogica, maar ook voor een operationeel controlesysteem met aangepaste parameters. Dit systeem kan eigenlijk alleen worden gevalideerd via load-testing.

De eigenaren van de service zijn bovendien bijna nooit experts op het gebied van autoscaling. Het is dan ook niet verrassend dat een foutief geconfigureerd autoscaling-beleid hier een rol speelde.

De component substitution fallacy

Hoewel het waardevol is om dit specifieke defect te bespreken, is het gevaarlijk om hierop te fixeren ten koste van andere factoren. David Woods noemt dit de component substitution fallacy: het idee dat de manier om betrouwbaarheid te verbeteren is door je te concentreren op het identificeren en repareren van defecte componenten.

Hoewel het correct is om defecten die door een incident aan het licht komen op te lossen, moet je ook erkennen dat:

  • Je systeem op dit moment vol zit met latente componentdefecten.
  • Ondanks de aanwezigheid van al deze defecten, je systeem niet constant uitvalt.

Dit betekent dat componentdefecten op zichzelf niet voldoende zijn om je systeem plat te leggen; anders zou het systeem nu al down zijn. Kijk dus niet alleen naar individuele componenten, maar behandel de interacties als primair. In de GitHub-storing zien we interacties tussen factoren zoals:

  • Veranderende verkeerspatronen (inclusief scrapers).
  • Het autoscaling-beleid.
  • Verzadiging van de Istio-sidecar.
  • Retry-logica.
  • Verzadiging van HAProxy-nodes.
  • Authenticatieverkeer.

Publieke versus interne analyses

Er zijn veel details onbekend omdat dit een snel verspreid publiek verslag is; de echt waardevolle informatie bevindt zich in het interne verslag. Ik heb in dit artikel gespeculeerd over de relatie tussen de service-eigenaar en het autoscaling-beleid, maar ik zou graag meer weten over de historie (bestond dit beleid bijvoorbeeld al vóór het gebruik van Istio-sidecars?). Ook over het problematische verkeer: wat voor soort aanvragen waren het? Was er sprake van een plotselinge piek of een geleidelijke toename? En weten we waarom het verkeer toenam?

Je krijgt geen antwoorden op dit soort vragen bij publieke incident-analyses, maar wel bij de interne analyses binnen je eigen organisatie. Het is aan jou om die vragen te stellen.