Ist die Funktionalität der DB ein Hindernis für die Skalierbarkeit?


17

Ich bin möglicherweise nicht in der Lage, der Frage den richtigen Titel zu geben. Aber hier ist es,

Wir entwickeln ein Finanzportal für die Vermögensverwaltung. Wir erwarten, dass über 10000 Kunden die Anwendung nutzen. Das Portal berechnet verschiedene Performance-Analysen basierend auf der technischen Analyse der Börse.

Wir haben viele Funktionen über gespeicherte Prozeduren, benutzerdefinierte Funktionen, Trigger usw. über die Datenbank entwickelt. Wir dachten, wir können eine enorme Leistungssteigerung erzielen, wenn wir direkt in der Datenbank arbeiten, als durch C # -Code. Und wir haben tatsächlich einen enormen Leistungsschub bekommen.

Als ich versuchte, unserem CTO mit der Errungenschaft zu prahlen, stellte er meine Entscheidung in Frage, die Funktionalität nicht in Code, sondern in einer Datenbank zu implementieren. Ihm zufolge leiden solche Anwendungen unter Skalierbarkeitsproblemen. In seinen Worten: "Heutzutage werden die Dinge im Speicher / Cache aufbewahrt. Cluster-Daten sind im Laufe der Zeit schwer zu verwalten. Facebook, Google haben nichts in der Datenbank. Es ist die Ära der Thin Server und Thick Clients. DB wird nur zum Speichern einfacher Daten verwendet und Funktionalität sollten vollständig von der Datenbank entkoppelt sein. "

Könnt ihr mir bitte ein paar Vorschläge machen, ob das, was er sagt, richtig ist. Wie gehen Sie vor, um eine solche Anwendung zu erstellen?


3
"und wir haben tatsächlich einen enormen Leistungsschub bekommen" im Vergleich zu was? Woher wissen Sie, dass Sie niemals die gleiche Funktionalität auf einem Client implementiert haben?
Doc Brown

3
Ich denke, es wird das Übliche sein - es hängt vom Projekt, der Datenimplementierung und der Kompetenz des Teams ab.
Daniel Iankov

1
Sie sollten Ihren CTO fragen, warum er der Meinung ist, dass Datenbanken nicht seine bevorzugten Techniken verwenden und warum gespeicherte Prozeduren nicht als "Code" eingestuft werden.
Blrfl

3
Facebook und Google haben Probleme in einem ganz anderen Ausmaß als die meisten anderen Anwendungen. Möglicherweise gibt es ein Problem mit der Datenmenge, mit der Sie im Hinblick auf Daten aus dem Markt umgehen müssen, aber moderne SQL-Datenbanken sind darauf ausgelegt, mit erstaunlichen Datenmengen fertig zu werden.
Murph

1
Ich würde wahrscheinlich genauso denken wie Ihr CTO, es sei denn, Sie könnten nachweisen, dass die Leistung seiner Lösung unzureichend ist und es keine anderen Möglichkeiten gibt, sie zu verwalten. Gespeicherte Prozeduren verursachen, insbesondere wenn ihre Anzahl an Daten zunimmt, eine enorme Barriere, die es unmöglich macht, bei Bedarf auf andere DBs zuzugreifen. Sie können die Zukunft nicht vorhersagen.
Rig

Antworten:


23

Kurz gesagt, ich stimme Ihrem CTO zu. Sie haben wahrscheinlich auf Kosten der Skalierbarkeit eine gewisse Leistung erzielt (wenn diese Begriffe verwirrend sind, erkläre ich dies weiter unten). Meine zwei größten Sorgen wären die Wartbarkeit und der Mangel an Optionen für die horizontale Skalierung (vorausgesetzt, Sie werden das brauchen).

Nähe zu Daten: Machen wir einen Schritt zurück. Es gibt einige gute Gründe, Code in eine Datenbank zu verschieben. Ich würde argumentieren, dass die größte Nähe zu den Daten besteht - zum Beispiel, wenn Sie erwarten, dass eine Berechnung eine Handvoll Werte zurückgibt, aber dies sind Aggregationen von Millionen von Datensätzen, die die Millionen von Datensätzen (bei Bedarf) übermitteln Das Netzwerk, das an anderer Stelle aggregiert werden muss, ist äußerst verschwenderisch und kann Ihr System leicht zum Erliegen bringen. Allerdings können Sie diese Nähe von Daten auch auf andere Weise erreichen, indem Sie im Wesentlichen Caches oder Analyse-DBs verwenden, bei denen ein Teil der Aggregation im Voraus erfolgt.

Leistung des Codes in der DB:Sekundäre Leistungseffekte wie "Zwischenspeichern von Ausführungsplänen" sind schwieriger zu diskutieren. Manchmal können zwischengespeicherte Ausführungspläne sehr negativ sein, wenn der falsche Ausführungsplan zwischengespeichert wurde. Abhängig von Ihrem RDBMS können Sie das meiste aus diesen herausholen, aber Sie werden in den meisten Fällen nicht viel über parametrisiertes SQL herausfinden (diese Pläne werden normalerweise auch zwischengespeichert). Ich würde auch argumentieren, dass die meisten kompilierten oder mit JIT erstellten Sprachen in der Regel eine bessere Leistung als ihre SQL-Entsprechungen (wie T-SQL oder PL / SQL) für grundlegende Operationen und nicht relationale Programmierung (Manipulation von Zeichenfolgen, Schleifen usw.) erbringen Sie verlieren dort nichts, wenn Sie etwas wie Java oder C # zum Knabbern der Zahlen verwenden. Feinkörnige Optimierung ist auch ziemlich schwierig - auf der DB, Sie Häufig wird ein generischer B-Baum (Index) als einzige Datenstruktur verwendet. Um fair zu sein, könnte eine vollständige Analyse, einschließlich längerer Transaktionen, Sperreneskalation usw., Bücher füllen.

Wartbarkeit: SQL ist eine wunderbare Sprache für das, wofür es entwickelt wurde. Ich bin mir nicht sicher, ob es gut zur Anwendungslogik passt. Die meisten Tools und Methoden, die unser Leben erträglich machen (TDD, Refactoring usw.), sind bei der Datenbankprogrammierung nur schwer anwendbar.

Leistung versus Skalierbarkeit:Um diese Begriffe zu verdeutlichen, meine ich Folgendes: Die Leistung gibt an, wie schnell eine einzelne Anforderung Ihr System (und zurück zum Benutzer) durchläuft, wenn nur eine geringe Auslastung angenommen wird. Dies wird oft durch Dinge wie die Anzahl der physischen Schichten, die durchlaufen werden, wie gut diese Schichten optimiert sind usw. begrenzt. Die Skalierbarkeit ist, wie sich die Leistung mit zunehmender Anzahl von Benutzern / Auslastung ändert. Möglicherweise verfügen Sie über eine mittlere / niedrige Leistung (z. B. 5 Sekunden + für eine Anforderung), aber eine hervorragende Skalierbarkeit (die Millionen von Benutzern unterstützen kann). In Ihrem Fall werden Sie wahrscheinlich eine gute Leistung erzielen, Ihre Skalierbarkeit wird jedoch davon abhängen, wie groß ein Server sein kann, den Sie physisch aufbauen können. Irgendwann werden Sie an diese Grenze stoßen und gezwungen sein, sich Dingen wie Scherben zuzuwenden, die je nach Art der Anwendung möglicherweise nicht durchführbar sind.

Vorzeitige Optimierung: Letztendlich haben Sie den Fehler gemacht, vorzeitig zu optimieren. Wie andere darauf hingewiesen haben, gibt es keine Messungen, die zeigen, wie die anderen Ansätze funktionieren würden. Nun, wir können nicht immer maßstabsgetreue Prototypen bauen, um eine Theorie zu beweisen oder zu widerlegen ... Aber im Allgemeinen würde ich immer zögern, einen Ansatz zu wählen, der Wartbarkeit (wahrscheinlich die wichtigste Qualität einer Anwendung) für die Leistung tauscht .

BEARBEITEN: Positiv ist zu vermerken, dass die vertikale Skalierung in einigen Fällen ziemlich weit gehen kann. Soweit ich weiß, lief SO einige Zeit auf einem einzelnen Server. Ich bin mir nicht sicher, wie es Ihren 10 000 Benutzern entspricht (ich denke, es hängt von der Art ab, wie sie in Ihrem System vorgehen), aber es gibt Ihnen eine Vorstellung davon, was getan werden kann (tatsächlich gibt es weit eindrucksvollere Beispiele, dies ist einfach ein beliebtes Beispiel, das die Leute leicht verstehen können).

EDIT 2: Um ein paar Dinge zu klären und zu kommentieren, die an anderer Stelle angesprochen wurden:

  • Betreff: Atomare Konsistenz - Die ACID-Konsistenz kann durchaus eine Anforderung des Systems sein. Das oben Gesagte spricht nicht wirklich dagegen, und Sie sollten sich darüber im Klaren sein, dass die ACID-Konsistenz nicht erfordert, dass Sie Ihre gesamte Geschäftslogik in der Datenbank ausführen. Durch die Verschieben - Code, der nicht brauchte , dort zu sein in die DB, Sie beschränke es in der physischen Umgebung des Restes der DB zu laufen - es ist im Wettbewerb um die gleichen Hardware - Ressourcen als den eigentliche Datenverwaltung Teil Ihrer DB. Da es nur darum geht, den Code auf andere DB-Server (aber nicht auf die eigentlichen Daten) zu skalieren, ist dies zwar möglich , aber was genau erzielen Sie hier, abgesehen von den zusätzlichen Lizenzkosten in den meisten Fällen? Behalten Sie Dinge, die nicht in der DB sein müssen, außerhalb der DB.
  • Betreff: SQL / C # -Leistung - da dies ein interessantes Thema zu sein scheint, wollen wir die Diskussion etwas erweitern. Natürlich können Sie nativen / Java / C # -Code in DBs ausführen, aber soweit ich weiß, wurde hier nicht darüber gesprochen. Wir vergleichen die Implementierung von typischem Anwendungscode in T-SQL mit der von C #. Es gibt eine Reihe von Problemen, die in der Vergangenheit mit relationalem Code nur schwer zu lösen waren - z. B. das Problem "Maximale Anzahl gleichzeitiger Anmeldungen", bei dem Aufzeichnungen vorliegen, die eine Anmeldung oder Abmeldung sowie die Uhrzeit angeben Die maximale Anzahl der gleichzeitig angemeldeten Benutzer war. Die einfachste mögliche Lösung besteht darin, die Datensätze zu durchlaufen und einen Zähler weiter zu erhöhen / zu verringern, wenn Anmeldungen / Abmeldungen auftreten, und das Maximum dieses Werts zu protokollieren.kannIch weiß nicht), das Beste, was Sie tun können, ist ein CURSOR (die rein relationalen Lösungen sind alle unterschiedlich komplex, und der Versuch, sie mit einer while-Schleife zu lösen, führt zu einer schlechteren Leistung). In diesem Fall ist die C # -Lösung tatsächlich schneller als das, was Sie in T-SQL erreichen können. Das mag weit hergeholt erscheinen, aber dieses Problem kann sich leicht in Finanzsystemen manifestieren, wenn Sie mit Zeilen arbeiten, die relative Änderungen darstellen, und fensterorientierte Aggregationen für diese berechnen müssen. Gespeicherte Proc-Aufrufe sind in der Regel auch teurer. Rufen Sie eine einfache SP millionenfach auf und sehen Sie, wie sich dies mit dem Aufrufen einer C # -Funktion vergleichen lässt. Ich habe oben einige andere Beispiele angedeutet - ich habe noch niemanden angetroffen, der eine richtige Hash-Tabelle in T-SQL implementiert hat (eine, die tatsächlich einige Vorteile bietet), während dies in C # ziemlich einfach ist. Wieder gibt es Dinge, bei denen DBs großartig sind, und Dinge, bei denen sie nicht so großartig sind. So wie ich JOINs, SUMs und GROUP BYs nicht in C # ausführen möchte, möchte ich in T-SQL nichts besonders CPU-intensives schreiben.

Einer der Gründe, warum ich dazu neige, Funktionen in die Datenbank zu übertragen, ist, dass sie viel weniger fehleranfällig sind als Code auf Anwendungsebene. SQL ist deklarativ und leidet nicht unter den Problemen, die imperative Sprachen verursachen.
wobbily_col

In Bezug auf die Wartbarkeit ist die Verwendung der SQL Server-Datentools ein Kinderspiel. In der Tat würde ich es für jede nicht-triviale Datenbank (eine mit mehr als 5 Tabellen) als eine Anforderung betrachten.
Jon49

4

Die Skalierbarkeit hat nichts damit zu tun, wo sich die Daten befinden oder wie die Berechnung erfolgt. Bei der Skalierbarkeit geht es darum, wie Sie die globale Abhängigkeit von Status und Daten verwalten. Wenn Ihre Architektur mit allen Arten von Datenabhängigkeiten behaftet ist, spielt es keine Rolle, wo Sie den Code für die Transformation dieser Daten ablegen. Die gegenseitigen Abhängigkeiten werden Ihre Hand zwingen und jedes Potenzial zur Skalierung von Dingen verringern. Wenn andererseits Ihre Daten lose gekoppelt sind und es nur sehr wenige oder gar keine globalen Zustände gibt, spielt es wiederum keine Rolle, wo die Berechnung stattfindet. Das Skalieren von Dingen wird viel einfacher.

Ich bin mir nicht sicher, woher Ihr CTO seine Informationen zu Skalierbarkeitsproblemen bezieht, aber nach Ihrer Aussage hat er keine wirklichen Gründe, die aktuelle Architekturentscheidung in Frage zu stellen, abgesehen von Software-Modetrends. Architekturentscheidungen auf solche Trends zu stützen, ist normalerweise eine schlechte Idee.


1
+1 fürScalability is all about how you manage global state and data inter-dependence.
Estefany Velez

2

Und wir haben tatsächlich einen enormen Leistungsschub bekommen.

Ich denke, Sie müssen zuerst einen Leistungsmaßstab setzen und mit dem Bau Ihres Prototyps beginnen. Alle Logik in der DB beizubehalten, ist eine alte Schule (ich habe leider nichts dagegen) des Umgangs mit Client-Server-Architektur. Obwohl es seine Vorteile hat, gibt es eine Reihe von Nachteilen, die berücksichtigt werden müssen.

Der übliche Ansatz für diese Art von verkaufsfähigen Anwendungen erfolgt über SOA . Denn auf lange Sicht ist dies der einfachste Weg, Ihrem Projekt neue Client-Anwendungen hinzuzufügen.

Sie haben auch Auslöser erwähnt. Die Verwendung des Auslösers könnte später im Support-Lebenszyklus der Anwendung zu einem großen Problem werden. Ich würde doppelt vorsichtig damit sein und sogar versuchen, die Verwendung zu überspringen.


2

Ihr CTO ist zu 100% falsch.

Ihre Finanzzahlen MÜSSEN sich jederzeit summieren. Das bedeutet, dass Sie ACID und relationale Datenbanken benötigen , um dies zu gewährleisten. Die Leistungsgewinne von NoSql DB liegen normalerweise auf Kosten von ACID und das ist für Google und Facebook in Ordnung, ABER NICHT für ein System, das Finanzdaten enthält.

Zu sagen, dass C # eine bessere Leistung als SQL-Code erbringt, ist auch ein Blödsinn…


Zu behaupten, dass C # eine bessere Leistung als SQL-Code erbringt, ist ebenfalls ein Blödsinn ... - Aber Sie bestreiten nicht, dass C # -Code skalierbarer ist, richtig?
Jim G.

Nein, es ist nicht mehr skalierbar. Da sich der Flaschenhals nicht befindet, kann ich den SQL-Code (nicht die Daten) horizontal genauso einfach skalieren wie den C # -Code horizontal.
Morons

@JimG. Nur um zu verdeutlichen: "Ich kann den SQL-Code (nicht die Daten) horizontal genauso einfach skalieren wie den C # -Code horizontal", wenn es dafür entworfen wurde ... Genau wie C # muss es für die Skalierung entworfen werden. Man kann nicht einfach sagen, dass C # besser skaliert, es geht darum, nicht die Sprache zu planen.
Morons

@JimG .: Software, die nicht skaliert, kann in jeder Sprache geschrieben werden, einschließlich C #. Jede Datenbank, die es wert ist, gespeichert zu werden, kann Prozeduren enthalten, die in einer anderen Sprache als ihrer nativen SQL-basierten Implementierung geschrieben sind, und Leute, die in Situationen, in denen ACID erforderlich ist, das meiste der Räder neu erfinden implementiert durch das DBMS.
Blrfl

@ Morons: Ich denke, wir sind uns einig. Ich war in der Tat die Daten mit „SQL“ conflating. Es ist viel teurer, die Datenbank zu skalieren.
Jim G.

2

Immer wenn jemand Skalierbarkeit und Google / Facebook / Twitter / etc erwähnt, ist es ein roter Hering. Wenn Sie nicht im Wesentlichen den gleichen Service anbieten, ist das, was für sie funktioniert, möglicherweise nicht für Sie geeignet. Wenn Sie von einer einzelnen Maschine zu einem Cluster mit acht Maschinen skalieren können, haben Sie im Allgemeinen wahrscheinlich alle Ihre Grundlagen abgedeckt. Machen Sie sich keine Sorgen über die Hyper-Skalierung, es sei denn, Sie haben geschäftliche Anforderungen, täglich 20 Millionen Seitenaufrufe bereitzustellen. Tun Sie, was für die tatsächlichen Anforderungen Ihrer Anwendung sinnvoll ist , und sorgen Sie sich um die Skalierung, wenn sich herausstellt, dass dies erforderlich ist. Und vergessen Sie nicht, dass die meisten Datenbankserver auch geclustert werden können. Nur weil alles in einer Datenbank enthalten ist, bedeutet dies nicht, dass es sich auf einem Server befindet.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.