1 Punkte von GN⁺ 2024-07-28 | 1 Kommentare | Auf WhatsApp teilen

650.000.000 Checkboxen anklicken: Umgang mit unerwarteter Popularität

Am 26. Juni 2024 wurde die Website One Million Checkboxes (OMCB) gestartet
  • Eine Website mit 1 Million globalen Checkboxen, bei der das Anklicken einer Checkbox sofort für alle Nutzer sichtbar wird
  • Bereits 30 Minuten nach dem Start hatten Tausende Nutzer Millionen von Checkboxen angeklickt
  • Traffic kam von Hacker News, /r/InternetIsBeautiful, Mastodon, Twitter usw.
  • Die Seite wurde auch in der Washington Post und der New York Times vorgestellt
  • Am ersten Tag wurden mehr als 50 Millionen Checkboxen angeklickt
  • Bis zur Abschaltung der Website zwei Wochen später wurden mehr als 650 Millionen Checkboxen angeklickt

Ursprüngliche Architektur

  • Der Zustand der Checkboxen wurde als 1 Million Bits (125 KB) gespeichert
  • Die Clients renderten die Checkboxen mithilfe eines Bitsets und meldeten dem Server den gesetzten Status
  • Der Server nutzte Redis, um Bits zu aktualisieren und an alle Clients zu broadcasten
  • Statische Inhalte wurden über nginx ausgeliefert, während ein Flask-Server den Bitset-Zustand und die WebSocket-Verbindungen verarbeitete
  • Redis diente als Zustands-Storage und Message Queue

Prinzipien für die Skalierung

  • Kostenlimit: Die Skalierung wurde mathematisch durchgerechnet, damit eine serverlose Lösung nicht in den Ruin treibt
  • Kurzfristige Lösungen akzeptieren: Es wurde angenommen, dass die Popularität der Website nur vorübergehend sein würde, daher wurden schnelle Lösungen gewählt
  • Einfache und selbst gehostete Technik verwenden: Es wurden nur Technologien hinzugefügt, für die eigene Server betrieben und debuggt werden konnten
  • Spaß als Ziel: Spaß hatte Vorrang vor Geld
  • Globalen Zustand beibehalten: Alle Nutzer sollten Änderungen sofort sehen können

Der erste Tag: explosionsartige Popularität

  • Bereits nach 30 Minuten schoss die Serverlast in die Höhe
  • Zusätzliche Server wurden hochgefahren, um die Last zu verteilen
  • Batch-Updates wurden eingeführt, um Redis-Verbindungsprobleme zu lösen
  • Die gemanagte Redis-Instanz von Digital Ocean wurde hochgestuft

Über Nacht gab es keinen Plan

  • Es wurde parallel geplant, auf einem ITP-Camp ein Pacman-Spiel mit Gesichtserkennung auszustellen
  • Ein iPad wurde mitgenommen, um Server hochzufahren
  • Mit einer weiterentwickelten Server-Namenskonvention wurden 8 Worker-VMs betrieben
  • Die Anzahl der Flask-Prozesse wurde reduziert und die Größe der Update-Batches erhöht, um die Last zu senken

Bandbreitenprobleme

  • Die Bandbreitenpreise von Digital Ocean waren nicht berücksichtigt worden
  • Die Häufigkeit von Zustands-Snapshots wurde reduziert und die Größe der Updates verkleinert
  • Mit dem tc-Utility wurde die pro Sekunde übertragene Datenmenge begrenzt

Der zweite Tag: weiteres Wachstum

  • Die Website fiel aus, weil die Input-Validierung nicht sauber umgesetzt war
  • Redis-Replikate wurden hinzugefügt, um die Last zu verteilen
  • Flask-Prozesse stürzten weiter ab, daher wurde ein Skript für automatische Neustarts geschrieben

Problem mit veralteten Updates

  • Clients wendeten veraltete Updates an, wodurch der Zustand falsch angezeigt wurde
  • Timestamps wurden hinzugefügt, um die Reihenfolge der Updates sicherzustellen

Neuimplementierung in Go

  • Zusammen mit einem Freund aus dem Performance Engineering wurde das Backend in Go neu geschrieben
  • Die Performance verbesserte sich deutlich
  • DDoS-Angriffe wurden über CloudFlare abgewehrt

Abschaltung der Website

  • Das Verhalten wurde so geändert, dass Checkboxen einfroren, wenn sie nicht schnell genug wieder deaktiviert wurden
  • Der eingefrorene Zustand wurde mit Redis verwaltet
  • Zwei Wochen später wurde die Website abgeschaltet

Erkenntnisse

  • Es war das zweite Mal, dass ein Server mit einem „echten“ Backend ins öffentliche Internet ausgerollt wurde
  • Die Entscheidung für kurzfristige Lösungen war die richtige Wahl
  • Die Stärke von Redis und nginx wurde erneut bestätigt
  • Es zeigte sich, wie groß das Bedürfnis nach Websites ist, auf denen Menschen anonym interagieren können

Zusammenfassung von GN⁺

  • Der Artikel behandelt die technischen Probleme und deren Lösungen, die durch die unerwartete Popularität der Website entstanden
  • Er zeigt, dass sich auch mit einer einfachen Architektur auf Basis von Redis und nginx massiver Traffic bewältigen lässt
  • Er erklärt, wie sich Probleme mit kurzfristigen Lösungen schnell beheben und die Website stabilisieren ließen
  • Er behandelt verschiedene technische Herausforderungen, darunter die Neuimplementierung in Go und die Abwehr von DDoS-Angriffen über CloudFlare
  • Ein ähnliches Projekt ist etwa das groß angelegte kollaborative Projekt /r/Place von Reddit

1 Kommentare

 
GN⁺ 2024-07-28
Hacker-News-Kommentare
  • Man konnte viele Lektionen und historisches Wissen daraus mitnehmen

    • Es wurden zwar alle möglichen Unterbrechungen und Ausfallpunkte behandelt, aber Speicherplatzprobleme wurden nicht erwähnt
    • Ich wusste nicht, dass Redis Lua verwenden kann, und finde es nun interessant, das als Ersatz-Zustandsspeicher zu nutzen
    • Bandbreitenprobleme bei Cloud-Diensten gehören zu den größten Frustpunkten, weil es keine harte Begrenzung gibt, mit der sich eine Überschreitung der Abrechnung vermeiden ließe
  • Ein großartiger Artikel! Glückwunsch auch zur Website, aber auf den Artikel selbst sollte man am stolzesten sein

  • Die Entscheidung, die Website in zwei Tagen zu bauen, war gut

    • Das ist eine wichtige Lektion, die Engineers am Anfang ihrer Karriere lernen sollten
    • Skalierungsprobleme sind erst dann wirklich Probleme, wenn sie tatsächlich auftreten
    • Und dann sind es gute Probleme, die oft nicht so schwer zu lösen sind, wie man denkt
  • Verwandtes Projekt aus jüngerer Zeit:

    • "One Million Checkboxes" - Link - Juni 2024 (305 Kommentare)
  • Ein unterhaltsames Projekt

    • Ich habe vor 6 Jahren auf Android eine kollaborative Pixel-Editing-App namens Pixmap veröffentlicht
    • Mithilfe einer Queue wurde jedes Event auf ein PNG-Bild angewendet, und Clients luden beim Verbinden das initiale PNG
    • Jedes Pixel-Draw-Event wurde als kleines Objekt an die Clients übertragen
    • Der initiale Ladevorgang nutzt Bildkomprimierung, und die Änderungsmengen sind sehr klein
    • Da jedes Event im Log gespeichert wird, kann man das Bild "zurückspulen"
    • Demo-Link
  • Großartiger Artikel – ich frage mich, wie viel das gekostet hat

  • Das bestätigt meinen Glauben daran, dass Menschen nach begrenzter anonymer Interaktion verlangen

  • Als Backend-Anfänger frage ich mich, ob es für dieses Projekt eine einfache alternative Architektur gibt

    • Ich hoffe, es gibt einen einfacheren Weg, eine Million Zustände zu hosten und mit den Clients zu synchronisieren
    • Einige der im Artikel beschriebenen Lösungen waren schwer zu verstehen
    • Lob an den Autor – das Projekt ist großartig
  • Cool!

    • Ich frage mich, ob der nächste Artikel eine statistische Analyse der Checkboxen sein wird
    • Ich erinnere mich daran, traurig gewesen zu sein, weil meine ausgewählte Checkbox fast sofort wieder deaktiviert wurde
  • Ich frage mich, ob das Spiel noch live ist

    • Als ich One Million Checkboxes aufgerufen habe, war nichts angehakt, und in der JS-Konsole erschien nur folgende Meldung
    • {"total":0,"totalGold":0,"totalRed":0,"totalGreen":0,"totalPurple":0,"totalOrange":0,"recentlyChecked":false}