„Die COVID-19-Pandemie hat unsere Vorstellung von Arbeit und Studieren sowie die Art und Weise, wie wir soziale Kontakte pflegen, auf völlig neue Füße gestellt. Wie viele andere auch habe ich Microsoft Teams für die Kommunikation mit meinen Kollegen für mich entdeckt. In diesem Beitrag erzählen Rish Tandon (Corporate Vice President), Aarthi Natarajan (Group Engineering Manager) und Martin Taillefer (Architect) aus dem Microsoft Teams-Produktteam von ihren Erfahrungen beim Verwalten und Skalieren einer sicheren Produktivitäts-App für Unternehmen.“ – Mark Russinovich, CTO, Azure
Skalierbarkeit, Resilienz und Leistung kommen nicht von ungefähr. Es erfordert dauerhafte und wohlüberlegte Investitionen sowie eine leistungsorientierte Denkweise, um Produkte zu entwickeln, die unsere Benutzer begeistern. Seit der Markteinführung im Jahr 2017 hat die Nachfrage nach Microsoft Teams stark zugenommen: auf zunächst 13 Millionen tägliche Benutzer im Juli 2019 und auf 20 Millionen im November 2019. Im April haben wir verkündet, dass Teams täglich mehr als 75 Millionen aktive Benutzer, 200 Millionen Meetingteilnehmer und 4,1 Milliarden Meetingminuten verzeichnet. Wir dachten in Anbetracht der Schnelligkeit, mit der Teams bis dahin angewachsen war, dass wir wüssten, wie man einen Dienst entsprechend kontinuierlich skaliert. Diese Annahme wurde durch COVID-19 auf die Probe gestellt. War unsere Erfahrungsgrundlage ausreichend, um den Dienst auch während dieser Phase des zuvor undenkbaren Wachstums am Laufen zu halten?
Eine solide Grundlage
Teams basiert auf einer Microservicesarchitektur, in der ein paar Hundert zusammenhängende Microservices die zahlreichen Features unserer Produkte wie Messaging, Meetings, Dateien, Kalender und Apps bereitstellen. Dank der Microservices können unsere einzelnen Komponententeams unabhängig voneinander arbeiten und ihre Änderungen veröffentlichen.
Azure ist die Cloudplattform, die allen Clouddiensten von Microsoft, einschließlich Microsoft Teams, zugrunde liegt. Die Teams-Workloads werden auf virtuellen Azure-Computern (Virtual Machines, VMs) ausgeführt, wobei die älteren Dienste über Azure Cloud Services und die neueren über Azure Service Fabric bereitgestellt werden. Der primäre Speicherstapel ist Azure Cosmos DB. Einige Dienste verwenden jedoch auch Azure Blob Storage. Wenn der Durchsatz hoch ist und Resilienz zählt, kommt Azure Cache for Redis zum Einsatz. Mit Traffic Manager und Azure Front Door lässt sich Datenverkehr genau dahin weiterleiten, wo er gebraucht wird. Die Kommunikation erfolgt mithilfe von Queue Storage und Event Hubs, während Azure Active Directory die Verwaltung von Mandanten und Benutzern ermöglicht.
Obwohl sich dieser Beitrag hauptsächlich auf das Cloud-Back-End konzentriert, möchten wir betonen, dass die Teams-Clientanwendungen dank moderner Entwurfsmuster und Frameworks ein hochwertiges und benutzerfreundliches Produkt mit Unterstützung für Offlineszenarios und zeitweilige Verbindungsunterbrechungen darstellen. Die Möglichkeit, Teams-Clients schnell und zusammen mit dem Dienst zu aktualisieren, ist der Schlüssel für eine schnelle Iteration. Wenn Sie mehr über unsere Architektur erfahren möchten, sehen Sie sich diese Session von der Microsoft Ignite 2019 an.
Agile Entwicklung
Unsere CI/CD-Pipelines basieren auf Azure Pipelines. Die Bereitstellungsstrategie ist ringbasiert und sieht Gates vor, in denen automatisierte End-to-End-Tests und Telemetriesignale ausgewertet werden. Die Telemetriesignale sind mit Incident-Management-Pipelines integriert, um anhand von dienst- und clientdefinierten Metriken Warnungen ausgeben zu können. Für die Analyse wird hauptsächlich Azure Data Explorer eingesetzt.
Zudem wird das Verhalten von Features für wichtige Produktmetriken, z. B. die Absturzrate, die Arbeitsspeicherauslastung, die Reaktionsfähigkeit von Anwendungen, die Leistung und das User Engagement, über eine Experimentpipeline mit Scorecards ausgewertet. Dadurch erfahren wir, ob neue Features wie gewünscht funktionieren.
Alle Teams-Dienste und -Clients verwenden einen zentralen Konfigurationsverwaltungsdienst. Dieser stellt Konfigurationszustände bereit, mit denen sich Produktfeatures an- und ausschalten, Werte für die Gültigkeitsdauer des Caches anpassen, Häufigkeiten von Netzwerkanforderungen steuern und Netzwerkendpunkte für APIs-Anfragen festlegen lassen. So entsteht ein flexibles Framework für Dark Launches und A/B-Tests, mit dem die Auswirkungen von Änderungen genau gemessen werden können. Darüber hinaus lässt sich so sicherstellen, dass die Änderungen für alle Benutzer sicher und effizient sind.
Wichtige Resilienzstrategien
In den Teams-Diensten kommen verschiedene Resilienzstrategien zum Einsatz:
- Aktiv-aktiv fehlertolerante Systeme: Ein aktiv-aktiv fehlertolerantes System besteht per definitionem aus (mindestens) zwei operativ unabhängigen heterogenen Pfaden. Jeder dieser Pfade überträgt nicht nur stabil Livedatenverkehr, sondern kann auch 100 % des erwarteten Datenverkehrs verarbeiten, während die Auswahl des Clients und des Protokollpfads für ein nahtloses Failover genutzt wird. Diese Strategie wird in Szenarios mit einer sehr großen Fehlerdomäne oder Auswirkungen auf Kunden eingesetzt, deren Kosten die Erstellung und Wartung heterogener Systeme rechtfertigen. Für extern sichtbare Clientdomänen wird beispielsweise das DNS-System von Office 365 verwendet. Außerdem werden statische CDN-Klassendaten sowohl in Azure Front Door als auch in Akamai gehostet.
- Resilienzoptimierte Caches: Caches werden zwecks Leistung und Resilienz sehr häufig zwischen in Teams-Komponenten eingesetzt. Sie tragen dazu bei, die durchschnittliche Latenz zu verringern und eine Datenquelle bereitzustellen, falls ein Downstreamdienst nicht verfügbar ist. Werden Daten über einen längeren Zeitraum in Caches aufbewahrt, führt dies zu Problemen mit der Datenaktualität. Es ist jedoch auch der beste Schutz vor Downstreamfehlern. Die wichtigsten Werte für die Cachedaten sind die Dauer bis zur nächsten Aktualisierung (Time to Refresh, TTR) und die Gültigkeitsdauer (Time to Live, TTL). Durch einen hohen TTL- und einen niedrigen TTR-Wert lässt sich genau abstimmen, wie aktuell Daten sein und wie lange diese bei einem Ausfall einer Downstreamabhängigkeit aufbewahrt werden sollen.
- Trennschalter: Hierbei handelt es sich um ein gängiges Entwurfsmuster, das einen Dienst daran hindert, einen Vorgang auszuführen, der wahrscheinlich fehlschlägt. Es gibt dem Downstreamdienst die Möglichkeit, sich zu erholen, ohne mit Wiederholungsanforderungen überlastet zu werden. Das Muster verbessert außerdem die Reaktion eines Diensts, wenn dessen Abhängigkeiten die Fehlertoleranz des Systems nicht steigern.
- Bulkheadisolation: Einige kritische Teams-Dienste sind in vollständig isolierte Bereitstellungen partitioniert. Wenn in einer Bereitstellung etwas schiefläuft, soll die Bulkheadisolation die Funktionsfähigkeit der anderen Bereitstellungen unterstützen. Dieses Feature zur Risikominderung sichert die Funktionalität für so viele Kunden wie möglich.
- Ratenbeschränkung für API-Ebenen: In den kritischen Teams-Diensten ist sichergestellt, dass Anforderungen auf API-Ebene gedrosselt werden können. Diese Grenzwerte werden über das zentralisierte Konfigurationsverwaltungssystem verwaltet, das zuvor erwähnt wurde. Diese Funktion ermöglichte es, während der Ausbreitung von COVID-19 eine Ratenbeschränkung für nicht kritische APIs zu implementieren.
- Effiziente Wiederholungsmuster: Mit diesem Ansatz kann überprüft und sichergestellt werden, dass alle API-Clients eine effiziente Wiederholungslogik implementieren, die einen Ansturm von Datenverkehr infolge von Netzwerkfehlern verhindert.
- Timeouts: Eine konsistente Verwendung der Timeoutsemantik verhindert, dass Prozesse zum Erliegen kommen, wenn bei einer Downstreamabhängigkeit ein Problem auftritt.
- Ordnungsgemäße Verarbeitung von Netzwerkfehlern: Eines der langfristigen Ziele für Teams besteht darin, die Clientleistung in Offlineszenarios oder bei schlechten Verbindungen zu verbessern. Dank einiger bedeutender Verbesserungen in diesem Bereich, deren Einführung mit dem Beginn der COVID-19-Krise zusammenfiel, kann der Client den Dienst unabhängig von der Netzwerkqualität konsistent bereitstellen.
Wenn Sie sich bereits mit den Azure-Cloudentwurfsmustern beschäftigt haben, sind Ihnen viele dieser Konzepte möglicherweise vertraut. Die Microservices, auf denen Teams aufbaut, verwenden außerdem Polly. Diese Bibliothek enthält Implementierungen für einige dieser Muster.
Diese Architektur funktionierte gut für Teams, die Produktnachfrage wuchs von Monat zu Monat, und die Plattform skalierte problemlos in Abhängigkeit von der Nachfrage. Skalierbarkeit ist jedoch kein Selbstläufer. Sie erfordert kontinuierliche Aufmerksamkeit, um neue Verhaltensweisen in komplexen Systemen zu entdecken.
Als aufgrund von COVID-19 immer mehr Menschen weltweit zu Hause bleiben mussten, bestand die Herausforderung darin, die integrierte Flexibilität der Systemarchitektur zu nutzen und an den richtigen Stellschrauben zu drehen, um effektiv auf die schnell steigende Nachfrage reagieren zu können.
Kapazitätsprognosen
Wie bei jedem anderen Produkt auch werden für Teams Modelle erstellt, die regelmäßig durchlaufen werden, um Wachstumsprognosen zu treffen, sowohl im Hinblick auf die Benutzerzahl als auch im Hinblick auf Verwendungsmuster. Die Modelle basieren auf historischen Daten, zyklischen Mustern, neuen Großkunden und einer Vielzahl anderer Eingaben.
Als COVID-19 begann, sich auszubreiten, wurde schnell deutlich, dass unsere früheren Vorhersagemodelle nicht mehr gültig waren. Es mussten neue Modelle erarbeitet und dabei das enorme Wachstum der globalen Nachfrage berücksichtigt werden. Viele maßgebliche Veränderungen liefen gleichzeitig ab: Bestandskunden begannen, Teams anders zu verwenden als zuvor, bei früher inaktiven Bestandskunden wurde Teams neuerdings wieder eingesetzt, und viele neue Benutzer nahmen das Produkt neu in Betrieb. Außerdem mussten schnelle Ressourcenentscheidungen getroffen werden, um potenzielle Compute- und Netzwerkengpässe zu bewältigen. Dazu wurden mehrere Predictive-Modelling-Techniken (ARIMA, additiv, multiplikativ, logarithmisch) mit länderspezifischen grundlegenden Obergrenzen kombiniert, um Überschätzungen bei den Prognosen zu vermeiden. Die Modelle wurden anschließend optimiert, indem der Wendepunkt und die Wachstumsmuster auf die Nutzung in den einzelnen Branchen und nach geografischer Region analysiert wurden. Zu diesem Zweck wurden auch externe Datenquellen hinzugezogen, unter anderem die nach Ländern und Datumsangaben geordneten COVID-19-Recherchedaten der Johns-Hopkins-Universität, um die Prognose der Spitzenlast für Engpassregionen zu verbessern.
Während des gesamten Prozesses sollten Risiken vermieden werden. Daher wurde vor allem auf Überbereitstellung gesetzt. Als sich die Nutzungstrends stabilisierten, wurde nach Bedarf wieder zurückskaliert.
Skalieren der Computeressourcen
Microsoft Teams ist generell so konzipiert, dass Naturkatastrophen ohne Dienstunterbrechungen überstanden werden. Dank der Azure-Regionen lassen sich verschiedene Risiken mindern: das Risiko von Problemen in Rechenzentren, aber auch das Risiko von Unterbrechungen in einer großen geografischen Region. Das bedeutet jedoch, dass zusätzliche Ressourcen bereitgestellt werden müssen, die die Last der betroffenen Region in einem solchen Fall übernehmen können. Zum Aufskalieren wurde die Bereitstellung aller kritischen Microservices schnell auf weitere Regionen in den wichtigen Azure-Geografien erweitert. Indem die Gesamtanzahl der Regionen pro Geografie hochgesetzt wurde, konnte die Gesamtmenge an Reservekapazität gesenkt werden, die in jeder Region für eventuelle Notfalllasten vorgehalten werden musste. Auf diese Weise konnte der Kapazitätsbedarf insgesamt reduziert werden. Aus der Auseinandersetzung mit dieser noch nie dagewesenen Last hat das Produktteam einige Erkenntnisse dazu gewonnen, wie sich die Effizienz steigern lässt:
- Durch die Neubereitstellung einiger Microservices, die der Implementierung einer größeren Anzahl kleinerer Computecluster diente, fielen einige clusterbezogene Skalierungsaspekte weg. Außerdem konnte die Bereitstellung beschleunigt und der Lastenausgleich noch präziser vorgenommen werden.
- Früher waren für unterschiedliche Microservices bestimmte VM-Typen erforderlich. Durch eine höhere Flexibilität in Bezug auf den VM-Typ oder die CPU und einen Fokus auf die allgemeine Rechenleistung bzw. den Arbeitsspeicher konnten die Azure-Ressourcen in den einzelnen Regionen effizienter genutzt werden.
- Der Dienstcode selbst wurde optimiert. Einige einfache Verbesserungen führten beispielsweise zu einer erheblichen Senkung der CPU-Zeit, die für das Erstellen von Avataren aufgewendet werden muss. Bei Avataren handelt es sich um die kleinen Kreise mit den Initialen, die angezeigt werden, wenn keine Bild des Benutzers verfügbar ist.
Netzwerk- und Routingoptimierung
Der Großteil des Kapazitätsverbrauchs in Microsoft Teams erfolgt in allen Azure-Geografien während des Tages. Während der Nacht befinden sich die Ressourcen im Leerlauf. Damit auch diese Leerlaufkapazität sinnvoll eingesetzt wird, wurden (unter Beachtung der Anforderungen an Compliance und Data Residency) neue Routingstrategien eingeführt:
- Nicht interaktive Hintergrundtasks werden dynamisch in die aktuell im Leerlauf befindliche Kapazität migriert. Dazu wurden API-spezifische Routen in Azure Front Door programmiert, die sicherstellen, dass der Datenverkehr an den richtigen Ort weitergeleitet wird.
- Anruf- und Meetingdatenverkehr wurde zwischen mehreren Regionen weitergeleitet, um den Anstieg absorbieren zu können. Diese Last konnte mit Azure Traffic Manager und den beobachteten Nutzungsmustern effektiv verteilt werden. Darüber hinaus wurden Runbooks erstellt, die einen tageszeitabhängigen Lastenausgleich vornehmen, um eine Wide-Area-Network-Drosselung (WAN) zu verhindern.
Ein Teil des Teams-Clientdatenverkehr wird an Azure Front Door gesendet. Nachdem zusätzliche Cluster in weiteren Regionen bereitgestellt wurden, fiel jedoch auf, dass einige neue Cluster nicht genügend Datenverkehr erhielten. Dabei handelte es sich um eine Folge des Standorts, an dem sich die Benutzer und die Azure Front Door-Knoten jeweils befanden. Diese ungleiche Verteilung ließ sich mithilfe der Fähigkeit von Azure Front Door beheben, Datenverkehr auf Länderebene weiterzuleiten. Im folgenden Beispiel sehen Sie, wie die Verteilung des Datenverkehrs optimiert werden konnte, indem zusätzlicher Datenverkehr aus Frankreich für einen Teams-Dienst an die Region „Vereinigtes Königreich, Westen“ weitergeleitet wurde.
Abbildung 1: Verbesserte Verteilung des Datenverkehrs, nachdem Datenverkehr zwischen Regionen weitergeleitet wurde
Cache- und Speicherverbesserungen
In Teams werden sehr oft sehr große verteilte Caches verwendet. Als der Teams-Datenverkehr zunahm, wuchs auch die Last auf die Caches. Diese Last wurde so groß, dass die einzelnen Caches nicht mehr skalierten. Deshalb wurden einige einfache Änderungen mit erheblichen Auswirkungen auf die Cacheverwendung vorgenommen:
- Der Cachezustand wird von nun an in einem Binärformat und nicht mehr als JSON-Rohdaten gespeichert. Hierfür wurde das Protokollpufferformat verwendet.
- Daten werden jetzt vor dem Senden an den Cache komprimiert. Aufgrund des hervorragenden Verhältnisses von Geschwindigkeit zu Komprimierung fiel die Wahl auf die LZ4-Komprimierung.
Auf diese Weise konnte die Nutzlast um 65 %, die Deserialisierungszeit um 40 % und die Serialisierungszeit um 20 % gesenkt werden. Ein voller Erfolg.
Untersuchungen ergaben, dass mehrere Caches übermäßig strikte TTL-Einstellungen aufwiesen, was zur übereifrigen Entfernung von Daten führte. Das Hochsetzen dieser TTL-Werte bewirkte sowohl eine Senkung der durchschnittlichen Latenz als auch eine Verkleinerung der Last, die auf Downstreamsystemen ruhte.
Gezielte Abschaltung (Featurebrownouts)
Da ungewiss war, wie weitgreifend die Veränderungen sein mussten, wurden Mechanismen implementiert, die eine schnelle Reaktion auf unerwartete Anforderungsspitzen ermöglichen und Zeit schaffen, um zusätzliche Teams-Kapazität verfügbar zu machen.
Nicht alle Features sind gleich wichtig für unsere Kunden. Das Senden und Empfangen von Nachrichten ist beispielsweise wichtiger als die Möglichkeit, zu sehen, dass der Gesprächspartner gerade eine Nachricht eingibt. Aus diesem Grund wurde der Schreibhinweis für zwei Wochen deaktiviert, während am Hochskalieren der Teams-Dienste gearbeitet wurde. Dadurch wurde der Spitzendatenverkehr für einige Teile der Infrastruktur um 30 % reduziert.
Üblicherweise wird in vielen Architekturebenen verstärkt auf Vorabrufe gesetzt, sodass benötigte Daten immer schnell zur Hand sind. Dies reduziert die durchschnittliche Gesamtlatenz. Vorabrufe sind jedoch unter Umständen teuer, da ein Teil der Daten nie verwendet wird und die entsprechenden Prozesse überflüssig sind. Zudem werden Speicherressourcen belegt. Daher wurden Vorabrufe in einigen Szenarios deaktiviert, um Kapazität für Teams-Dienste freizugeben, was natürlich mit einer höheren Latenz einherging. In anderen Fällen wurde die Dauer der Synchronisierungsintervalle für Vorabrufe verlängert. So wurde beispielsweise beim Unterdrücken der Vorabrufe von Kalenderdaten auf mobilen Geräten verfahren, wodurch sich das Anforderungsvolumen um 80 % senken ließ:
Abbildung 2: Deaktivieren des Vorabrufens von Details zu Kalenderereignissen auf mobilen Geräten
Incident Management
Für Teams ist zwar ein ausgereifter Incident-Management-Prozess in Kraft, mit dem sich die Integrität des Systems nachverfolgen und verwalten lässt, die durch das Coronavirus verursachte Situation war jedoch neu. Es musste nicht nur ein enormer Anstieg des Datenverkehrs absorbiert werden, auch unsere Entwickler und Kollegen sahen sich mit persönlichen und emotionalen Herausforderungen konfrontiert und mussten gleichzeitig die Umstellung auf das Homeoffice meistern.
Damit wir als Unternehmen nicht nur unseren Kunden, sondern auch unseren Entwicklern gerecht werden, wurden einige Änderungen vorgenommen:
- Die Incident-Management-Rotationen wurden von einem wöchentlichen auf einen täglichen Rhythmus umgestellt.
- Jeder Entwickler, der auf Abruf bereitstehen musste, hatte zwischen den Schichten mindestens 12 Stunden frei.
- Darüber hinaus wurden weitere Incident Manager aus dem gesamten Unternehmen ins Team geholt.
- Alle nicht kritischen Dienständerungen wurden verschoben.
Dank dieser Maßnahmen hatten unsere Incident Manager und Entwickler Zeit, sich auf ihre Bedürfnisse zu Hause zu konzentrieren und gleichzeitig den Anliegen unserer Kunden nachzukommen.
Die Zukunft von Teams
Es ist interessant, sich vorzustellen, wie diese Situation verlaufen wäre, wenn sie vor ein paar Jahren aufgetreten wäre. Ohne Cloud Computing wäre eine Skalierung in dieser Größenordnung nicht möglich gewesen. Was heute durch einfaches Ändern von Konfigurationsdateien machbar ist, hätte früher möglicherweise den Erwerb von neuer Hardware oder gar neuen Gebäuden erfordert. Da sich die aktuelle Nachfrage und damit der Skalierungsbedarf stabilisiert, haben wir unsere Aufmerksamkeit wieder auf die Zukunft gerichtet. Wir sind überzeugt, dass wir unsere Infrastruktur noch auf vielerlei Weise verbessern können:
- Es ist geplant, mithilfe von Azure Kubernetes Service eine Umstellung von VM-basierten auf containerbasierte Bereitstellungen durchzuführen. Wir rechnen damit, dass dies zu einer Senkung der Betriebskosten, einer Agilitätssteigerung sowie einer besseren Ausrichtung an der Branche führen wird.
- Die Verwendung von REST soll zugunsten von effizienteren binären Protokollen wie gRPC minimiert werden. Mehrere Abstimmungsinstanzen werden systemweit durch effizientere ereignisbasierte Modelle ersetzt.
- Chaos-Engineering-Praktiken werden systematisch übernommen, um sicherzustellen, dass alle bereitgestellten Mechanismen, die unser System zuverlässiger gestalten sollen, immer voll funktionsfähig und bereit sind, in Aktion zu treten.
Wenn wir unsere Architektur an den Branchenpraktiken und den bewährten Methoden des Azure-Teams ausrichten, gibt es viele Experten, die uns bei Bedarf zur Seite springen können, sei es bei Problemen bei der Datenanalyse, der Überwachung, der Leistungsoptimierung oder bei Problemen mit dem Incident Management. Wir möchten uns bei unseren Kollegen bei Microsoft und der großen Entwicklercommunity für ihre Offenheit bedanken. Architekturen und Technologien sind zwar wichtig, die Integrität von Systemen wird jedoch vor allem mithilfe von Teamwork gewahrt.
Ähnlicher Beitrag: Azure reagiert auf COVID-19
Ähnlicher Artikel: Microsoft während der COVID-19-Pandemie: Kapazitätssteigerung in Azure zur Unterstützung unserer Kunden