Dienstag, 8. Juni 2010

Lesetip: MongoDB: Warum Etsy und Shutterfly auf neue Datenbanken setzen

Marcel Weiß hat auf Exciting Commerce einen interessanten Artikel zum Thema MongoDB: Warum Etsy und Shutterfly auf neue Datenbanken setzen geschrieben, der ein guter Einstieg in hochskalierbare Datenbanken ist.

Mittwoch, 2. Juni 2010

Magento im High Performance Umfeld

Christiane Philipps (CTO), Martin Rothenberger (Head of Engineering) - DailyDeal GmbH

Einsatz von Magento im High Performance Umfeld



Im Rahmen der Social Live Shopping Plattform DailyDeal.de setzt sich die Firma sehr intensiv mit Performance-Anforderungen an die technische Infrastruktur sowie an Magento selbst auseinander. Performance ist einer der kritischsten Faktoren für den Erfolg einer High-Traffic-Anwendung. Auf der anderen Seite ist es nach wie vor ein zu bearbeitendes Thema im Magento-Umfeld, das nicht out of the box gelöst ist, aber im zunehmenden Maße dringender wird, je mehr Shopbetreiber auf Magento umstellen. Philipps und Rothenberg stellen ihre Erfahrungen dar und welche Optimierungsmaßnahmen sie ergriffen haben.

Magento im High Performance Umfeld on Prezi

Freitag, 28. Mai 2010

Ein Leben mit und ohne Magento

[Update 2018-07-11] Volker Pilz hat die Vortragsfolien von Slideshare entfernt. im Web Archiv ist jedoch das Präsentationstranskript einsehbar

Volker Pilz und Daniel Nowak, Senior Software Developer bei zalando:

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

Samstag, 12. Januar 2008

Twitter skalieren: Wie man Twitter 1.000 Prozent schneller macht

Original: http://highscalability.com/scaling-twitter-making-twitter-10000-percent-faster
Autor: Todd Hoff am 10. Agust 2007 21:01
Übersetzung: Sebastian Wallroth

Twitter begann als Nebenprojekt und wuchs schnell an, von 0 auf Millionen Pageviews in erschreckend wenigen Monaten. Frühe Design-Entscheidungen, die im Kleinen gut funktionierten schmolzen unter dem Andrang neuer Benutzer, die Piepse zu all ihren Freunden zwitscherten. Der Web-Liebling Ruby on Rails wurde früh für die Skalierungsprobleme verantwortlich gemacht, aber Blaine Cook, Twitters Hauptarchitekt, hält Ruby für schuldlos:
Für uns geht es wirklich um horizontales Skalieren - auf dieser Seite waren Rails und Ruby nicht die Stolpersteine, verglichen mit anderen Sprachen und Frameworks. Die Leistungssteigerung, die mit “schnelleren” Sprachen assoziiert wird, hätte uns 10-20% Verbesserung gebracht, aber Dank der Architektur-Änderungen, die Ruby und Rails glücklicherweise beinhaltet, ist Twitter im August 2007 1.000% schneller, als es im Januar 2007 war.

Wenn Ruby on Rails nicht Schuld war, wie lernte Twitter immer höher und höher zu skalieren?

Website: http://twitter.com

Informationsquellen
Die Plattform
  • Ruby on Rails
  • Erlang
  • MySQL
  • Mongrel - Ein hybrider Ruby/C-HTTP-Server, designed, klein, schnell und sicher zu sein
  • Munin
  • Nagios
  • Google Analytics
  • AWStats - Echtzeit-Logdatei-Analysierer für erweiterte Statistiken
  • Memcached
Die Fakten
  • Mehr als 350.000 Benutzer. Die tatsächliche Anzahl ist wie immer, sehr sehr super geheim.
  • 600 Aufrufe pro Sekunde.
  • durchschnittlich 200-300 Verbindungen pro Sekunde. Spitzen bis zu 800 Verbindungen pro Sekunde.
  • MySQL verarbeitet 2.400 Aufrufe pro Sekunde.
  • 180 Rails-Instanzen. Verwendet Mongrel als "Web"-Server.
  • 1 MySQL Server (eine große 8-Kern-Box) und einen Slave. Der Slave ist nur zum lesen für Statistiken und Reporting.
  • 30+ Prozesse für die Behandlung von Sonderaufträgen (odd jobs).
  • 8 Sun X4100s.
  • Ein Aufruf wird in Rails innerhalb von 200 Millisekunden verarbeitet.
  • Die durchschnittliche Verarbeitungszeit in der Datenbank liegt bei 50-100 Millisekunden.
  • Über 16 GB Memcached.
Die Architektur
  • Lief vor aller Augen in Skalierungsprobleme. Eine Zeit lang traten immer wieder Fehler auf.
  • Ursprünglich hatten sie kein Monitoring, keine Diagramme, keine Statistiken, was es schwer machte, die Probleme festzumachen und zu lösen. Munin und Nagios wurden hinzugefügt. Es gab Schwierigkeiten damit, die Tools unter Solaris zu verwenden. Sie hatten Google Analytics, aber die Seiten wurden gar nicht geladen, so dass das nichts brachte :-)
  • Verwendet Caching mit Memcached ausgiebig.
    • Wenn zum Beispiel der Aufruf eines Zählers langsam wird, kann man den Zähler in Millisekunden in Memcache memoisieren.
    • Die Status der Freund zu erhalten ist schwierig. Es gab Sicherheits- und andere Herausforderungen. Anstatt eine Datenbanksuche auszuführen, wird der Freundesstatus im Cache erneuert. Das gibt einen vorhersagbaren Antwortzeitrahmen (Obergrenze 20 Millisekunden).
    • ActiveRecords-Objekte sind gewaltig, weshalb sie nicht gecached werden. Also wollen sie kritische Attribute in einem Hash speichern und die anderen Attribute bei Bedarf per Lazy loading holen.
    • 90% der Anfragen sind API-Abfragen. Also mach kein Seiten/Abschnitts-Caching im Frontend. Die Seiten sind so zeitempfindlich, dass nichts Gutes dabei herauskommt. Aber sie cachen API-Abfragen.
  • Messaging
    • Verwende Messaging ausgiebig. Produzenten produzieren nachrichten, die in Warteschlangen warten und dann an die Kunden ausgeliefert werden. Twitters Hauptfunktionalität ist es, als eine Nachrichtenbrücke zwischen verschiedenen Formaten (SMS, Web, IM, etc.) zu agieren.
    • Sende eine Nachricht, um die Cache des Freundes im Hintergrund zu leeren, anstatt alles einzeln gleichzeitig zu machen.
    • Gestartet mit DRb (Distributed Ruby). Eine Bibliothek, die Dir erlaubt Nachrichten von ferngesteuerten Ruby-Objekten (remote Ruby objects) via TSP/IP zu senden und zu empfangen. Aber es funktionierte irgendwie komisch und war eine Fehlerwuelle.
    • Umstellung auf Rinda, eine gemeinsam genutzte Warteschlange, die ein Tuple space-Modell im Rahmen von Linda verwendet. Aber die Warteschlangen sind persistent und die Nachrichten gehen im Fehlerfall verloren.
    • Erlang wurde getestet. Problem: Wie kriegt man einen abgestürzten Server am Sonntag zum Kaufen, wenn 20.000 Benutzer warten? Der Entwickler wusste es nicht. Nicht viel Dokumentation. Also bedrohte es den Betrieb - was tödlich ist.
    • Umstellung auf Starling, eine in Ruby geschriebene verteilte Warteschlange.
    • Verteilte Warteschlangen wurde geschaffen, um Systemabstürze zu überleben, indem sie auf die Festplatte geschrieben werden. Andere große Webseiten verwenden diesen einfachen Ansatz ebenfalls.
  • SMS werden mittels einer von einer Drittpartei bereitgestellten API verwendet. Ist sehr teuer.
  • Deployment
    • Sie untersuchen und installieren neue Mongrel Server. Kein sehr schöner Weg.
    • Dem Benutzer wird ein interner Serverfehler angezeigt, wenn die Mongrel Server ersetzt werden.
    • Alle Server werden zeitgleich abgeschossen. Ein rollender Ausfall wird nicht angewandt, weil der Status der Nachrichtenschlange in Mongrels steckt und ein rollierender Ansatz die Warteschlangen dazu bringen würde, die verbleibenden Mongrels überlaufen zu lassen.
  • Missbrauch
    • Eine Menge Downtime weil Leute durch die Seite surfen und jedermann als Freund hinzufügen. 9.000 Freunde in 24 Stunden. Das würde die Seite abstürzen lassen.
    • Baue Werkzeuge, um diese Probleme anzuzeigen, so dass man genau festmachen kann, wann und wo sowas passiert.
    • Sei unbarmherzig. Lösche deren Benutzeraccounts.
    Partitionierung
    • Es gibt Pläne für eine zukünftige Partitionierung. Zur Zeit machen sie das nicht. Diese Änderungen haben bisher gereicht.
    • Das Partitionierungsschema wird auf Zeit basieren, nicht auf Benutzern, weil die meisten Anfragen zeitlich eng begrenzt und nur lokal auftreten.
    • Partitionierung wird schwierig sein wegen der automatischem Memoisation. Sie können nicht garantieren, das Nur-Lesen-Operationen wirklich nur-lesend sein werden. Sie könnten auf einen Nur-Lesen-Slve schreiben, was wirklich schlecht ist.
  • Twitters API-Traffic ist zehnmal größer als der Seiten-Traffic
    • Deren API ist das wichtigste, was Twitter gemacht hat.
    • Den Dienst zu halten erlaubt den Entwicklern auf der Infrastruktur aufzubauen und mit Ideen zu kommen, die besser sind als das, was Twitter selbst einfallen würde. Twitterific zum Beispiel, ein wundevollerer Weg, Twitter zu nutzen, als ein kleines Team mit anderen Prioritäten erstellen könnte.
  • Monit wird verwendet, um Prozesse abzuschießen, wenn sie zu groß sind.

Gelernte Lektionen
  • Sprich mit der Community. Verstecke dich nicht und versuche nicht, Probleme selber zu lösen. Viele hervorragende Leute sind bereit zu helfen, wenn Du fragst.
  • Behandle Deinen Skalierungsplan wie einen Geschäftsplan. Stelle ein Beratergremium zusammen, das Dich unterstützt.
  • Mach es selbst. Twitter verbrachte viel Zeit damit, anderer Leute Lösungen auszuprobieren, die fast zu funktionieren schienen, aber dann doch nicht ausreichten. Es ist besser, einige Dinge selber zu bauen, so dass man immerhin etwas Kontrolle behält und man kann die Features einbauen, die man braucht.
  • Baue Benutzerbeschränkungen ein. Die Leute werden versuchen, Dein System kaputt zu machen. Baue vertretbare Beschränkungen und Warnmelder ein, um Dein System davor zu beschützen, abgemurkst zu werden.
  • Mach die Datenbank nicht zum zentralen Flaschenhals des Untergangs. Nicht alles erfordert einen gigantischen Join. Cache Daten. Denk über andere kreative Wege nach, um dasselbe Ergebnis zu erhalten. Ein gutes Beispiel wird in Twitter, Schienen, Hämmer und 11.000 Nägel pro Sekunde beschrieben.
  • Mach Deine Applikation von Start weg partitionierbar. Dann wirst Du immner einen Weg haben, Dein System zu skalieren.
  • Wenn Du merkst, dass Deine Seite langsam ist, füge sofort ein Reporting hinzu, um die Probleme analysieren zu können.
  • Optimiere die Datenbank.
    • Indiziere alles. Rails macht das nicht für Dich.
    • Versuche mal zu erklären, was deine Abfragen (queries) machen. Die Indexe könnten anders sein, als Du erwartest.
    • Denormalisiere viel. Kleinlichkeit nützte ihnen. Zum Beispiel speichern sie alle Benutzer-IDs zusammen mit den IDs der Freunde, was ihnen eine Menge aufwändiger Joins erparte.
    • Vermeide komplexe Joins.
    • Vermeide das Scannen großer Datenmengen.
    Cache verdammt noch mal alles. Individuelle aktive Einträge werden derzeit noch nicht gecached. Testabfragen sind zur Zeit noch schnell genug.
  • Teste alles.
    • Du willst wissen, wenn Du eine Applikation ausrollst, dass sie richtig funktionieren wird.
    • Sie haben jetzt eine komplette Testsuite. Wenn das Caching nicht funktioniert, dann sind sie in der Lage den Fehler zu finden, bevor sie Live gehen.
  • Lange laufende Prozesse sollten zu Daemons abstrahiert werden.
  • Verwende Ausnahme-Melder und Ausnahme-Logger, um sofort über Probleme benachrichtigt zu werden, so dass Du korrekt reagieren kannst.<
  • Mach keine Dummheiten.
    • Skalieren bedeutet, dass vorher richtige Vorgehensweisen jetzt bescheuert sind.
    • Zu versuchen 4.000 Freunde auf einmal in den Speicher zu laden, kann den Server zum Absturz bringen, aber wenn da nur 4 Freunde sind, funktioniert es großartig.
  • Die meiste Leistung kommt nicht von der Sprache, sondern vom Anwendungsdesign.
  • Mach aus Deiner Webseite einen offenen Dienst, indem Du einen API baust. Ihre API ist ein gewaltiger Grund für Twitters Erfolg. Es erlaubt Benutzern ein immer weiter expandierendes Ökosystem um Twitter herum aufzubauen, so dass es schwierig ist, mit ihm zu konkurrieren. Du kannst niemals all die Arbeit machen, die Deine Benutzer machen und Du wirst wahrscheinlich niemals so kreativ sein. Also öffne Deine Anwendungen und mach es Anderen einfach, ihre Anwendungen mit Deinen zu verbinden.


Verwandte Artikel

technorati skalieren - 100 Millionen täglich indizierte Blogs

Original: http://www.royans.net/arch/2007/10/25/scaling-technorati-100-million-blogs-indexed-everyday/
Autor: Royans Tharakan
Übersetzung: Sebastian Wallroth

Mit der Indizierung von 100 Millionen Blogs mit über 10 Milliarden Objekten und einer Benutzerbasis, die sie alle sechs Monate verdoppelt, ist technorati den meisten anderen Blog-Suchmaschinen weit voraus. Aber technorati ist viel mehr als nur eine Suche und jeder technorati-Benutzer kann Dir das erläutern. Ich empfehle, John Newtons Interview mit David Sifry zu lesen, dass ich faszinierend fand. Hier ein paar Höhepunkte aus diesem Interview, wenn Du nicht die Zeit hast, das ganze Ding zu lesen.

Gegenwärtiger Stand von technorati

  • 1 Terabyte Inhalt kommen pro Tag hinzu
  • 100 Millionen Blogs
  • 10 Milliarden Objekte
  • 0,5 Milliarden Fotos und Videos
  • Datenverdopplung alle sechs Monate
  • Benutzerverdopplung alle sechs Monate

Die erste Version war dafür vorgesehen, für eine gewisse Zeit für wenig Geld Informationen zu tracken.

  • Diese Version tat alles in eine relationale Datenbank, was ausreichte, solange die Größe des Indexes kleiner war als der physikalische Speicher
  • Es funktionierte gut bis etwa 20 Millionen Blogs

Die nächste Generation zog Vorteil aus der Parallelisierung.

  • Die Daten wurden in Shards aufgebrochen
  • Die Daten wurden häufig zwischen den Servern synchronisiert
  • Die Datenbankgröße erreichte die größte bekannte OLTP-Größe.

    • Daten Schreiben und Lesen hielten sich sie Waage
    • Die Verwaltung der Datenintegrität war wichtig

      • So kam viel Druck auf das System



Die dritte Generation

  • Die Shards entwickelten sich weiter

    • Die Shards basierten jetzt auf Zeiten statt auf URLs
    • Inhalte wurden in spezielle Datenbank verschoben, anstatt sie in einer relationalen Datenbank zu halten

  • Nichts wurde gelöscht
  • Es wurden nur Shards bewegt und für Hinzugekommenes wurden neue Shards verwendet

Verwendete Werkzeuge

  • Green Plum - ermöglicht Firmen, für eine genaue Analyse schnell auf große Mengen kritischer Daten zuzugreifen. Entworfen für hohe Leistung und groß skalierende Business Intelligence besteht Greenplums Familie von Datenbankprodukten aus Lösungen für Installationen von Abteilungs-Datamarts bis zu Multi-Terabyte-Data Warehouses.

Hätte früher gemacht werden sollen

  • Man hätte sich für Klickstromanalyse-Software interessieren sollen, um zu analysieren, was Klicks mit den Benutzern

    • Aussagen, wieviel Zeit die Benutzer mit einem Feature zubringen

Samstag, 17. November 2007

Architekturen, über die Du dich schon immer gewundert hast: Was man auf der QCon lernen konnte

Original: http://natishalom.typepad.com/nati_shaloms_blog/2007/11/lessons-from--1.html 15. November 2007
Autor: Nati Shalom
Übersetzung: Sebastian Wallroth

Ich bin gerade von QCon in San Francisco zurückgekehrt. Mir hat die Konferenz wirklich gefallen. Die Präsentationen und Panels waren von hoher Qualität. Mir hat auch die Tatsache gefallen, dass es persönlich genug war, um interessante Personen aus der Wirtschaft zu treffen. Mit gefiel insbesondere die Diskussion mit Brian Zimmer von Orbitz, wo man Jini als Teil des Backbones verwendet, wie auch mit Randy Shoup (eBay), der am Freitag eine exzellente Präsentation über die eBay-Architektur gab. Ein "Gut gemacht!" geht an Floyd und Trifork (Aino, Roxanne und der Rest des Teams) für die Organisation dieses Ereignisses.

Im Track "Architekturen, über die Du dich schon immer gewundert hast" präsentierten Second Life, eBay, Yahoo, LinkedIn und Orbitz, wie sie mit den verschiedenen Aspekten ihrer Anwendungen umgehen, wie zum Beispiel der Skalierungsfähigkeit. Es sind einige Lektionen, die ich gelernt habe und die ich gerne teilen möchte.

Diclaimer: Die nachfolgenden Informationen basieren auf Notizen, die ich während der Sitzungen machte. Es handelt sich nicht um detaillerte Berichterstattungen der einzelnen Präsentationen sondern vielmehr um die Zusammenfassungen meiner persönlichen Interpretationen und Schlussfolgerungen. Lesen sie gerne auch die Präsentationen des Tracks "Architekturen. über die Du dich schon immer gewundert hast" im Original.

Der Stack

Dieses Thema scheint ganz schön emotional zu sein, hauptsächlich zwischen dem LAMP- und dem Java-Lager, wie ich erfahren musste, nachdem ich "Warum die meisten hochskalierten Webseiten nicht in Java geschrieben sind" veröffentlicht hatte. Obgleich der LAMP-Stack in im Bereich hochskalierter Webanwendungen sehr populär ist sind die Umgebungen sehr heterogen, insbesondere bei den großen Seiten: Yahoo und eBay natürlich und teilweise gilt das auch für Google und Amazon. Tatsächlich verwendet eine Anwendung von Google GigaSpaces. Eine offensichtliche Erklärung für diese Heterogenität ist der Fakt, dass viele der großen Seiten verschiedene Firmen übernommen und integriert haben, wovon jede ihre eigenen Implementierungsstack mitbrachte.

Es gibt nur einige wenige (LinkedIn, eBay, Orbitz, Yahoo Bix) die Java als ihre Kernsprache verwenden. (Beachte, dass die meisten Anwendungen von Yahoo LAMP als ihre Kern-Stack verwenden. Yahoo Bix ist eine Ausnahme.) Der Linux-Apache-Tomcat-Spring-Hibernate-Stack ist üblich bei den Java verwendenden Seiten. Wenn ich mich recht erninnere verwendet nur eBay den kompletten J2EE-Stack, aber eBay scheint nur einen kleinen Teil von dessen Funktionalität zu verwenden. Second Life hat eine ziemlich ungewöhnliche Architektur: man benutzt dort zumeist C++ und Python und sagte, dass man der Skalierungsfähigkeit wegen zu Web Services und SOA migrieren will. Bei Orbitz verwendet man Jini als Dienste-Framework und hat interessante Dinge mit Spring angestellt, um Jini für seine Entwickler zu vereinfachen. Man hat dort zudem mit Spring Remote-Funktionalität entwickelt, um die Dienste-Interaktion zu vereinfachen.

Integrationstrategie

Integration ist eine große Aufgabe für all diese Seiten, wenn aufgekaufte Firmen integriert werden. Im Falle von eBay und Yahoo hatten die Firmen, die sie gekauft hatten ganz andere Architekturen und in vielen Fällen auch andere Implementierungs-Stacks. Ihre Methode ist, sich nicht in die Implementierungsdetails einzumischen (wenigstens nicht zu Anfang), sondern sich auf eine schnelle Integation zu konzentrieren -- mit dem Endkunden im Blick. Sowohl Yahoo als auch eBay bauten ein allgemeines Framework, um diesen Integrationsanforderungen Genüge zu tun. Großen Aufwand kostete die Ermöglichen eines allgemeinen Benutzeridentifizierungssystems (Single Sign-On) wie auch ein Lastverteilungsschema. Bei eBay wählte man Apache als allgemeines Modul und erweiterte es ein bisschen mit eigenen Modulen. Yahoo baute einen Identifizierungsverwaltungsdienst, der auf Erweiterungsfähigkeit ausgelegt ist. Erweiterbarkeit meint hier die Möglichkeit der Anwendungen ihre eigenen Daten dem Benutzerprofil hinzuzufügen, dass dann für Personalisierung und andere Zwecke verwendet werden kann.

Anwendungsarchitektur

Niemanden wird überraschen, dass diese Anwendungen in einer schichtbasierten Architektur aufgebaut sind. Wenn man dort über Partitionierung spricht, meint man im Allgemeinen die Datenschicht.

Die Datenbankschicht

MySQL ist definitiv die beliebteste Datenbank. Es ist interessant (und überraschend) zu entdecken, wieviele Ressourcen Organisationen wie eBay und Google in die Erweiterung von MySQL gesteckt haben und es erfreut zu sehen, dass sie diese Erweiterungen der MySQl-Gemeinschaft übereignet haben. Nach Dan Pritchett (eBay) kann man eBay Erweiterungen mit MySQL dast dasselbe anstellen wie mit der Datenbank von Oracle. In "Die Zukunft ist wolkig" erfährt etwas man über den Kontext der MySQL-Erweiterungen von Google. Die Oracle-Datenbank wird weiterhin von einigen Seiten genutzt, aber überlicherweise gleichzeitig auch MySQL.

Die meisten Seitenbetreiber sagten, dass sie ihre Daten im Speicher hielten, um den Ein-/Auslese-Overhead der Datenbank zu minimieren. Das tun sie jedoch nur für Szenarios mit überwiegend Leseoperationen. Einer der Vortragenden (ich glaube es war Dan Pritchett) meinte dass der Grund für den begrenzten Gebrauch des Cachings in der Natur der Datenverwendungsmuster liege. Jeder ihrer Server könne jederzeit jedes Datum ohne bestimmte Reihenfolge anfordern. Weil die Datenvolumen mit denen sie es zu tun haben so gewaltig sind, können sie sie nicht komplett im Speicher halten. Die inkonsistenten Datenverwendungsmuster ihrer Anwendungen minimieren das Potenzial der Leistungsgewinne, die im Caching liegen.

Ich denke diese Aussage sollte erneut untersucht werden, weil es auf diesem Gebiet in den letzten Jahren große Fortschritte gegeben hat, die viele der Voraussetzungen ändern, die derzeit hier in Betracht gezogen werden (aber das ist ein anderes Thema). Viele Seiten benutzen Memcached als ihre Cachingschicht. Beispielsweise gibt es in dieser Studie über die Architektur von TypePad Hinweise darauf, dass Memcached verwendet wird, um Zähler, Sets, Status und heavyweight Daten zu speichern.

Benachrichtigungsschicht

Bei der Ermöglichung von Skalierbarkeit gibt es einen Trend weg von synchronen RPC-Amsätzen hin zu asynchroner Kommunikationen (Ich gehe später darauf ein, wenn ich mich der Skalierbarkeit zuwende.) Man könnte glauben, dass JMS überall verwendet wird um diese Anforderung zu erfüllen. Es scheint aber, dass fast jeder Vortragende sagte, dass sie ihren eigenen Banchrichtigungsstack gebaut hätten. Die Gründe scheinen zu sein:
  • Die Anforderungen für effiziente inhaltsbasierte Benachrichtigungen: Der erforderliche Benachrichtigungstyp ist weder direkt Punkt-zu-Punkt noch pub/sub. Er ist mehr assoziativer Natur. Es ist eine häufige Anforderung, dass man erst die Nachricht ansehen und durch sie browsen will, bevor man sich entscheidet, ob man sie auswählen will (und die JMS-Auswahloberfläche ist genau darauf beschränkt)
  • Konsistenz: Um Teilfehler und die Notwendigkeit verteilter Transaktionen zu vermeiden speichert man seine Events in der selben Partition wie die Daten. Auf diese Art kann man sicherstellen, dass die Nachrichten in die selbe PArtition wie die Daten geleitet werden (und vermeidet verteilte Transaktionen)
  • Man konnte diese Schicht basierend auf spezifischen Anforderungen und Semantiken feinjustieren
LinkedIn bezeichnet diesen Benachrichtigungstyp als "Datenbus" - eine sehr passende Bezeichnung.

Das erinnert mich an den ursprünglichen Grund für mein Interesse an JavaSpaces als ich an einem B2B-Exchange arbeitete und ähnliche Anforderungen hatte. JavaSpaces macht genau das. Es bietet beispielsweise einen Datenbus, der sowohl Benachrichtigungen und Daten in einer einzigen konsistenten Implementierung kombiniert.

An Skalierbarkeit nicht erst nachher denken

Ein Botschaft, die während der Konferenz von fast allen Architekten immer wieder verkündet wurde, lautete, dass an Skalierbarkeit nicht erst nachher gedacht werden sollte. Während ich mit dieser Aussage übereinstimme, enthüllten alle Fallstudien auf der QCon eine interessante Tatsache: Die meisten der beschriebenen Seiten wurde ursprünglich nicht aus Skalierbarkeit ausgelegt (es gibt eine berühmte Geschichte, dass eBay als einzelne DLL-Datei gestartet sei). Trotzdem schienen alle in der Lage gewesen zu sein, durche mehrere Zyklen der Erneuerung der Architektur zu gehen, wann immer Skalierbarkeit ein großes Problem wurde. KAnn man daraus etwas lernen?

Meiner Ansicht nach werden , weil heutige Ansätze für Skalierbarkeit einen riesigen Grad an Komplexität aufweisen (nicht zu vergessen, dass viele Entwickler Skalierbarkeit nicht richtig verstehen), Skalierbarkeit und Time-to-Market als zwei sich widersprechende Ziele angesehen. Mit anderen Worten, der Versuch eins davon zu erreichen wird als ein Riskieren des anderen angesehen. Die Lehre könnte darum sein, dass man Skalierbarkeit nicht gleich vom ersten Tage an implementieren muss, sondern, dass man sich bewusst machen muss, was Skalierbarkeit bedeutet. Auch wenn man Kompromisse eingeht, um die Anforderungen der Time-to-Market zu berücksichtigen muss vorausplanen, um zur rechten Zeit umstellen zu können.

Werner Vogel (Amazon CTO) drückte ein ähnliches Gefühl aus als er sagte: "Skaliere später. Es ist soooo schwierig es richtig zu machen, dass manchmal der Aufwand es vorher zu erledigen nicht gerechtfertigt ist. Oder überlasse es jemandem, der die Kenntnisse besitzt und es bereits getan hat ... wie Amazon (denke an S3 - Virtual Disk, etc.)."

Skalierbarkeit -- Wie man es richtig macht

Und hier kommt, worauf Du gewartet hast:
  • Asynchrone ereignisgesteuerte Entwürfe: Vermeide so gut es geht synchrone Interaktion mit der Daten- oder der Geschäftslogikschicht. Stattdessen verwende einen ereignisgesteuerten Ansatz und Workflow
  • Partitionierung/Shards: Man muss das Datenmodell so modellieren, dass es mit dem Partitionerungsmodell zusammenpasst
  • Gleichzeitige Ausführung: Gleichzeitige Ausführung sollte genutzt werden, um so viel wie möglich aus den verfügbaren Ressourcen herauszuholen. Ein guter Platz für gleichzeitige Ausführung ist die Verarbeitung der Benutzeranfragen. In diesem Fall können mehrfache Instanzen der Dienste die Anfragen vom Benachrichtigungsdienst entgegennehmen und sie gleichzeitig ausführen. Ein anderer Anwendungsfall für gleichzeitige Ausführung ist die Verwendung von MapReduce für die Ausführung aggregierter Anfragen auf partitionierter Daten.
  • Replikation (vorwiegend lesender Zugriff): In Szenarios mit vorwiegend lesenden Zugriffen (LinkedIn scheint in diese Kategorie zu fallen) kann Datenbankreplikation helfen, die Lese-Last zu verteilen, indem man Lese-Anfragen zwischen den replizierten Datenbankknoten verteilt
  • Konsistenz ohne verteilte Transaktionen: Das war einer der Hauptpunkte der Konferenz, der auch während eines Panels, an denen ich teilnahm, die Funken sprühen ließ. Ein Argument war, dass man, um Skalierbakeit zu erreichen, die Konsistenz opfern müsse und die Konsistenz in Anwendungen sicherstellen müsse mittels solcher Dinge wie optimistic locking und asynchroner Fehlerbehandlung. Man nimmt außerdem an, dass man Idempotenz im Code abhandeln muss. Meiner Meinung nach erzeugt dieses Softwaremuster zur Verbesserung der Skalierbarkeit zusätzliche Komplexität und ist deshalb fehleranfällig. Während eines anderen Panels behauptete Dan Pritchett, dass es Wege gäbe, diesen Grad von Komplexität zu vermeiden und trotzdem das gleiche Ziel zu erreichen, wie er es in seinem Blogartikel beschreibt.
  • Schiebe die Datenbank in den Hintergrund - Es bestand eine starke Einstimmigkeit darüber, dass die Datenbankengstelle nur behoben werden kann, wenn die Datenbankinteraktionen im Hintergrund stattfinden
Um noch einmal Werner Vogel zu zitieren: "Um zu skalieren: Kein direkter Zugriff mehr auf die Datenbank. Stattdessen ist der Datenzugriff in Diensten eingekapselt (Code und Daten zusammen), mit einer stabilen, öffentlichen Schnittstelle."

Andere Tips
  • Yahoo Bix - entwickelte einen Netzwerk-Sniffer, um Datenbankaufrufe zu überwachen und die Verwendung von Hibernate zu optimieren. Das stellt eines der interessanten Tauschgeschäfte in der Datenbankabstraktionsschicht dar: indem man abstrahiert, was hinter den Kulissen passiert, erlaubt man den Entwicklern sozusagen nichtoptimierten Code zu schreiben. Der Sniffer-Ansatz hilft herauszufinden, was hinter den Kulissen passiert und verwendet diese Informationen, um den Code von Hibernate zu optimieren.
  • LinkedIn - verwendet Lucene (und nicht die Datenbank) für die Indizierung. Wenn man nach einem effizienten Weg sucht, Indizierung und Suche in den Indexen zu betreiben, ist eine Datenbank wahrscheinlich nicht das Mittel der Wahl. Lucene bietet eine viel effizientere Implementierung für diese Zwecke. Ich würde auch empfehlen, Compass zu verwenden. Und hier kommen brandheiße Neuighkeiten: Ich habe gerade von Shay Banon, dem Besitzer des Compass-Projektes erfahren, dass er an einer Lucene-Integration in einen im Speicher geclusterten Index (GigaSpaces nutzend) arbeitet. Das ist sehr spannend, weil das ermöglichen wird, einen Lucene-Index verteilt zu speichern. Es wird außerdem ermöglichen, den Inhalt einer Webseite zu indizieren und eine Google-artige Suchanfrage zu stellen!
Zusammenfassung: Tauschhandel zwischen Komplexität und Time-to-Market

Die für Skalierbarkeit überwiegend verwendeten Softwaremuster führen zu mehr Komplexität. Beispielsweise muss man mit Teil-Fehler-Szenarios umgehen und Idempotenz im Code abhandeln. Das führt zu einem hohenGrad von Komplexität und ist der Hautpgrund, warum die meisten Architekten und Entwickler mit einfacheren Ansätzen beginnen, die nicht sklaierbar sind, wohl wissend, dass sie später einen kompletten Neuentwurf ihrer Anwendung machen müssen, um den Anforderungen gerecht zu werden. Second Life hielt einen ganzen Vortrag zu diesem Thema.

Ich sehe unsere Herausforderung bei GigaSpaces darin, diesen Widerspruch soweit wie möglich zu eleminieren, indem wir Skalierbarkeit zu einfach wie möglich machen, so dass Skalierbarkeitssoftwaremuster von Anfang an einfach implementiert werden können und so dem Geschäft ermöglicht wird auf die erforderliche inkrementelle Art zu wachsen. Das war tatsächlich der Hauptpunkt meiner Präsentation auf der QCon mit dem Titel "Drei Schritte um eine schichtenbasierte Ursprungsanwendung in dynamisch skalierbare Dienste umzuwandeln." Ich werde mehr Details zu diesem Ansatz in zukünftigen Artikeln beschreiben.

Samstag, 10. November 2007

Vertikales UND horizontales Skalieren - ein Kompromiss

Autor: Jeremy Cole
Übersetzung: Sebastian Wallroth

Du wirst bemerkt haben, dass es derzeit eine (überwiegend kultivierte) Debatte über RAID und Skalierung gibt:
Ich möchte einige der - meiner Meinung nach - falschen Vorstellungen über "horizontales Skalieren" aufgreifen, die ich immer wieder gefunden habe und biete meine Erfahrungen und Meinungen an.

Es geht um Kompromisse.

Arbeitszeit ist teuer. Wenn man Operations, IT usw. mit Aufgaben betraut (wie die Wiederherstellung einer Maschine), wenn man ein Problem löst, dass man mit einem Plattentausch in 30 Sekunden erledigen könnte, dann nenne ich das ineffiziente Nutzung menschlicher Arbeitskraft. Nimm keine Abkürzung, wo es keinen Sinn ergibt. Das bezieht sich auf Brians Kommentare über die realen Kosten des defekten 200$-Teils.

Horizontales Skalieren bedeutet nicht, dass man Billighardware benutzt. Ich glaube die Leute treiben das horizontale Skalierungsmodell (über das sie oft nur in veralteten Konferenzpräsentationen lesen) zur sehr auf die Spitze. Sie glauben, horizontales Skalieren bedeute die Verwendung schlechter Hardware aus dem Desktopbereich und kaufen Tonnen davon. Das funktioniert nicht und es ist die Hölle, das auf lange Sicht zu verwalten.

Kompromiss. Einer der Hauptpunkte des horizontales Skalierungsmodells: dimensioniere die physikalische Hardware sinnvoll um den besten Kompromiss zwischen horizontalem und vertikalem Skalieren zu finden. Das ist der Hauptgrund, warum ich nicht glaube, dass RAID nicht von uns geht... Es ist oft einfach der beste und kostengünstigste Weg die Leistung und Verlässlichkeit zu erreichen, die man auf jeder physikalischen Maschine braucht, damit das Skalierungsmodell funktioniert.

Verwende normale Hardware. Oft hört man den Begriff "normale Hardware" im Zusammenhang mit horizontaler Skalierung. Während mistige Hardware durchaus auch normal ist, ist eigentlich gemeint, dass wenn man mit einer low-end $40k-Maschine feststeckt und mit dem Gedanken auf ein Upgrade auf eine $250k- und später vielleicht auf eine $1M-Maschine spielt, man Datenverteilung (data partitioning) und einige, nun ja, $5k-Maschinen verwendet. Es ist keine $1k-1-Festplatte-Mist-Maschine gemeint, wie ich bereits sagte. Was ist nun mit einer "normalen" Maschinen gemeint? Nun, eine Maschine mit standardisierten, üblichen Komponenten, bei der der Preis vom Markt und nicht von einer einzelnen Maschine festgelegt wird. Man verwende normale Hardware mit einem ausgewogenen Preis-Leistungsverhältnis.

Verwende Datenverteilung (Sharding). Ich habe hierüber in meinen vorhergehenden Beiträgen nicht viel geschrieben, weil es eine Art Selbstverständlichkeit ist. Mein Teilnahme am HiveDB-Projekt und meine kürzlichen Vorträge über "Skalierfähige und hochverfügbare Architekturen" auf der MySQL-Konferenz und -Expo sollten genug über meinen Standpunkt zu diesem Thema sagen. Trotzdem will ich ein paar Punkte aus meinen Vorträgen wiederholen: Datenverteilung ist das einzig Wahre, Cache alles und verwende MySQL-Replikation für Hochverfügbarkeit und Redundanz.

Trotzdem. RAID ist preiswert. Ich habe das bereits ein paar Mal gesagt, nur um sicherzustellen, dass man mich richtig versteht: RAID ist ein preiswerter und effizienter Weg um sowohl Leistung als auch Verlässlichkeit von normaler Hardware sicherzustellen. Für die meisten Systeme ist es wegen der IT- und Operationszeit viel teurer Verlässlichkeit auf nicht-RAID-Systemen zu erreichen als auf RAID-Systemen. Ja, andere Komponenten werden kaputtgehen, aber in einem ausreichend großem datenzentrierten System mit guter Serverhardware werden Festplatten zehnmal öfter kaputtgehen als irgendetwas anderes.

Das ist alles. Weitermachen.

Sonntag, 4. November 2007

Das uneindeutig unklare Duo: Horizontales Skalieren und Vertikales Skalieren

Original: http://jpipes.com/index.php?/archives/175-The-Ambiguously-Vague-Duo-Scale-Out-and-Scale-Up.html= 25. Juni 2007 17:30
Autor: Jay Pipes
Übersetzung: Sebastian Wallroth

So, eine Anzahl von Leuten verlangte ein paar mehr Informationen, als in der an CIOs gerichteten MySQL-Marketing-Kampagne von neulich angeboten wurden: "Die zwölf Tage des MySQL Scale-out". Ich wollte einen Blog-Artikel schreiben, der sich der nach Inhalten lechzenden MySQL-Community annimmt, in dem ich diskutiere, was genau der Begriff "scale-out" (horizontales Skalieren) bedeutet.

Vergleiche zwischen horizontalem im Unterschied zu vertikalem Skalieren

Was ist überhaupt Skalieren? Einfach ausgedrückt ist es die Fähigkeit einer Anwendung wachsende Anforderungen an Durchgang, Nutzung und Kapazität zu verkraften. Sowohl horizontale als auch vertikale Skalierungsstrategien dienen der Fähigkeit eines Systems dieses Wachstum zu verkraften. Ich sehe eine Tendenz, auf die auch Jeremy hinwies, die Beziehung zwischen den Strategien zu vereinfachen und die horizontale Skalierungsarchitektur auf ein Podest zu erheben, ohne die Herausforderungen, die mit seiner Implementierung einhergehen wirklich zu verstehen.

Manchmal glaube ich, dass die Leute "scale out" hören und diese Strategie mit einem Ansatz mit Computerclustern verwechseln, bei dem Hunderte von Billigcomputern und große Speicherbänke und Festplatten sich wie ein einziger Computer verhalten. Skalieren bedeutet nicht Computercluster - weder horizontales noch vertikales Skalieren.

Im Allgemeinen bezieht sich der Term "vertikales Skalieren" (Scale-up) auf die Strategie, Kapazität hinzuzufügen, indem man die Kapazität der darunter liegenden Hardware erhöht - man kauft eine größere Kiste mit mehr Prozessoren oder Speicher, um die Anwendung darauf laufen zu lassen. Horizontale Skalierungsansätze auf der anderen Seite kann man sich im Allgemeinen als das Hinzufügen von Kapazität durch das Hinzufügen zusätzlicher Server zur Anwendungsarchitektur vorstellen. Einfach ausgedrückt sind dies die drei wichtigsten Dinge, die meinem Gefühl nach vertikale von horizontale Skalierungsansätzen unterscheiden:

  1. Vertrauen auf Hardware vs. Vertrauen auf Software
  2. Enterprise-Hardware vs. normaler Hardware
  3. Plötzliche vs. schrittweiser Kapazitätssteigerung
  4. Zentralisierte vs. verteilte Anwendungsarchitektur

Vertrauen auf Hardware vs. Vertrauen auf Software

Für Shops mit einem vertikalen Skalierungsansatz ist die Lösung, wenn der Durchsatz der datenbankzentrierten Anwendungen auf der vorhandenen Hardware die Obergrenze erreicht, die Kapazität der Datenbankserver so zu erhöhen, so dass sie mehr Such- und Transaktionsanfragen verkraften können, ohne den Anwendungscode verändern zu müssen. Der fettgedruckte Punkt ist wichtig: indem man die Kapazität der Hardware erhöht, auf der der Datenbankserver läuft, muss man den Anwendungscode überhaupt nicht ändern; das ist natürlich ein Vorteil für die Entwicklungsabteilung, es bedeutet weniger Arbeit für sie!

Tja, aber es gibt eine paar Probleme mit diesem Ansatz, auf die man achten muss, die ich in den Abschnitten über das schrittweise Hinzufügen von Kapazität und gewachsener Anwendungskomplexität hervorhebe.

Enterprise-Hardware vs. normaler Hardware

Wie ich im vorigen Abschnitt beschrieb, bedeutet vertikales Skalieren typischer Weise das Erhöhen der Kapazität durch die Erhöhung der Kapazität der zugrundeliegenden Hardware. Es gibt einen weiteren Punkt: Die Hardware selbst unterscheidet sich bei vertikalen und horizontalen Skalierungsmodellen. Vertikale Modelle tendieren zu "Enterprise-Hardware", während horizontale Modelle zu "normaler Hardware" tendieren. Ich möchte zwei Zitate von Jeremy Cole und Raj Thukral von Pythian hierzu anführen, die meiner Meinung nach etwas Licht auf diesen Unterschied zwischen vertikaler und horizontaler Skalierung werfen.

Zuerst Jeremys Versuch, den Mythos zu widerlegen, dass mit normaler Hardware "superbillige" Hardware gemeint ist. (Die Hervorhebungen stammen von mir.)

Oft hört man den Begriff "normale Hardware" im Zusammenhang mit horizontaler Skalierung. Während mistige Hardware durchaus auch normal ist, ist eigentlich gemeint, dass wenn man mit einer low-end $40k-Maschine feststeckt und mit dem Gedanken auf ein Upgrade auf eine $250k- und später vielleicht auf eine $1M-Maschine spielt, man Datenverteilung (data partitioning) und einige, nun ja, $5k-Maschinen verwendet. Es ist keine $1k-1-Festplatte-Mist-Maschine gemeint, wie ich bereits sagte. Was ist nun mit einer "normalen" Maschinen gemeint? Nun, eine Maschine mit standardisierten, üblichen Komponenten, bei der der Preis vom Markt und nicht von einer einzelnen Maschine festgelegt wird. Man verwendet normale Hardware mit einem ausgewogenen Preis-Leistungsverhältnis.

Ich stimme im höchsten Maße mit Jeremys Einschätzung überein. Standardisierte, übliche Komponenten, die nicht von einer einzelnen Firma kontrolliert werden, sind unlösbar mit dem horizontalen Skalierungsmodell verbunden, wie auch "Enterprise-Hardware" mit vertikalen Skalierungsmodellen verbunden ist. Raj bot mir eine Erklärung in einer Mail, die er mir neulich sandte:

... die meisten Leute, die Oracle zu laufen haben, tendieren dann auch dazu, auf Markenkisten mit vielen Pferdestärken zu setzen. Ich schätze, wenn man sechs Dinger für eine Lizenz bezahlt, dann kann man sich auch eine gute Kiste leisten. Mit MySQL tendiert man im Allgemeinen zu lower-end Hardware der Weißwarenklasse.

Vielleicht hat Raj es auf den Punkt gebracht. Vielleicht hat der Grund, warum vertikale Skalierungsmodelle mit higher-end Maschinen verknüpft sind einfach mit dem Vergleich der Kosten der Software und den Kosten der Hardware zu tun? Schlussendlich liegt es wohl in der Natur des Menschen zu denken, dass je teurer etwas ist, desto mehr es auch von teureren Sachen umgeben sein muss... :-)

Ich denke, dass es einen weiteren Grund gibt: Oracle kann bessere Hardware effizienter nutzen als MySQL. Mehr darüber später...

Kapazität schrittweise hinzufügen?

In einem vertikalen Skalierungsmodell ist es sehr unwahrscheinlich, dass der Anwendung Kapazität schrittweise hinzugefügt wird. Beispielsweise angenommen, dass man eine Anwendung hat, die auf Oracle 10g Enterprise Edition auf einer ordentlichen Sun-Kiste mit 16GB RAM und, nun ja, 4 Prozessoren läuft. Jetzt erreicht man einen Punkt, an dem die Anwendungsleistung leidet, weil Oracle die Hardware bis ins Letzte ausnutzt und mehr Speicher braucht. Man muss also die Leistung verbessern und anstatt irgendwelche Änderungen am Anwendungscode vorzunehmen beschließt man, die Kapazität der Hardware zu erhöhen, indem man einen neuen Sun-Server mit 8 Prozessoren und 32GB RAM anschafft.

OK, jetzt hat man das Leistungsproblem gelöst, weil Oracle jetzt mehr Speicher und mehr Prozessoren zu Verfügung stehen, um die Anfragen zu bearbeiten. Es ist nur eben unwahrscheinlich, dass der neue Server richtig ausgelastet wird und man einen guten Gegenwert für das Geld kriegt, dass man für die neue Hardwarekapazität ausgegeben hat. Angenommen man braucht zwei Jahre, um die Kapazität des ursprünglichen 4 Prozessor/16GB RAM Sun-Servers auszulasten. Man wird etwa ein Jahr oder mehr brauchen, die neue Hardware voll auszulasten. Es ist ja schön und gut, dass man sich für eine Weile keine Sorgen mehr über die Leistung meines Datenbankservers machen muss. Aber es ist im Grunde eine Vergeudung von Hardwareleistungskraft in der Zeit, in der der Durchsatz sich innerhalb des nächsten Jahres erhöht. Die Grafik unten illustriert den Punkt: Hardwarekapazität und Rechenleistung werden vergeudet, während man darauf "wartet", dass die neue Hardware voll ausgelastet wird - wenn das jemals eintritt... Die lila Fläche zeigt die vergeudete Rechnerleistung der Hardware über die Zeit.

Vergeudung von Prozessorleistung beim vertikalen Skalieren
In einem horizontalen Skalierungsmodell wird Hardwarekapazität nicht auf so dramatische Art hinzugefügt. Server mit jeweils weniger Kapazität als die oben beschriebenen vertikalen Skalierungsserver werden der Anwendung mit der Zeit schrittweise, auf gestaffelte und konsistentere Art hinzugefügt. Wenn man eine horizontale Skalierungsstrategie anwendet, um dieselbe Steigerung der Anwendungslast zu bewältigen, wird man Kapazität 13k-Schritten hinzufügen. Wie man sehen kann, ist die lila Fläche, die die vergeudete Rechnerleistung darstellt, deutlich kleiner.

Horizontales Skalieren führt zu geringerer Vergeudung von Prozessorleistung

Der Gewinn der verminderten Vergeudung ist ziemlich offensichtlich. An Stelle einer einmaligen großen Ausgabe für die kräftigere Sun-Kiste verteilen sich die Kosten über die Zeit. Investoren und Vorstände sind froh, wenn Kosten kontrolliert und schrittweise ansteigend sind und das Ausgleichsrisiko der Sofortkosten minimiert ist, falls die Anwendungsbelastung langsamer steigt als erwartet, was zusätzliche Rechenleistung unnötig werden lassen kann.

Angestiegene Komplexität der Anwendung?

Schrittweise ansteigende Kosten und Kapazität führen jedoch zu anderen Aufwänden - insbesondere eine angestiegene Komplexität der Anwendungsarchitektur um die Aufteilung der Anwendungsanfragen der verschiedenen Server unserer Architekturtopologie zu verarbeiten. Es ist aufwändiger mit dieser horizontalen Skalierungsarchitektur umzugehen, sowohl konzeptionell als auch bei der Implementierung. Kenntnis der horizontale Anwendungsskalierungsarchitektur ist notwendig und die Profis, die diese Kenntnisse haben, sind nicht billig.

Die horizontale Skalierungsfähigkeit von MySQL kann nicht mit der von Oracle verglichen werden

Hier ist eine Henne-Ei-Frage für dich. Was war zuerst da: die horizontale Skalierungsarchitektur die MySQL bietet oder das Design von MySQL für horizontales Skalieren? Lustige Frage? Nicht wirklich. So sehr ich MySQL auch liebe, glaube ich doch nicht, dass MySQLs Fähigkeit, eine horizontalen Skalierungsarchitektur zu unterstützen dem Konzept von MySQL bevorzugter horizontaler Skalierungsarchitektur vorausging.

Tatsächlich glaube ich, dass das, was wir heute das "horizontale Skalierungsmodell" nennen - das Modell, für das mit der "Der zwölf Tage der Scale Out"-Kampagne geworben wurde - der Unfähigkeit MySQLs entspringt im gleichen Maße vertikal zu skalieren, wie Oracle das kann.

Schockiert über meine Blasphemie? :-) Musst Du nicht sein. Das ist nur eine Beobachtung, die ich für richtig halte: das horizontale Skalierungsmodell - ein Modell, von dem ich ehrlich glaube, dass es das Skalierungsmodell der Zukunft ist - ist das einzige Modell, mit dem MySQL Erfolg haben kann. MySQLs Architektur und inneren Eigenschaften fehlen in einigen Schlüsselgebieten bestimmte Features, die Oracle vorweisen kann, die ein vertikales Skalierungsmodell für MySQL zu einer überflüssigen Übung machen:

  • Ineffiziente Nutzung mehrerer Prozessoren
  • weniger in der Lage, eine schlecht formulierte Anfrage davon abzuhalten, allen anderen den Tag zu verderben

Wegen dieser Defizite ist der Gewinn durch den Einsatz besserer Hardware bei MySQL geringer als bei Oracle. In einer horizontalen Skalierungsarchitektur werden diese Defizite jedoch gemildert. Das Problem ineffizienter Nutzung mehrerer Prozessoren verschwindet in einem horizontalen Skalierungsmodell fast völlig, weil die Server normaler Weise in einem Mix von einem bis vier Prozessoren auftreten und MySQL lokal auf den Servern läuft. Bei ein bis vier Prozessoren ist die Ineffizienz von MySQL beim Verwalten von zusätzlichen Prozessoren nicht so offensichtlich. Das Problem mit der schlecht formulierten Anfrage, die allen anderen den Tag verderben will ist minimiert, weil die verschiedenen Datenbankserver in der horizontal skalierten Architektur immer nur einen Teil der Anwendungsanfragen bearbeiten. Im Wesentlichen isoliert die horizontale Skalierungsarchitektur schlechte Anfragen bei einer kleinen Anzahl der Benutzer; etwas, was bei einem vertikal skalierten, einzelnen MySQL-Datenbankserver nicht möglich wäre.

Zentralisierte vs. verteilte Anwendungsarchitektur

Der vierte Hauptunterschied zwischen vertikaler und horizontaler Skalierungsarchitektur hat mit der Gesamttopologie der Anwendungen der jeweiligen Strategien zu tun. In vertikalen Skalierungsmodellen tendieren die Anwendungen mehr zu Zentralismus als in horizontalen Skalierungsmodellen. Mit "Zentralismus" meine ich nicht, dass der Anwendungscode selbst auf einem einzelnen Server läuft. Ich meine, dass die Daten allgemein auf einem einzelnen Datenbankserver liegen und dass ein oder mehrere Anwendungsserver sich nach Bedarf zu diesem einzelnen Datenbankserver verbinden.

Mit "verteilt" meine ich, dass die Daten selbst dazu tendieren, auf mehrere "Shards" verteilt zu sein, mit einer oder mehreren Anwendungen, die ihre Anfragen zu einem oder mehreren der Datenbankteile richten. Die Verteilung der Daten über die Datenbankserver kann mit einer selbstgestrickten Lösung oder mit den Verteilungsfeatures von MySQL 5+ erledigt werden.

In beiden Fällen wird das Verteilungsmodell so gewählt, dass die Daten über die Anwendung konsistent und gleichmäßig verteilt werden. Manchmal werden Benutzeraccount-IDs verwendet um die Daten zwischen den verschiedenen Servern aufzuteilen. In anderen Fällen werden Hashing-Funktionen oder Datenbereiche verwendet. Dessen ungeachtet ist es so, dass die horizontale Skalierungsarchitektur die Aufteilung der Daten in einer nicht-zentralisierten, verteilten Topologie fördert.

Viel der zusätzlichen Anwendungskomplexität, über die ich weiter oben schrieb, rührt von dieser Verteilung auf Datenebene her. Zusätzlicher Code ist notwendig, der als Verkehrspolizist die Anfragen zum richtigen Datenspeicher leitet. Zudem ist es tendenziell schwieriger aggregierte Daten zu erhalten, weil Prozesse eingerichtet werden müssen, um Daten aus den einzelnen Shards zur Analyse in ein zentrales Datenwarenhaus zu holen. Ich erachte diesen Nachteil als vernachlässigbar, da auch in vertikalen Skalierungsmodellen Daten oft für Offlineanalysen aus der zentralen Datenbank in ein separates Warenhaussystem gezogen werden.

Aber zusammen mit dieser gestiegenen Komplexität kommen die Vorteile des horizontalen Skalierungsmodells: schrittweise Zunahme der Kapazität und die Möglichkeit, Last auf eine Datenbankserverfarm zu verteilen. Zudem neigt ein horizontales Skalierungsmodell nicht zu Engpässen, da es keinen einzelnen monolithischen Datenbankserver gibt, der als Datenspeicher für die gesamte Anwednung dient.

Montag, 29. Oktober 2007

Ist Sharding dasselbe wie Partitionierung und Föderation?

Original: http://www.royans.net/arch/2007/09/09/sharding-different-from-partitioning-and-federation/ 9. September 2007 12:34
Autor: Royans Tharakan
Übersetzung: Sebastian Wallroth

Dieses Wort "Sharding"... ich höre es immer öfter. Es geht um wie ein Lauffeuer. Theo Schlossnagle, der Autor von "Skalierbare Internetarchitekturen", vertritt die Ansicht, dass ein föderiertes Informationssystem ein Form von Partitionierung und dass Sharding wiederum nichts anderes als eine Form von Partitionierung und Föderation ist. Schlossnagle meint, dass Sharding bereits seit sehr langer Zeit angewandt wird.

Ich bin weder beruflich noch privat Datenbankadministrator. Um also die Unterschiede zu verstehen, habe ich ein bisschen geforscht und ein paar interessante Artikel gefunden.

Das erste Mal hörte ich von "Sharding" im Blog "mySQL DBA" in einem Artikel über einen unorthodoxen Datenbankentwurf (Teil I und Teil II). Hier ist das exakte Zitat:
Teilt man die Benutzerdaten so auf, dass Benutzer A auf dem einen Server
existiert, während Benutzer B auf einem anderen Server existiert, so hält jeder
Server in diesem föderierten Modell einen Splitter (shard) der Daten vor.
Vor ein paar Monaten griff Highscalability.com das Thema Sharding auf und ließ es so aussehen (möglicherweise unabsichtlich) als ob Sharding eigentlich etwas anderes ist als Föderation und Partionierung. Todds Artikel weist darauf hin, dass Flickr Sharding verwendet. Die Suche nach Flickrs Architektur führte mich zu Colin Charles Artikel über das föderierte Informationssystem bei Flickr: Eine Führung durch die Architektur von Flickr, in der er Shards als eine Komponente des föderierten Schlüssels erwähnt. Auch er jedoch nennt Sharding nichts Neues. Zitat:
Schlüsselkomponenten eines föderierten Informationssystems:
  • Shards: Meine Daten werden in meinem Shard gespeichert, aber die Aufzeichnung über eine ausgeführte Tätigkeit steht in deinem Shard. Beispiel: Man macht einen Kommentar in jemandes anderen Blog.
  • Global Ring: Das ist wie DNS, Du musst wissen, wo Du hin musst und wer kontrolliert, wohin Du gehst. Bei jedem Seitenaufruf wird im selben Moment berechnet, wo deine Daten sind.
  • PHP-Logik, um die Shards zu verbinden und die Daten konsistent zu halten (10 Zeilen Code - mit Kommentaren!)

Ausgehend von den Diskussionen in diesem und anderen Blogs scheinen "Shards" eher eine Terminologie zu sein, um Datenfragmente zu beschreiben, die über mehrere Datenbanken hinweg föderiert sind, als eine Architektur an sich. Ich denke, Theo Schlossnagles Argument ist triftig. Wenn jemand anderer Meinung ist, dann würde ich gern davon hören. Eine klarere Definition von Sharding im Unterschied zu Föderation würde ebenfalls sehr hilfreich sein.

Weitere Referenzen zum Thema Shards/Sharding

Was ist Skalierbarkeit?

Original: http://www.royans.net/arch/2007/09/22/what-is-scalability/ 22. September 2007 18:14
Autor: Royans Tharakan
Übersetzung: Sebastian Wallroth

Gefragt, was sie denn mit Skalierbarkeit meinen, sprechen die Leute über Verbesserung der Leistung, Einführung von Hochverfügbarkeit oder sogar über spezielle Technologien oder Protokolle. Tja, Skalierbarkeit ist nichts davon. Versteh' mich nicht falsch. Man muss schon alles über Geschwindigkeit, Leistung, Hochverfügbarkeitstechnologie, Anwendungsplattformen, Netzwerk, etc. wissen. Aber das ist nicht die Definition von Skalierbarkeit.

Einfach ausgedrückt bezeichnet Skalierbarkeit die Möglichkeit, dein bisheriges Geschäft in einem größeren Rahmen zu betreiben. Eine Webanwendung zu skalieren bedeutet, mehr Leuten zu ermöglichen, die Anwendung zu benutzen. Wenn Du nicht erklären kannst, wie Du die Leistung verbesserst, wenn Du mehr Rechner einbindest, dann ist das okay. Und so lange Du skalieren kannst, um eine größer werdende Anzahl von Benutzern zu bedienen, ist es auch okay, manche Dinge nicht zu wissen. Alle anderen lesen bitte weiter.

Derzeit werden zwei Hauptarten der Webseitenskalierung angewandt.

  • "Vertikale Skalierung" - Das Hinzufügen von Ressourcen innerhalb einer logischen Einheit, um die Kapazität zu erhöhen. Ein Beispiel könnte das Hinzufügen von CPUs zu einem existierenden Server sein oder die Erweiterung des Speicherplatzes durch das Hinzufügen von Festplatten zu einer existierenden RAID/SAN-Installation.

  • "Horizontale Skalierung" - Das Hinzufügen mehrere logischer Ressourcen-Einheiten, die dazu gebracht werden, wie eine einzige Einheit zu arbeiten. Die meisten Cluster-Lösungen, verteilten Dateisysteme und Lastverteiler dienen der horizontalen Skalierung.
Alle Komponenten, seien es Prozessoren, Server, Speicherlaufwerke oder Lastverteiler, haben in irgend einer Form einen Verwaltungsüberbau. Wenn Du den skalieren willst, musst Du herausfinden, welcher Anteil der Ressource tatsächlich verwendbar ist. Das Ergebnis wird "Skalierbarkeitsfaktor" genannt. Wenn Du jedesmal 5% Prozessorleistung verlierst, wenn Du deinem System eine weitere CPU hinzufügst, dann beträgt dein Skalierbarkeitsfaktor 0,95. Ein Skalierbarkeitsfaktor von 0,9 bedeutet, dass Du nur 90% deiner Ressourcen verwenden können wirst.

Skalierbarkeit kann basierend auf dem Skalierbarkeitsfaktor weiter unterteilt werden.

  • Wenn der Skalierbarkeitsfaktor beim Skalieren konstant bleibt, nennt man das "lineare Skalierbarkeit".
  • Es kann aber sein, das manche Komponenten nicht so gut skalieren wie andere. Ein Skalierbarkeitsfaktor unter 1,0 wird "sub-lineare Skalierbarkeit" genannt.
  • Obgleich selten, ist es möglich eine bessere Leistung (einen besseren Skalierbarkeitfaktor) zu erhalten, indem man einfach mehr Komponenten hinzufügt (I/O zwischen Festplattenspindeln in einem RAID wird besser, wenn man mehr Spindeln hinzufügt). Das nennt man "supra-lineare Skalierbarkeit".
  • Wenn die Anwendung nicht auf Skalierbarkeit ausgelegt wurde, ist es möglich, dass das System sogar schlechter wird, wenn man es skaliert. Das nennt man "negative Skalierbarkeit".
Wenn Du dringend auf Skalierbarkeit angewiesen bist, dann ist vertikale Skalierung möglicherweise der einfachere Weg (vorausgesetzt, dass dein Kontostand dir das erlaubt). In den meisten Fällen kannst Du, ohne eine Zeile Code zu ändern, deine Anwendung auf einem superteuren 64-CPU-Server von Sun oder HP mit Speicher von EMC, Hitachi oder Netapp installieren und alles wird toll sein. Zu dumm, dass vertikales Skalieren immer teurer wird, je weiter Du es treibst.

Horizontale Skalierung hingegen nötigt dich nicht, immer teurere Server zu kaufen. Sie ist auf Skalierung mit normalen Speicher- und Serverlösungen ausgelegt. Aber horizontale Skalierung ist nicht automatisch billiger. Die Anwendung muss von Grund auf so konzipiert werden, dass einzelne Anwendungen auf mehreren Rechnern laufen können. Die zwei interessantesten Probleme, die die meisten Anwendungen in der Welt der horizontalen Skalierung fürchten müssen sind "Split Brain" und "Hardwareabsturz".

Während unendliche horizontale Skalierbarkeit schwierig zu erreichen ist, ist unendliche vertikale Skalierbarkeit unmöglich. Wenn Du Kapazitäten für eine vorher festgelegte Anzahl von Benutzern aufbaust, kann es weise sein, vertikal zu skalieren. Wenn Du aber eine Webanwendung baust, die von Millionen genutzt werden könnte, dann könnte die Entscheidung für vertikale Skalierung ein teurer Fehler sein.

Aber bei Skalierbarkeit geht es nicht nur um CPU (Rechenleistung). Für eine erfolgreich skalierbare Webanwendung müssen alle Schichten in gleichem Maße skalieren. Das schließt die Speicherschicht (geclusterte Dateisysteme, S3, etc.), die Datenbankschicht (Partitionierung, Federation), die Anwendungsschicht (Memcached, Scaleout, Terracotta, Tomcat Clustering, etc.), die Webschicht, den Lastverteiler, die Firewall und alle anderen ein. Wenn Du zum Beispiel nicht mehrere Lastverteiler einsetzen kannst um deine zukünftige Zugriffslast zu bewältigen, dann ist es wirklich egal, wie viel Geld und Aufwand Du in die horizontale Skalierbarkeit deiner Webschicht gesteckt hast. Deine Zugriffslast wird darauf beschränkt sein, was dein Lastverteiler stemmen kann.

Die Wahl der richtigen Art von Skalierbarkeit hängt davon ab, wie viel Du skalieren und wie viel Du ausgeben willst. Wenn jemand behauptet, es gäbe eine Lösung, die alle Bedürfnisse befriedigt - dann glaube ihm nicht. Und wenn jemand auf der nächsten Party eine Diskussion über "Skalierbarkeit" beginnt, dann frage ihn bitte zuerst, was er denn mit Skalierbarkeit meint.

Referenzen


  1. Cost and Scalability in Vertical and Horizontal Architectures, Implications for Database and Application Layer Deployments, Technical White Paper, Tom Atwood (Sun Microsystems), September 2004 (PDF, englisch)
  2. My Linear Scalability is bigger than yours! Posted at 07:30AM Dec 20, 2006 by Cameron Purdy on /dev/null

Sonntag, 28. Oktober 2007

Scale-Out vs. Scale-Up - Skalierung durch Vermehrung statt Verbesserung

Original: http://oracle2mysql.wordpress.com/2007/08/22/12/ Mittwoch, 22. August 2007 19:26
Autor: Ben Krug
Übersetzung: Sebastian Wallroth

Scale-Up versus Scale-Out - Worum geht's?

Grundsätzlich geht es um die Skalierung, das heißt die Verbesserung oder Vergrößerung eines Serversystems um zum Beispiel eine größere Datenmenge oder mehr Zugriffe verarbeiten zu können oder die vorhandenen Daten oder Zugriffe schneller zu bearbeiten. "Scale-Up" und "Scale-Out" sind neue geschaffene Wörter, die sich an den englischen Wörtern "build up", "aufbauen; das Vorhandene verbessern" und "build out", "ausbauen; das Vorhandene erweitern" orientieren.
"Scale-up" oder "Scaling up" ("vertikale Skalierung") bedeutet, Server aufzurüsten oder einen größeren Server einzusetzen, also eine qualitative Veränderung.
"Scale-out" oder "Scaling out" ("horizontale Skalierung") bedeutet, neue Server hinzuzufügen, also eine quantitative Änderung.

Oracle wirbt für beide Methoden. Man soll RAC auf großen Servern oder "Blades" oder "Grids" einsetzen.

MySQL wirbt im Allgemeinen für Scale-Out und die meisten der großen Seiten, die MySQL verwenden setzen auf Scale-Out. Meiner Erfahrung nach und in Einklang mit Jay Pipes exzellentem Blog-Artikel zu diesem Thema ist das teilweise so, weil MySQL nicht so gut vertikal skaliert wie horizontal. (Ein anderer Grund, den Jay erwähnt und der sich auch mit meinen Erfahrung deckt, ist, dass Leute, die eine Oracle-Lizenz kaufen meist auch teure Maschinen bezahlen, um es darauf laufen zu lassen.)

Mit Oracle, egal ob Du vertikal oder horizontal skalierst, wirst Du normalerweise RAC verwenden, was das Aufsetzen von private-Verbindungen und ein Grundsätzliches "alles gemeinsam nutzen" für deine Server bedeutet. Das ist immer noch irgendwie ein vertikales Skalieren der Datenbank, ein Wachsen mit einer bestehenden Anzahl von Servern. (Korrigiere mich, wenn ich falsch liege...)

Mit MySQL neigen die Leute dazu, ihre Datenbanken aufzuteilen, sie in Teile zu "sharden", die in verschiedene Datenbanken auf verschiedenen Servern getan werden. Beispielsweise könntest Du eine kleine globale Datenbank haben, die Informationen darüber enthält, auf welchem Server die Daten eine Benutzers gespeichert sind und dann mehrere "Benutzer"-Datenbanken auf verschiedenen Servern. Deine Datenbank würde im Grunde nach Benutzern in kleinere Datenbanken aufgeteilt sein. (So machen wir das.) Das ist horizontales Skalieren. Wenn Du dann mehr Benutzer kriegst und Du wachsen musst, fügst Du einfach neue Server hinzu.

(Wenn Du auf der anderen Seite eine kleine Datenbank hast - die komplett in den RAM passt - kannst Du MySQLs Clustering-Technologie und die NDB-Speicher-Engine verwenden, um einen Cluster einzurichten, der mehr wie RAC ist. Mit MySQL 5.1 kannst Du das mit Festplatten-basierten Datenbanken machen - aber wieso?) (Lies die Kommentare unten, wenn Du wissen willst, warum...)

Ein anderer Aspekt des horizontalen Skalierens kann sein, MySQLs Replikationstechnologie auf die eine oder andere Art zu verwenden. Du kannst die Master-Master-Replikation einsetzen, um zwei (oder ein paar mehr) Datenbanken aufzusetzen, die im Wesentlichen Kopien voneinander sind und sie synchron miteinander halten. Oder, und das ist üblicher, (und wir machen das so) Du verwendest die Master-Slave-Replikation, um Kopien deiner Datenbanken (shards) zu machen, die Du verwenden kannst, um deine Lese-Zugriffe darauf zu verteilen (und für eine Wiederherstellung im Falle einer Katastrophe: wenn der Master abstürzt - ernenne einen Slave zum neuen Master). Die meisten großen LAMP-Webseiten scheinen das so zu machen.

Zusammenfassend kann man sagen, dass der übliche Ansatz ist, deine Datenbank so zu entwerfen, dass sie in mehrere Shards (Server/Datenbanken) aufgeteilt wird, und Du dann die Replikation verwendest, um Kopien der Shards für weitere Lastverteilung und Verfügbarkeit herzustellen.

Das sagen einige andere Quellen:

Definitionen nach Wikipedias Eintrag zu Skalierbarkeit:

Vertikal skalieren (scale vertically)
Vertikal zu skalieren (scale-up) bedeutet, dass man einem einzelnen Knoten in einem System Ressourcen hinzufügt, typischer Weise gehört dazu das Hinzufügen von CPUs oder RAM zu einem einzelnen Computer. Es kann auch die Erhöhung der Anzahl der laufenden Prozesse, wie zum Beispiel der Erhöhung der Anzahl der Apache-Daemons bedeuten.

Horizontal skalieren (scale horizontally)
Horizontal zu skalieren (scale-out) bedeutet, einem System mehr Knoten hinzuzufügen, wie zum Beispiel das Hinzufügen eines neuen Computers zu einer verteilten Softwareanwendung. Ein Beispiel könnte das horizontale Skalieren von 1 auf 3 Webserver sein.
Nach MySQL: (aus der ersten Seite von "12 Tage des Scale-Out")
Was ist Scale-Out von Datenbanken?

Scale-Out ist eine moderne Rechnerarchitektur, die Organisationen in die Lage versetzt, die Anwendungsleistung und die Skalierbarkeit auf einer inkrementellen, auf die Anforderungen zugeschnittenen Basis zu verbessern, indem mehrere replizierte Datenbankserver auf einer niedrigpreisigen normalen Hardware hinzugefügt werden. Dies steht im Kontrast zu einem Scale-Up-Ansatz, der Organisationen nötigt, eine gewaltige Vorabinvestition in teurere und komplexere Serverhardware und Datenbanklizenzen zu tätigen, um mehr Kapazität hinzuzufügen.
Der exzellente Blog-Artikel von Jay Pipe: Das uneindeutig unklare Duo: Horizontales Skalieren und Vertikales Skalieren

Eine Produktinformation von MySQL: Guide to Cost-effective Database Scale-Out using MySQL (Anleitung für kosteneffektives Scale-Out mit MySQL)

Kommentar von Keith Murphy vom 23. August 2007 1:26

Ich habe ein paar Anmerkungen. Zum einen... MySQL 5.0 hat ein totales RAM-internes Clustering unter Verwendung der NDB-Engine. Mit MySQL 5.1 kann man auf der anderen Seite nur die Indizes im RAM halten. Tatsächlich können die Daten auf der Festplatte gehalten werden.

Warum würdest Du das tun? Nun, vor allem wegen der Verlässlichkeit. Wenn Du mehrere SQL- und Datenknoten hast und sie angemessen konfiguriert sind, dann kann jeder Server abstürzen und der Cluster läuft trotzdem weiter.

Theoretisch erlaubt Dir das, deine Anwendung nach Bedarf zu skalieren. Das ist meines Wissens derzeit eher theoretisch, aber ich bin sicher, dass das weiter besser wird.

Ich führe die Diskussion derzeit auch - Scale-Out vs. Scale-Up. Ja, Scale-Out ist billig(er), weil höherwertige Hardware teurer ist. Aber mehr Server brauchen mehr Leute, um sie zu verwalten (Systemadministratoren) und mehr Datenbankadministratoren, um mit ihnen zu arbeiten. Also fischt man im Trüben, wenn es darum geht, was besser ist.

Es ist wieder und wieder bewiesen worden, das MySQL ausskalieren kann. Nicht so viele Informationen stehen über das Aufskalieren zur Verfügung. Ich habe die Artikel, auf die Du verweist, noch nicht gelesen, aber ich werde es tun. Ich habe gehört, dass MySQL unter Linux ohne viel Effizienzverlust mit ungefähr 64 GB RAM und ungefähr 8 Cores umgehen kann. Das ist eine ganz schön heftige Maschine... eine, die einige kleinere Server ersetzen könnte.

Ein anderes Argument außer den reduzierten Administrationskosten ist, dass manche Anwendungen sich einfach nicht so leicht sharden lassen. In manchen Anwendungen steckt eine so große Komplexität, dass sie das unmöglich macht.

Ich hoffe, einiges davon durchtesten zu können. Ich werde auf jeden Fall darüber bloggen, wenn es so ist.
Kommentar von Matthew Montgomery vom 23. August 2007 4:24
Ich muss dich in einem Punkt korrigieren... Festplatten-basierte Spalten für
NDB-(MySQL-Cluster)-Tabellen sind in Version 5.1 verfügbar.

Siehe: http://dev.mysql.com/doc/refman/5.1/en/mysql-cluster-disk-data.html

Die NDB-Engine gibt dir die Möglichkeit, auszuskalieren, während Du ein einzelnes logisches Image deiner Daten konservierst, ohne Sharding in deine Anwendung hinein programmieren zu müssen. Außerdem bietet es Hochverfügbarkeit mit synchroner Replikation, Aktivierung eines Ersatzsystems in unter einer Sekunde und automatische Wiederherstellung.

Wikimedia Architecture

Original: http://highscalability.com/wikimedia-architectureInformationsquellen
Plattform
  • Apache
  • Linux
  • MySQL
  • PHP
  • Squid
  • LVS
  • Lucene für die Suche
  • Memcached für Distributed Object Cache
  • Lighttpd Image Server
Die Fakten
  • 8.000.000 Artikel in mehr als 100 nach Sprachen aufgeteilten Projekten (Englisch, Französisch, Schwedisch, ...)
  • Platz 10 unter den Seiten mit den meisten Zugriffe (Quelle: Alexa)
  • Exponentielles Wachstum: Verdopplung alle 4 bis 6 Monate in Bezug auf Besucher / Zugriffe /Server
  • Bis zu 30.000 HTTP-Zugriffe/Sekunde
  • 3 GBit/Sekunde Datenübertragungsvolumen
  • 3 Datenzentren: Tampa, Amsterdam, Seoul
  • 350 Server; von 1 x P4 bis 2 x Xeon Quadcore; 0,5 bis 16 GB RAM
  • gewartet von etwa 6 Personen
  • 3 Cluster auf 3 Kontinenten
Die Architektur
  • Geografische Lastverteilung, die den Internetbenutzer auf Grundlage dessen IP zum nächstgelegenen Servercluster weiterleitet. Statische Zuordnung der IP-Adressen zu Ländern und damit zu den Clustern.
  • HTTP Reverse-Proxy-Caching mit Hilfe von Squid, gruppiert nach Text für den Wikiinhalt und Medien für Bilder und große unveränderliche Dateien
  • derzeit 55 Squid-Server, plus 20, die auf ihren Einsatz warten
  • 1.000 HTTP-Anfragen/Sekunde pro Server; bis zu 2.500 zu Spitzenzeiten
  • rund 100 bis 250 MBit/Sekunde pro Server
  • rund 40.000 bis 32.000 offene Verbindungen pro Server
  • bis zu 40 GB Festplattencache pro Squid-Server
  • bis zu 4 Festplatten pro Server (1U-Rack-Server)
  • 8 GB RAM; die Hälfte davon wird von Squid belegt
  • Zugriffsraten: 85% Text, 98% Medien, seit CARP verwendet wird
  • PowerDNS bietet die geografische Verteilung
  • In den Haupt- und den regionalen Datenzentren entstehen Text- und Medien-Cluster unter Verwendung von LVS, CARP Squid und Cache Squid. IM Hauptdatenzentrum steht der Medienspeicher.
  • Im sicher zu stellen, dass die letzte Version aller Seiten ausgeliefert wird, werden Annullierungsanfragen an alle Squid-Caches geschickt.
  • Eine zentral verwaltete und synchronisierte Softwareinstallation für Hunderte Wikis.
  • MediaWiki skaliert gut mit mehreren CPUs, deswegen werden Duale Quad-Core-Server angeschafft (8 CPUs pro Box)
  • die Hardware wird sich geteilt; zusätzlich gibt es externen Speicherplatz und Memcached-Aufgaben
  • Memcached wird verwendet, um Bildmetadaten, Parserdaten, Unterschiede, Benutzer, Sessions und Textversionen zu cachen. Metadaten, wie zum Beispiel Artikelversionsgeschichten, Artikelbeziehungen (Links, Kategorien, etc.), Benutzeraccounts und Einstellungen werden in der zentralen Datenbank gespeichert.
  • Die aktuelle Textversion wird in Blobs im externem Speicher gespeichert.
  • Unveränderliche (hochgeladene) Dateien, wie zum Beispiel Bilder, werden getrennt von den anderen Daten auf einem Bilderserver gespeichert - Metadaten (Größe, Typ, etc.) wird in der zentralen Datenbank und Objektcaches gecached.
  • Jedes Wiki hat seine eigene Datenbank (keinen eigenen Server!).
  • Ein Master, viele kopierte Slaves.
  • Die Lesezugriffslast wird zwischen den Slaves verteilt, Schreibzugriffe gehen direkt an den Master.
  • Der Master wird nur für Lesezugriffe verwendet, wenn die Slaves nicht auf dem aktuellsten Stand (lagged) sind.
  • Externer Speicher
    • Der Artikeltext wird in von den anderen Daten getrennten Speicherclustern gespeichert, einfach angehängter Blob-Speicher. Das spart Speicher auf den teuren und unter Last stehenden Zentraldatenbanken für sowieso weithin ungenutzte Daten.
    • Erlaubt die Verwendung magerer Ressourcen auf den Applikationsservern (2 x 250 - 500 GB pro Server)
    • Derzeit werden kopierte Cluster dreier MySQL-Hosts verwendet; das kann sic inder Zukunft zu Gunsten besserer Verwaltbarkeit ändern
Gelernte Lektionen
  • Konzentriere dich auf die Architektur; nicht so sehr auf Verwaltung und nichttechnisches Angelegenheiten.
  • Manchmal ist Caching aufwändiger als Neuberechnung oder ein Blick auf die Datenquelle ... Profiling (Analyse des Laufzeitverhaltens von Software)!
  • Vermeide aufwändige Algorithmen, Datenbankabfragen, etc.
  • Cache jedes Ergebnis, das aufwändig zu berechnen ist und nur zeitweise Gültigkeit hat.
  • Konzentriere dich auf die heißen Stellen im Code (Profiling!).
  • Skaliere, indem Du trennst:
    • Lese- von Schreibzugriffen (Master/Slave)
    • Aufwändige Operationen von einfachen und häufigen Operationen (query groups)
    • Große, häufig besuchte Wikis von kleineren Wikis
  • Verbessere das Caching: temporäre und räumliche Anordnung von Verweisen (memory locality) und Verminderung der Datensatzgröße pro Server
  • Text wird komprimiert und nur die Unterschiede zwischen den Artikelversionen werden gespeichert.
  • Einfach scheinende Bibliotheksaufrufe, wie die Verwendung von stat, um die Existenz einer Datei zu überprüfen, können zu lange dauern, wenn sie geladen werden.
  • Begrenze die Zugriffszeit auf die Festplatten. Je mehr Spindeln, desto besser!
  • Skalierung durch Vermehrung mit normaler Hardware bedeutet nicht, dass man unbedingt Billighardware nehmen muss. Wikipedias Datenbankserver sind heute 16 GB Dual- oder Quad-Core-Kisten mit 6 15.000 RPM SCSI-Festplatten in einer RAID 0-Konfiguration. Es hat sich einfach ergeben, dass dies die optimale Umgebung (Sweet Spot) für Wikipedias Working Set und das Lastverteilungssystem ist. Wikipedia würde kleinere und billigere Systeme verwenden, wenn es Sinn ergeben würde, aber 16 GB ist passend für die Größe des Working Sets und das führt den Rest der Spezifikation dazu, ein System mit so viel RAM zu verlangen. Ganz ähnlich dazu sind die Webserver derzeit 8 Core-Kisten, weil sich heraus stellte, dass das so mit der Lastverteilung gut funktioniert und einen guten PHP-Durchsatz mit einer verhältnismäßig einfachen Lastverteilung ergibt.
  • Es ist viel Arbeit, durch Vermehrung zu Skalieren, und sogar noch mehr, wenn man das System nicht selbst entwirft. Wikipedias MediaWiki wurde ursprünglich für einen einzelnen Masterdatenbankserver geschrieben. Dann wurde die Unterstützung von Slaves hinzugefügt. Dann wurde die Unterteilung nach Sprache/Projekt hinzugefügt. Die Entwürfe von damals haben den Test gut bestanden, obgleich viel Verbesserungsarbeit an neu auftauchenden Engstellen nötig wurde.
  • Jeder, der seine Datenbankarchitektur so entwerfen möchte, dass sie es ihm erlaubt, ohne großen Aufwand von einer Stufe mit nur einer Kiste auf die Stufe der Top 10 oder Top 100 der Webseiten des Internet zu wachsen, sollte damit anfangen, leicht veraltete Daten von Kopien-Slaves verwalten zu lassen, sollte wissen, wie man die Last der Lesezugriffe zwischen den Slaves verteilt und wann immer möglich so entwerfen, dass Datenbrocken (Bündel von Benutzern, Accounts, was auch immer) auf verschiedenen Serven landen können. Man kann das von Anfang an mittels Virtualisierung tun und die Architektur testen, solange man noch klein ist. Es ist VIEL einfacher, als wenn man es erst prüft, wenn sich die Last alle paar Monate verdoppelt.