Heim  >  Artikel  >  Datenbank  >  Designdiskussion über die Speicherung und den Zugriff auf große Datenmengen in MySQL

Designdiskussion über die Speicherung und den Zugriff auf große Datenmengen in MySQL

高洛峰
高洛峰Original
2016-12-02 13:17:321124Durchsuche

1. Einführung

Mit der weit verbreiteten Beliebtheit von Internetanwendungen sind die Speicherung und der Zugriff auf große Datenmengen zu Engpässen im Systemdesign geworden. Bei einer groß angelegten Internetanwendung stellen Milliarden von PVs jeden Tag zweifellos eine erhebliche Belastung für die Datenbank dar. Dies hat zu großen Problemen bei der Stabilität und Skalierbarkeit des Systems geführt. Um die Website-Leistung durch Datensegmentierung zu verbessern, ist die horizontale Erweiterung der Datenschicht zur bevorzugten Methode für Architekturentwickler geworden. Durch horizontales Sharding der Datenbank kann die Belastung einer einzelnen Maschine reduziert und die durch Ausfallzeiten verursachten Verluste minimiert werden. Durch die Lastausgleichsstrategie wird die Zugriffslast einer einzelnen Maschine effektiv reduziert und die Möglichkeit von Ausfallzeiten durch die Cluster-Lösung reduziert. Das Problem der durch Datenbankausfallzeiten verursachten Unzugänglichkeit von Einzelpunkten wird durch die Lese-/Schreibtrennung gelöst Strategie, mehr Es maximiert die Geschwindigkeit und Parallelität beim Lesen (Lesen) von Daten in der Anwendung. Derzeit verwenden viele inländische große Internetanwendungen solche Datensegmentierungslösungen, wie z. B. Taobao, Alibaba und Tencent. Die meisten von ihnen haben ihre eigene verteilte Datenzugriffsschicht (DDAL) implementiert. Unterteilt nach Implementierungsmethoden und Implementierungsebenen kann es grob in zwei Ebenen unterteilt werden (Java-Anwendung als Beispiel): Kapselung der JDBC-Schicht und Implementierung der ORM-Framework-Schicht. Was die direkte Kapselung der JDBC-Schicht angeht, ist eines der am weitesten entwickelten Projekte in China das Projekt namens „Amoeba“, das vom Forschungsinstitut der Alibaba Group entwickelt wurde und sich noch im Teststadium (Beta-Version) befindet ). Betriebseffizienz und Produktionspünktlichkeit müssen untersucht werden. Was die Implementierung der ORM-Framework-Schicht betrifft, wird die auf Ibatis und Spring basierende verteilte Datenzugriffsschicht von Taobao seit vielen Jahren verwendet und ihre Betriebseffizienz und Produktionseffektivität wurden von Entwicklern und Benutzern anerkannt. Dieser Artikel ist eine verteilte Datenzugriffsschicht, die auf der ORM-Framework-Schicht basiert. Die Schwierigkeit dieses Themas liegt in der Formulierung und Auswahl von Routing-Regeln und der späteren Skalierbarkeit nach der Aufteilung der Datenbank, beispielsweise in der Frage, wie der Zweck der Erweiterung der Datenbankkapazität (Hinzufügen von Maschinenknoten) mit der geringsten Datenmigration erreicht werden kann. Die Kernthemen werden sich um die Routing-Regeln und Lastausgleichsstrategien von Datenbank-Shards und -Tabellen drehen.

2. Grundprinzipien und Konzepte

2.1 Grundprinzipien:

Der Prozess menschlicher kognitiver Probleme ist immer so: was (was) -? warum (warum)-? Wie (wie es geht), als nächstes werden in diesem Artikel diese drei Themen diskutiert und untersucht:

 2.1.1 Was ist Datensegmentierung

 Die englische Bedeutung des Wortes „Shard“ ist „ „Fragment“, ein technischer Begriff im Zusammenhang mit Datenbanken, scheint erstmals in Massively Multiplayer Online-Rollenspielen aufgetaucht zu sein. „Sharding“ wird vorläufig als „Sharding“ bezeichnet. Sharding ist keine neue Technologie, sondern ein relativ einfaches Softwarekonzept. Wie wir alle wissen, war die Partitionierungsfunktion für Daten erst nach MySQL5 verfügbar. Davor waren viele potenzielle Benutzer besorgt über die Skalierbarkeit von MySQL. Ob die Partitionierungsfunktion ein Maß für die Skalierbarkeit einer Datenbank ist Indikatoren (natürlich nicht die einzigen Indikatoren). Datenbankskalierbarkeit ist ein ewiges Thema. MySQL-Befürworter werden oft gefragt: Wie kann dies erreicht werden, wenn die Anwendungsdatenverarbeitung auf einer einzelnen Datenbank überlastet ist und eine Partitionierung erfordert? Sharding ist keine Funktion, die an eine bestimmte Datenbanksoftware gebunden ist, sondern eine Abstraktion, die auf bestimmten technischen Details basiert. Es handelt sich um eine Lösung für die horizontale Erweiterung (ScaleOut oder horizontale Erweiterung, Erweiterung nach außen). Die O-Kapazitätsgrenze des Knotendatenbankservers löst das Problem der Datenbankskalierbarkeit.

Durch eine Reihe von Segmentierungsregeln werden die Daten horizontal auf verschiedene Datenbanken oder Tabellen verteilt, und die spezifische Datenbank oder Tabelle, die abgefragt werden muss, wird über die entsprechenden DB-Routing- oder Tabellen-Routing-Regeln für den Abfragevorgang gefunden. Das hier erwähnte „Sharding“ bezieht sich in der Regel auf „horizontales Slicing“, das auch im Mittelpunkt dieses Artikels steht. Welche spezifischen Segmentierungs- und Routingmethoden werden verwendet? An dieser Stelle werden die Leser unweigerlich Fragen haben: Lassen Sie uns die Protokolle in einer Blog-Anwendung veranschaulichen. Die Protokollartikeltabelle (Artikel) enthält beispielsweise die folgenden Felder:

Article_id (int) , title(varchar(128)),content(varchar(1024)),user_id(int)

Wie segmentieren wir eine solche Tabelle? Wie verteilt man solche Daten auf Tabellen in verschiedenen Datenbanken? Tatsächlich fällt es uns bei der Analyse der Blog-Anwendung nicht schwer, die Schlussfolgerung zu ziehen: Bei der Blog-Anwendung werden Benutzer in zwei Typen unterteilt: Betrachter und Blog-Eigentümer. Wenn ein Betrachter einen Blog durchsucht, durchsucht er tatsächlich den Blog eines bestimmten Benutzers, und der Eigentümer des Blogs, der seinen eigenen Blog verwaltet, operiert auch unter dem Blog eines bestimmten Benutzers (in seinem eigenen Bereich). Der sogenannte spezifische Benutzer wird durch ein Datenbankfeld als „user_id“ dargestellt. Es ist diese „user_id“, die die Grundlage für die Unterbibliothek und die Grundlage der von uns benötigten Regeln bildet. Wir können dies tun, indem wir alle Artikelinformationen mit einer Benutzer-ID zwischen 1 und 10.000 in die Artikeltabelle in DB1 einfügen, alle Artikelinformationen mit einer Benutzer-ID zwischen 10.001 und 20.000 in die Artikeltabelle in DB2 einfügen und so weiter, bis DBn. Auf diese Weise werden die Artikeldaten auf natürliche Weise in verschiedene Datenbanken aufgeteilt, wodurch der Zweck der Datensegmentierung erreicht wird. Das nächste zu lösende Problem ist, wie man die spezifische Datenbank findet. Tatsächlich ist das Problem einfach und offensichtlich. Da wir beim Teilen der Datenbank das Unterscheidungsfeld user_id verwendet haben, ist der Prozess des Datenbankroutings immer noch unverzichtbar. Betrachten Sie die Blog-Anwendung, die wir gerade vorgestellt haben. Kurz gesagt, ich muss wissen, wer der Benutzer dieses Blogs ist, wenn wir die Benutzer-ID dieses Blogs kennen Verwenden Sie diese Benutzer-ID, um die spezifische Datenbank zu finden. Wenn Sie beispielsweise die Regel dieser Person verwenden, sollten Sie DB1 suchen Regel dieser Person, sollten Sie DB2 finden. Analog dazu werden die Sharding-Regeln verwendet, um eine umgekehrte Weiterleitung zu einer bestimmten Datenbank durchzuführen. Dieser Vorgang wird als „DB-Routing“ bezeichnet.

Natürlich muss das DB-Design, das die Datensegmentierung berücksichtigt, ein unkonventionelles und unorthodoxes DB-Design sein. Was für ein DB-Design ist also das orthodoxe DB-Design?

Es ist im Grunde das, was wir regelmäßig verwenden. Normalerweise entwerfen wir unsere Datenbank bewusst nach dem Paradigma. Wenn die Auslastung hoch ist, können wir die Verwendung des entsprechenden Replikationsmechanismus in Betracht ziehen, um den Durchsatz und die Leistung beim Lesen und Schreiben zu verbessern Dieser Mechanismus selbst ist noch relativ offensichtlich (siehe unten). Das oben erwähnte „bewusste Design nach Paradigma“. In Anbetracht des DB-Designs der Datensegmentierung verstößt es gegen diese üblichen Regeln und Einschränkungen. Um zu segmentieren, müssen wir redundante Felder in den Datenbanktabellen haben, die als Unterscheidungsfelder oder Markierungsfelder, sogenannte Unterdatenbanken, verwendet werden, wie z Artikel oben Felder wie user_id im Beispiel (natürlich spiegelt das aktuelle Beispiel die Redundanz von user_id nicht sehr gut wider, da das Feld user_id auch dann angezeigt wird, wenn es nicht in Datenbanken unterteilt ist, also haben wir es ausgenutzt ). Natürlich tritt die Entstehung redundanter Felder nicht nur im Szenario von Unterdatenbanken auf. In vielen großen Anwendungen ist auch Redundanz erforderlich. Dies beinhaltet den Entwurf einer effizienten Datenbank, auf die in diesem Artikel nicht eingegangen wird.

 2.1.2 Warum Datensegmentierung erforderlich ist

Oben wurde eine kurze Beschreibung und Erklärung dessen gegeben, was Datensegmentierung ist. Leser fragen sich möglicherweise, warum Datensegmentierung erforderlich ist. Reicht eine ausgereifte und stabile Datenbank wie Oracle aus, um die Speicherung und Abfrage großer Datenmengen zu unterstützen? Warum brauchen wir Data Slicing? Tatsächlich ist die Datenbank von Oracle sehr ausgereift und stabil, aber die hohen Nutzungsgebühren und der High-End-Hardware-Support können sich nicht jedes Unternehmen leisten. Stellen Sie sich nur die Nutzungskosten von mehreren zehn Millionen Dollar pro Jahr und die Hardware-Unterstützung eines Minicomputers vor, die mehrere zehn Millionen Dollar kostet. Können sich normale Unternehmen das leisten? Selbst wenn wir es uns leisten können, wenn es eine bessere Lösung gibt, eine günstigere Lösung mit besserer horizontaler Skalierbarkeit, warum sollten wir uns dann nicht dafür entscheiden?

Allerdings sind die Dinge immer unbefriedigend. Normalerweise entwerfen wir unsere Datenbank bewusst nach dem Paradigma. Wenn die Auslastung hoch ist, können wir die Verwendung des entsprechenden Replikationsmechanismus in Betracht ziehen, um den Durchsatz und die Leistung beim Lesen und Schreiben zu verbessern Dieser Mechanismus selbst ist noch relativ offensichtlich. Erstens hängt seine Wirksamkeit vom Anteil der Leseoperationen ab, die zur Ausführung in die Warteschlange gestellt werden müssen. Wenn er überlastet ist, kann er die Verzögerung bei der Datensynchronisierung nicht bewältigen Die Anzahl der Slaves kann auch relativ groß sein und die Rechenleistung der CPU sehr in Anspruch nehmen, da der Schreibvorgang nach der Ausführung auf dem Master noch auf jedem Slave-Computer ausgeführt werden muss. Das Sharding kann zu diesem Zeitpunkt nutzlos werden. Eine Replikation ist nicht möglich, warum kann Sharding also funktionieren? Der Grund ist einfach, denn es lässt sich gut skalieren. Wir wissen, dass jede Maschine ihre eigene physische Obergrenze hat, egal wie gut sie konfiguriert ist. Wenn unsere Anwendung also eine bestimmte Obergrenze einer einzelnen Maschine erreicht oder weit überschreitet, können wir nur die Hilfe anderer Maschinen in Anspruch nehmen oder mit dem Upgrade fortfahren. Unsere Hardware, aber die übliche Lösung besteht darin, durch Hinzufügen weiterer Maschinen zu skalieren, um den Druck zu teilen. Wir müssen auch überlegen, ob unsere Maschinen die Nachfrage durch lineares Wachstum decken können, während unsere Geschäftslogik weiter wächst? Durch Sharding können Rechenleistung, Speicher und E/A problemlos parallel auf mehrere Maschinen verteilt werden, wodurch die verschiedenen Verarbeitungsfunktionen mehrerer Maschinen voll ausgenutzt werden können, während gleichzeitig einzelne Fehlerquellen vermieden, die Systemverfügbarkeit gewährleistet und eine gute Fehlerisolierung durchgeführt wird.

Basierend auf den oben genannten Faktoren ist die Datensegmentierung sehr wichtig, und die Datensegmentierung, die wir hier diskutieren, verwendet auch MySQL als Hintergrund. Aus Kostengründen haben sich viele Unternehmen auch für Free und Open MySql entschieden. Entwickler, die etwas über MySQL wissen, wissen möglicherweise, dass die Partitionierungsfunktion für Datentabellen erst nach MySQL5 verfügbar war. Davor waren viele potenzielle Benutzer von MySQL besorgt über die Skalierbarkeit von MySQL, und ob die Partitionierungsfunktion vorhanden war, wurde zu einem Schlüsselindikator (natürlich nicht der einzige Indikator), um die Skalierbarkeit einer Datenbank zu messen. Datenbankskalierbarkeit ist ein ewiges Thema. Wenn die Anwendungsdaten in einer einzelnen Datenbank gestreckt sind und partitioniert werden müssen, lautet die Antwort auch Sharding planen.

Wir nutzen kostenloses MySQL und günstige Server oder sogar PCs als Cluster, um den Effekt eines Minicomputers + einer großen kommerziellen Datenbank zu erzielen, eine Menge Kapitalinvestitionen zu reduzieren und die Betriebskosten zu senken. Deshalb entscheiden wir uns für Sharding und begrüßen Sharding.

 2.1.3 So erreichen Sie eine Datensegmentierung

Wenn es um die Datensegmentierung geht, werden wir noch einmal die Methode und Form der Datensegmentierung genauer erläutern und erläutern.

Die Datensegmentierung kann physisch erfolgen. Die Daten werden über eine Reihe von Segmentierungsregeln auf verschiedene DB-Server verteilt, und auf bestimmte Datenbanken wird über Routingregeln zugegriffen, sodass jeder Zugriff möglich ist N Server, sodass der Lastdruck auf einer einzelnen Maschine reduziert werden kann.

Die Datensegmentierung kann auch innerhalb der Datenbank erfolgen. Die Daten werden über eine Reihe von Segmentierungsregeln auf verschiedene Tabellen einer Datenbank verteilt. Beispielsweise wird der Artikel in mehrere Untertabellen unterteilt Die Untertabellen werden horizontal zu einer logisch vollständigen Artikeltabelle zusammengefasst. Der Zweck ist eigentlich sehr einfach. Beispielsweise befinden sich derzeit 50 Millionen Daten in der Artikeltabelle. Zu diesem Zeitpunkt müssen wir dieser Tabelle neue Daten hinzufügen (einfügen). Nach Abschluss des Einfügens wird die Datenbank diese Tabelle neu indizieren und erstellen Sie 50 Millionen Datenzeilen. Der Systemaufwand für die Indizierung kann nicht ignoriert werden. Wenn wir diese Tabelle jedoch in 100 Tabellen aufteilen, von Artikel_001 bis Artikel_100, werden 50 Millionen Datenzeilen gemittelt, und jede Untertabelle enthält nur 500.000 Datenzeilen. Zu diesem Zeitpunkt fügen wir eine Tabelle mit nur 500.000 Zeilen hinzu Nach dem Einfügen von Daten wird die Zeit zum Erstellen eines Index um eine Größenordnung verkürzt, was die Laufzeiteffizienz der Datenbank erheblich verbessert und die Parallelität der Datenbank erhöht. Natürlich sind die Vorteile des Shardings noch nicht bekannt. Es gibt aber auch viele offensichtliche Vorteile, wie zum Beispiel Sperrvorgänge für Schreibvorgänge.

Zusammenfassend lässt sich sagen, dass die Untertabelle die Belastung einer einzelnen Maschine reduziert und die Effizienz von Datenoperationen verbessert, insbesondere die Effizienz von Schreiboperationen. Zu diesem Zeitpunkt des Schreibens haben wir die Frage der Segmentierung noch nicht angesprochen. Als nächstes werden wir die Segmentierungsregeln im Detail erläutern und erläutern.

Um eine horizontale Segmentierung der Daten zu erreichen, müssen in jeder Tabelle redundante Zeichen als Grundlage für die Segmentierung und Markierungsfelder vorhanden sein. In gängigen Anwendungen verwenden wir user_id als Unterscheidungsfeld Dazu gibt es die folgenden drei Methoden und Regeln der Unterbibliothek: (Natürlich kann es auch andere Methoden geben)

Geteilt durch Zahlensegment:

(1) user_id ist die Unterscheidung, 1 ~1000 entspricht DB1, 1001~2000 entspricht DB2 usw.

Vorteile: Teilmigration ist möglich

Nachteile: Ungleichmäßige Datenverteilung

(2) Hash Modulpunktzahl:

Hashen Sie die Benutzer-ID (oder verwenden Sie den Wert von Benutzer-ID direkt, wenn die Benutzer-ID ein numerischer Typ ist) und verwenden Sie dann eine bestimmte Zahl. Wenn die Anwendung beispielsweise eine Datenbank in 4 Datenbanken aufteilen muss, verwenden wir 4. Die Zahl führt eine Modulo-Operation für den Hash-Wert von user_id aus, der user_id%4 ist. In diesem Fall gibt es vier Möglichkeiten für jede Operation: Wenn das Ergebnis 1 ist, entspricht es DB1, wenn das Ergebnis 2 ist zu DB2; wenn das Ergebnis 3 ist, entspricht es DB2; wenn das Ergebnis 0 ist, entspricht es DB4, sodass die Daten gleichmäßig auf die 4 DBs verteilt werden.

Vorteile: Gleichmäßige Datenverteilung

Nachteile: Datenmigration ist mühsam, Daten können nicht entsprechend der Maschinenleistung zugeordnet werden

(3) Speichern Sie die Datenbankkonfiguration in der Authentifizierungsdatenbank

Diese Datenbank speichert separat die Zuordnungsbeziehung zwischen user_id und DB. Jedes Mal, wenn wir auf die Datenbank zugreifen, müssen wir diese Datenbank zuerst abfragen, um die spezifischen DB-Informationen zu erhalten Abfrageoperationen, die wir benötigen.

Vorteile: Starke Flexibilität, Eins-zu-Eins-Beziehung

Nachteile: Vor jeder Abfrage ist eine weitere Abfrage erforderlich, was die Leistung erheblich verringert

Das Obige ist das, was wir normalerweise tun In der Entwicklung stehen drei Methoden zur Auswahl, und einige komplexe Projekte verwenden möglicherweise eine Mischung dieser drei Methoden. Durch die obige Beschreibung erhalten wir auch ein einfaches Verständnis der Regeln der Unterbibliothek. Natürlich wird es bessere und umfassendere Möglichkeiten zur Unterbibliothek geben, und wir müssen weiterhin erforschen und entdecken.

3. Der Grundriss dieser Diskussion

Im obigen Text erklären wir einige Konzepte und Konzepte der Datenbanksegmentierung gemäß den Regeln menschlicher kognitiver Dinge und eine kurze Einführung in einige herkömmliche Segmentierungsregeln. Die in diesem Thema besprochene verteilte Datenschicht ist nicht nur das, sie ist eine vollständige Datenschichtlösung. Wie sieht sie aus? Im folgenden Text werde ich auf die vollständigen Ideen und Umsetzungsmethoden dieses Forschungsthemas eingehen.

Die verteilte Datenlösung bietet die folgenden Funktionen:

(1) Stellt Sharding- und Routing-Regeln bereit (RouteRule wird als RR bezeichnet) und konvertiert die drei in der obigen Beschreibung genannten Segmentierungsregeln direkt Einbetten dieses Systems, die spezifische Einbettungsmethode wird im folgenden Inhalt ausführlich erläutert

(2) Einführung des Cluster-Konzepts (Gruppe), um die hohe Verfügbarkeit von Daten sicherzustellen; > (3) Einführung einer Lastausgleichsrichtlinie (LoadBalancePolicy, abgekürzt als LB); (4) Einführung eines Mechanismus zur Erkennung der Clusterknotenverfügbarkeit, um die Verfügbarkeit von Einzelpunktmaschinen sicherzustellen, um die korrekte Implementierung der LB-Richtlinie sicherzustellen Stellen Sie ein hohes Maß an Stabilität des Systems sicher.

(5) Führen Sie eine Lese-/Schreibtrennung ein, um die Datenabfragegeschwindigkeit zu verbessern.

Nur das Design der Datenschicht von Unterdatenbank und Untertabelle nicht perfekt genug. Was passiert, wenn der DB-Server auf einem bestimmten Knoten ausfällt? Ja, wir haben ein Datenbanksegmentierungsschema eingeführt, was bedeutet, dass N Maschinen eine vollständige Datenbank bilden. Wenn eine Maschine ausfällt, kann nur auf ein N/N der Daten in der Datenbank zugegriffen werden. Dies bedeutet, dass dies für uns akzeptabel ist Zumindest ist es viel besser als vor der Aufteilung, und die gesamte Datenbank ist nicht unzugänglich. Bei allgemeinen Anwendungen ist es akzeptabel, dass ein solcher Maschinenausfall dazu führt, dass Daten nicht mehr zugänglich sind. Was ist, wenn es sich bei unserem System um eine E-Commerce-Website mit hoher Parallelität handelt? Die wirtschaftlichen Verluste, die durch den Ausfall einer einzelnen Knotenmaschine verursacht werden, sind sehr schwerwiegend. Mit anderen Worten: Es gibt immer noch Probleme mit unserer aktuellen Lösung und die Fehlertoleranzleistung kann dem Test nicht standhalten. Natürlich gibt es für Probleme immer Lösungen. Wir führen das Konzept des Clusters ein, das ich hier als Gruppe bezeichne. Das heißt, wir führen mehrere Maschinen in jeden Unterbibliotheksknoten ein. Unter normalen Umständen teilen sich diese mehreren Maschinen die Last Im Falle eines Ausfalls verteilt der Load Balancer die Last auf die ausgefallene Maschine. Auf diese Weise wird das Problem der Fehlertoleranz gelöst. Also führten wir das Konzept der Cluster ein, betteten es in unser Framework ein und wurden Teil des Frameworks.

Wie in der Abbildung oben gezeigt, besteht die gesamte Datenschicht aus drei Clustern: Gruppe1, Gruppe2 und Gruppe3. Diese drei Cluster sind das Ergebnis der horizontalen Segmentierung von Daten. Natürlich bilden diese drei Cluster auch eine Datenbank mit vollständigen Daten. Jede Gruppe umfasst 1 Master (natürlich kann es mehrere Master geben) und N Slaves. Die Daten dieser Master und Slaves sind konsistent. Wenn beispielsweise ein Slave in Gruppe 1 ausfällt, können weiterhin zwei Slaves verwendet werden. Ein solches Modell führt niemals zu dem Problem, dass auf bestimmte Teile der Daten nicht zugegriffen werden kann, es sei denn, alle Maschinen in der gesamten Gruppe sind ausgefallen dass die Wahrscheinlichkeit, dass so etwas passiert, sehr gering ist (sofern es keinen Stromausfall gibt, ist es unwahrscheinlich, dass so etwas passiert).

Vor der Einführung des Clusters war unser Abfrageprozess ungefähr wie folgt: Fordern Sie die Datenschicht an und übergeben Sie das erforderliche Unterscheidungsfeld der Unterdatenbank (normalerweise user_id). Die Datenschicht leitet basierend auf dem Unterscheidungsfeld an die spezifische Datenbank weiter Operationen werden innerhalb dieses bestimmten DB ausgeführt. Dies ist die Situation ohne die Einführung von Clustern. Wie würde es aussehen, wenn zu diesem Zeitpunkt Cluster eingeführt würden? Wie Sie in Abbildung 1 sehen können, können die Regeln und Richtlinien auf unserem Router tatsächlich nur an eine bestimmte Gruppe weitergeleitet werden, das heißt, sie können nur an eine virtuelle Gruppe weitergeleitet werden. Bei dieser Gruppe handelt es sich nicht um einen bestimmten physischen Server. Als nächstes muss der spezifische physische DB-Server gefunden werden, um bestimmte Datenoperationen auszuführen. Basierend auf den Anforderungen dieses Links haben wir das Konzept des Load Balancers (LB) eingeführt. Die Verantwortung des Load Balancers besteht darin, einen bestimmten DB-Server zu finden. Die spezifischen Regeln lauten wie folgt: Der Load Balancer analysiert die Lese- und Schreibeigenschaften des aktuellen SQL. Wenn es sich um einen Schreibvorgang oder einen Vorgang handelt, der eine starke Echtzeitleistung erfordert, weist er die Abfragelast direkt dem Master zu. Wenn es sich um einen Lesevorgang handelt, wird er über die Lastausgleichsrichtlinie einem Slave zugewiesen. Die Hauptforschungsrichtung unseres Load Balancers ist die Lastverteilungsstrategie. Normalerweise umfasst der Lastausgleich zufälligen Lastausgleich und gewichteten Lastausgleich. Der zufällige Lastausgleich ist leicht zu verstehen, d. h. die zufällige Auswahl eines Slaves aus N Slaves. Bei einem solchen zufälligen Lastausgleich wird die Maschinenleistung nicht berücksichtigt. Standardmäßig wird die gleiche Leistung jeder Maschine verwendet. Wenn dies der Fall ist, ist daran nichts auszusetzen. Was ist, wenn dies nicht der Fall ist? Die physische Leistung und Konfiguration jeder Slave-Maschine ist unterschiedlich. Es ist sehr unwissenschaftlich, einen zufälligen Lastausgleich zu verwenden, ohne die Leistung zu berücksichtigen. Dies führt zu einer unnötig hohen Belastung von Maschinen mit schlechter Maschinenleistung und birgt sogar das Risiko von Ausfallzeiten Gleichzeitig können leistungsstarke Datenbankserver ihre physikalische Leistung nicht voll ausschöpfen. Basierend auf dieser Überlegung haben wir einen gewichteten Lastausgleich eingeführt, d. h. über eine bestimmte Schnittstelle in unserem System kann jedem DB-Server eine Gewichtung zugewiesen werden, und wenn er ausgeführt wird, wird LB entsprechend dem Gewichtungsanteil im Cluster zugewiesen . Ein gewisser Anteil der Last wird dem DB-Server übertragen. Natürlich wird die Einführung eines solchen Konzepts zweifellos die Komplexität und Wartbarkeit des Systems erhöhen. Es gibt Gewinne und Verluste, und es gibt für uns keine Möglichkeit, ihnen zu entkommen.

Wird nun, da wir Unterdatenbanken, Cluster und Load Balancer haben, alles gut? Die Dinge sind nicht so einfach, wie wir denken. Obwohl diese Dinge grundsätzlich sicherstellen können, dass unsere Datenschicht einem hohen Druck standhält, kann ein solches Design die Gefahren von Datenbankausfällen nicht vollständig vermeiden. Wenn Slave2 in Gruppe1 ausgefallen ist, kann der LB des Systems dies nicht wissen. Dies ist tatsächlich sehr gefährlich, da der LB nicht weiß, dass Slave2 verfügbar ist, und daher Slave2 weiterhin Last zuweist. Auf diese Weise treten Probleme auf, und der Client stößt natürlich auf Fehler oder Ausnahmen bei Datenoperationsfehlern. Das ist sehr unfreundlich! Wie kann dieses Problem gelöst werden? Wir führen einen Verfügbarkeitserkennungsmechanismus für Clusterknoten oder einen Verfügbarkeitsdaten-Push-Mechanismus ein. Was ist der Unterschied zwischen diesen beiden Mechanismen? Lassen Sie uns zunächst über den Erkennungsmechanismus sprechen. Wie der Name schon sagt, ist die Erkennung mein Datenschicht-Client, der von Zeit zu Zeit die Verfügbarkeit jeder Datenbank im Cluster prüft. Das Implementierungsprinzip ist die Testverknüpfung oder der Testzugriff auf den Datenbankport. Dies ist natürlich möglich. Sie können jedoch auch versuchen, eine Verbindung herzustellen und den Ausnahmemechanismus von Java zu verwenden, um die Verfügbarkeit zu beurteilen. Was ist also der Daten-Push-Mechanismus? Tatsächlich muss dieses Problem in einem realen Anwendungsszenario besprochen werden. Wenn die angewendete DB-Datenbank ausgefallen ist, wird der DBA dies meiner Meinung nach definitiv wissen Über das Programm wird zu diesem Zeitpunkt eine lokale DB-Statusliste auf der Anwendungsseite der verteilten Datenschicht aktualisiert. Und informieren Sie LB, dass dieser Datenbankknoten nicht verwendet werden kann. Weisen Sie ihm bitte keine Last zu. Einer ist ein aktiver Überwachungsmechanismus und der andere ist ein passiver Benachrichtigungsmechanismus. Beide haben ihre eigenen Vorzüge. Aber sie können alle den gleichen Effekt erzielen. Auf diese Weise wird das gerade angenommene Problem nicht auftreten. Selbst wenn es tatsächlich auftritt, wird die Wahrscheinlichkeit, dass es auftritt, minimiert.

Wir haben den im obigen Text erwähnten Master und Slave nicht ausführlich erklärt. Wie in Abbildung 1 dargestellt, besteht eine Gruppe aus 1 Master und N Slaves. Warum das tun? Der Master ist für die Auslastung der Schreiboperationen verantwortlich, das heißt, dass alle Schreiboperationen auf dem Master ausgeführt werden, während Leseoperationen dem Slave zugewiesen werden. Dies kann die Leseeffizienz erheblich verbessern. Bei allgemeinen Internetanwendungen kommt man nach einigen Datenerhebungen zu dem Schluss, dass das Lese-/Schreibverhältnis etwa 10:1 beträgt, was bedeutet, dass sich eine große Anzahl von Datenvorgängen auf Lesevorgänge konzentriert, weshalb wir mehrere Slave-Gründe haben. Aber warum sollte man Lesen und Schreiben trennen? F&E-Mitarbeiter, die mit DB vertraut sind, wissen alle, dass Schreibvorgänge mit Sperrproblemen verbunden sind, unabhängig davon, ob es sich um Zeilensperren, Tabellensperren oder Blocksperren handelt, die die Effizienz der Systemausführung relativ verringern. Unsere Trennung besteht darin, Schreibvorgänge auf einen Knoten zu konzentrieren, während Lesevorgänge auf anderen N-Knoten ausgeführt werden. Dadurch wird die Leseeffizienz effektiv verbessert und die hohe Verfügbarkeit des Systems sichergestellt. Die Trennung von Lesen und Schreiben wird auch neue Probleme mit sich bringen, z. B. wie ich die Daten auf meinem Master mit anderen Slave-Maschinen im Cluster synchronisieren und konsistent halten kann. Dies ist ein Problem, dem wir nicht allzu viel Aufmerksamkeit schenken müssen Der Proxy-Mechanismus kann uns dabei helfen. Da der Proxy-Mechanismus für dieses Thema nicht sehr relevant ist, werden wir ihn hier nicht im Detail vorstellen.

Zusammenfassend ist die allgemeine Funktion der in diesem Thema untersuchten verteilten Datenschicht folgende.


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn