Sonntag, 2. März 2008

Ein unorthodoxer Ansatz für ein Datenbank-Design: Das Aufkommen des Shardings

Quelle: http://highscalability.com/unorthodox-approach-database-design-coming-shard
Autor: Todd Hoff am 31. Juli 2007 18:13
Übersetzung: Sebastian Wallroth

Vor langer, langer Zeit skalierten wir Datenbanken, indem wir immer größere, schneller und teurere Maschinen kauften. Während diese Vorgehensweise tolle fette Gewinnspannen ist, funktioniert es nicht so gut mit den Girokonten unserer heldenhaften Systembauer, die weit mehr skalieren müssen, als sie für gigantische Datenbankserver aufbringen können. In einer außergewöhnlichen zweiteiligen Artikelserie erklärt Dathan Pattishall seine Beweggründe für ein revolutionäres neues Datenbankdesign - Sharding -, über das er nachzudenken begann noch bevor er bei Friendster arbeitete und dann bei Flickr voll implementierte. Flickr verarbeitet heute mehr als 1 Milliarde Transaktionen pro Tag, in weniger als ein paar Sekunden antwortend und bei niedrigen Kosten linear skalieren.

Was ist Sharding und wie wurde es die Antwort auf die Skalierungsprobleme großer Webseiten?

InformationsquellenWas ist Sharding?
Während er an Auction Watch arbeitete kam Dathan die Idee, ihre Skalierungsprobleme zu lösen, indem er einen Datenbankserver für eine Benutzergruppe aufbaute und diese Server auf billigen Linuxkisten laufen ließ. In diesem Schema sind die Daten für den Benutzer A auf einem Server gespeichert und die Daten für Benutzer B auf einem anderen Server. Es ist ein föderatives Modell. Gruppen von 500.000 Benutzern werden zusammen in sogenannten Shards gespeichert

Die Vorteile sind:
  • Hohe Verfügbarkeit. Wenn eine der Kisten abstürzt, können die anderen weiterarbeiten.
  • Schnellere Abfragen. Kleine Datenmengen in jeder Benutzergruppe bedeuten schelleres Durchsuchen.
  • Mehr Schreibbandbreite. Ohne Masterdatenbank, die die Schreibzugriffe serialisiert kann man parallel schreiben, was die Schreibdurchsatz erhöht. Schreiben ist der Hauptengpass für viele Webseiten.
  • Du kannst mehr Arbeit erledigen. Ein paralleles Backend bedeutet, dass Du mehr Arbeiten gleichzeitig erledigen lassen kannst. Du kannst mit mehr Benutzerlast verkraften, insbesondere, wenn Du Daten schreibst, weil es parallele Wege durch das System gibt. Du kannst die Last zwischen den Webservern verteilen, die auf die Shards über verschiedene Netzwerkwege zugreifen, von getrennten CPUs betrieben werden, getrennte RAM-Caches und getrennte IO-Wege verwenden, um die Aufgaben zu bearbeiten. Nur sehr wenige Engpässe begrenzen Deine Arbeit.
Was unterscheidet Sharding von traditionellen Architekturen?
Sharding unterscheidet sich von traditionellen Datenbankarchitekturen in mehreren wichtigen Punkten:
  • Daten sind denormalisiert. Traditionell normalisieren wir Daten. Daten werden über anomaliefreie Tabellen verteilt und dann wieder miteinander verbunden, wenn sie gebraucht werden. Beim Sharding werden die Daten denormalisiert. Man speichert Daten zusammen, wenn sie später zusammen verwendet werden.
    Das bedeutet nicht, dass man Daten auch nach Typ aggregiert. Man kann Benutzerprofile getrennt von deren Kommentaren, Blogs, E-Mails, Medien etc. speichern, aber die Benutzerprofildaten würden als Einheit gespeichert und verarbeitet. Das ist ein sehr schneller Ansatz. Man holt und speichert einfach einen Blob. Man braucht keine Joins und man kann sie mit einem Festplattenzugriff speichern.
  • Daten sind über viele physikalische Instanzen hinweg parallelisiert. Nach althergebrachter Weise werden Datenbanken vertikal skaliert (scale up). Man kauft größere Maschinen, um mehr Power zu kriegen. Mit diesem Ansatz kann man jedoch massiv mehr Arbeit erledigen, weil sie parallel erledigt werden kann.
  • Daten werden klein gehalten. Je größer ein Datenset ist, das ein Server bearbeitet, desto schwerer ist es, intelligent zu optimieren, weil man auf eine so breite Vielfalt von Daten zugreifen muss. Man braucht gewaltige Brocken RAM, die dann nicht mal dazu ausreichen, die Daten zu cachen, wenn man es braucht. Indem man Daten in kleineren Shards isoliert, können die Daten, auf die man zugreift leichter im Cache gehalten werden.
    Kleinere Datensets kann man außerdem leichter sichern, wiederherstellen und verwalten.
  • Daten sind höher verfügbar. Weil die Shards unabhängig sind, schadet eine Fehlfunktion an einem Shard keinem anderen Shard. Und wenn man jeden Shard mit 50% Kapazität laufen lässt, ist es viel einfacher, einen Shard an Ort und Stelle upzugraden. Das Vorhalten mehrerer Datenkopien innerhalb eines Shards hilft außerdem bei Redundanzen und dabei, die Daten mehr zu parallelisieren, so dass mehr Arbeit mit den Daten erledigt werden kann. Man kann einen Shard auch so aufsetzen, dass man eine Master-Slave- oder eine Doppel-Master-Beziehung zwischen den Shards hat, um einzelne Fehlerquellen innerhalb des Shards zu vermeiden. Wenn ein Server abstürzt, kann ein anderer übernehmen.
  • Man braucht keine Replikation. Daten von einem Master-Server zu einem Slave-Server zu replizieren ist ein traditioneller Ansatz für das Skalieren. Daten werden auf den Master-Server geschrieben und dann auf einen oder mehr Slave-Server repliziert. An diesem Punkt können Lese-Operationen von den Slaves übernommen werden, aber alle Schreiboperationen passieren auf dem Master.
    Selbstverständlich wird der Master zum Schreib-Engpass und zur Fehlerquelle. Und wenn die Last zunimmt, nehmen auch die Kosten für die Replikation zu. Replikation kostet CPU, Netzwerkbandbreite und Festplatten-IO. Die Slave fallen zurück und haben veraltete Daten. Die Typen bei YouTube hatten ein großes Problem mit Replikationsoverhead, als sie skalieren wollten.
    Sharding löst das Replikationsproblem klar und elegant.
Einige Probleme mit Sharding
Sharding ist nicht perfekt. Es hat einige Probleme.
  • Rebalancieren von Daten. Was passiert, wenn ein Shard die Speichergröße übersteigt und geteilt werde muss? Sagen wir, einige Benutzer haben ein besonders lange Freundesliste, die die Speicherkapazitäten für den Shard überschreiten. Man muss den Benutzer in einen anderen Shard übertragen.
    Auf einigen Plattformen, mit denen ich gearbeitet habe, war das ein tödliches Problem. Man muss das Datenzentrum von Anfang an korrekt ausbauen, weil das übertragen von Daten von Shard zu Shard eine Menge Downtime verbraucht.
    Rebalancing muss von Anfang an eingebaut sein. Googles Shards werden automatisch rebalanciert. Dafür müssen Datenreferenzen durch so eine Art Naming-Dienst laufen, so dass sie wiedergefunden werden können. So macht es Flickr. Und die Referenzen müssen annullierbar sein, so dass die darunterliegenden Daten übertragen werden können, während man sie benutzt.
  • Daten von multiplen Shards joinen. Um eine komplexe Freundeseite zu bauen oder eine Benutzerprofilseite oder eine Diskussionsseite mit Threads muss mann normalerweise viele verschiedene Daten aus vielen verschiedenen Quellen zusammen ziehen. Mit Sharding kann man nicht einfach eine Abfrage ausführen und alle Daten kriegen. Man muss einzelne Anfragen an die Datenquellen stellen, alle Antworten einsammeln und dann die Seite bauen. Dankenswerterweise ist dieser Prozess wegen Caching und schnellen Netzwerken normalerweise schnell genug, so dass die Ladezeiten der Seiten exzellent sein können.
  • Wie partitioniert man Daten in Shards? Welche Daten tut man in welche Shards? Wo kommen Kommentare hin? Gehören alle Benutzerdaten wirklich zusammen oder nur die Profildaten? Sollten die Mediendaten, IMs und Freundeslisten usw. der Benutzer irgenwo anders hin? Unglücklicherweise gibt es keine einfachen Antworten auf diese Fragen.
  • Weniger Schwung. Die Leute haben Erfahrung mit traditionellen RDBMS-Werkzeugen, so dass es viel Hilfe von außen gibt. Man hat Bücher, Experten, Werkzeugsätze und Diskussionforen, wenn etwas schief läuft oder man sich fragt, wie man ein neues Feature implementiert. Eclipse wird keinen Shard-View haben und man wird keine automatischen Backup- und Wiederherstellungsprogramme für Shards finden. Mit Shards ist man auf sich gestellt.
  • Die Implementierung von Shards wird nicht gut unterstützt. Sharding ist zur Zeit zumeist ein Eigenbau-Ansatz. LiveJournal macht seine Werkzeugsätze verfügbar. Hibernate entwickelt eine Bibliothek, MySQL hat die Unterstützung von Partitionierung hinzugefügt. Aber im Allgemeinen ist es immer noch etwas, was man selbst implementieren muss.

Siehe auch
Kommentar veröffentlichen