Nachfragehintergrund Ein Teil der Daten in der Geschäftstabelle tb_image ist wie folgt, wobei die ID eindeutig ist, die image_no jedoch nicht. image_no stellt die Nummer jeder Datei dar. Jede Datei generiert mehrere Dateien im Geschäftssystem. Die eindeutige ID jeder Datei ist das Feld id: Einige Informationen zur Geschäftstabelle tb_image lauten wie folgt:
Lösungsauswahl Aufgrund der obigen Geschäftsanalyse ist eine Trennung von Datenbank und Tabellen völlig unnötig. Wenn eine einzelne Datenbank geteilt wird, besteht eine Lösung darin, redundantes Sharding zu verwenden (d. h. eine Kopie der Daten wird mit „image_no“ als Sharding-Schlüssel gespeichert und die andere Kopie der Daten wird mit „id“ als Sharding-Schlüssel gespeichert), da Abfragen auf „image_no“ und „id“ basieren müssen. Eine andere Lösung besteht darin, nur „image_no“ als Sharding-Schlüssel zu verwenden und die Geschäftsebene die Ergebnisse basierend auf den Abfrageanforderungen der ID zusammenzuführen oder Middleware von Drittanbietern einzuführen. Da es komplizierter ist, eine einzelne Datenbank in Tabellen aufzuteilen, haben wir uns für die Partitionierungsfunktion entschieden. Darüber hinaus kann die Kapazitätsbewertungslösung mit Partitionstabellen und 128 Partitionen (jede Partition hat ein Datenvolumen auf kw-Ebene) vollständig sicherstellen, dass das Geschäft mindestens 15 Jahre lang stabil läuft (der orangefarbene Teil in der Abbildung entspricht eher dem tatsächlichen Wachstum unseres Geschäfts): Da RANGE-, LIST- und HASH-Partitionen keine VARCHAR-Spalten unterstützen, wird außerdem entschieden, KEY-Partitionen zu verwenden. Die offizielle Einführung ihres Prinzips besteht darin, den in MySQL integrierten Hash-Algorithmus zu verwenden und dann den Modul der Partitionsnummer zu nehmen. Leistungstests Nachdem Sie den Shard-Schlüssel als image_no ausgewählt und 128 Partitionen festgelegt haben, ist es an der Zeit, Daten für Machbarkeits- und Leistungstests zu laden. Der Grund, warum die Anzahl der Partitionen auf 128 festgelegt wurde, ist: 1,1 Milliarden/1 kW = 110 ≈ 128. Außerdem verwenden Programmierer gerne die Zweierpotenz, wie Sie wissen. Der Albtraum beginnt jedoch mit der Partitionsnummer 128. Ich habe versucht, 100.000 Daten in 128 Partitionen einzufügen. Nach dem Einfügen trat ein überraschendes Phänomen auf: In allen ungeraden Partitionen (p1, p3, p5, …, p2n-1) waren keine Daten vorhanden. Gleichzeitig enthielt jede gerade nummerierte Partition viele Daten, und sie war nicht sehr gleichmäßig. Wie in der folgenden Abbildung dargestellt: Hinweis: Die IBD-Dateigröße von Partitionen mit ungeraden Nummern beträgt 112 KB. Dies ist die Initialisierungsgröße beim Erstellen der Partitionstabelle. Tatsächlich sind keine Daten vorhanden. Wir können dies mit SQL überprüfen: select partition_name, partition_expression, table_rows from information_schema.partitions where table_schema = schema() and table_name='image_subpart' ;, und einige der Ergebnisse werden in der folgenden Abbildung angezeigt: Reichen 100.000 Daten nicht aus, um das Problem zu veranschaulichen? Im Durchschnitt enthält jede Partition fast 800 Datenelemente! Ok, machen wir etwas drastisches: Ich werde weitere 990-W-Daten einfügen, also insgesamt 1 kW Daten. Das Ergebnis ist immer noch dasselbe: Partitionen mit ungeraden Nummern haben keine Daten und Partitionen mit geraden Nummern haben Partitionen. Fragen zum Nachdenken Erinnern wir uns an das Prinzip der KEY-Partitionierung: Berechnen Sie den Hash-Wert des Shard-Schlüssels mit dem in MySQL integrierten Hash-Algorithmus und nehmen Sie dann den Modul der Partitionsnummer. Dieses Prinzip ist auch auf der offiziellen MySQL-Website zu finden. Klicken Sie bitte auf den Link: 22.2.5 KEY-Partitionierung: https://dev.mysql.com/doc/refman/5.7/en/partitioning-key.html. Der Originaltext lautet wie folgt:
**So einen beschissenen Hash-Algorithmus kann es auf der Welt doch nicht geben, oder? **Egal welchen Algorithmus Sie schreiben, es wird nicht so ungleichmäßig sein, oder? Derzeit frage ich mich, ob es eine Konfiguration ist, die die Ursache dafür ist. In den Anzeigevariablen sind jedoch keine partitionsbezogenen Variablen enthalten. Zu dieser Zeit galoppierten zehntausend Pferde vorbei. Könnte es sein, dass Dokument und Quellcode nicht synchron sind? Schauen wir uns doch einmal den MySQL-Quellcode an. Schließlich kommt der Quellcode der Wahrheit am nächsten. Der Quellcode für die KEY-Partition befindet sich in der Datei sql_partition.cc. Der Autor hat einige Schlüsselquellcodes abgefangen, wie unten gezeigt. Auf den ersten Blick ist nichts falsch. Berechnen Sie zuerst den Hashwert des Partitionsfelds und nehmen Sie dann den Modul der Partitionsnummer: /** Berechnen Sie die part_id für (SUB)PARTITION BY KEY @param Dateihandler zur Speicher-Engine @param field_array Array von Feldern für PARTTION KEY @param num_parts Anzahl der KEY-Partitionen @param func_value[out] Gibt den berechneten Hashwert zurück @return Berechnete Partitions-ID */ im Einklang statische uint32 get_part_id_key(handler *datei, Feld **field_array, uint Anzahl_Teile, lang lang *Funktionswert) { DBUG_ENTER("Teile-ID-Schlüssel abrufen"); // Berechnen Sie den Hash-Wert des Partitionsfelds *func_value = file->calculate_key_hash_value(field_array); // Modulo die Anzahl der Partitionen DBUG_RETURN((uint32) (*func_value % num_parts)); } Wenn Sie verzweifelt sind, suchen Sie bitte in der Suchmaschine nach „uneven KEY partition data“. Im CSDN-Forum (https://bbs.csdn.net/topics/390857704) gibt es in den Suchergebnissen einen Volksmeister, Hua Xia Xiao Zu, der wie folgt antwortete: Ein Kollege hat die Kennwortfunktion analysiert und gemessen und festgestellt, dass bei der Schlüsselpartitionierung die Anzahl der Partitionen nur als Primzahl angegeben werden kann, um sicherzustellen, dass jede Partition Daten enthält. Ich habe es getestet, von 11 Partitionen bis 17 Partitionen. Nur die Daten in den Partitionen 11, 13 und 17 sind grundsätzlich gleichmäßig verteilt. Zu dieser Zeit galoppierten weitere zehntausend Pferde vorbei. Aber während ich mich fragte, WAS ZUM F**K, war ich auch ein wenig aufgeregt, weil ich vielleicht eine Lösung gefunden hatte (obwohl ich immer noch nicht weiß, warum sich der eingebaute Hash-Algorithmus von MySQL so verhält). Schließlich testete ich die KEY-Partition erneut und kam zu folgendem Schluss:
Wie in der folgenden Abbildung dargestellt, ist dies die Situation, nachdem der Autor die Anzahl der Partitionen auf 127 angepasst und 1 Million Daten eingefügt hat. SQL beweist, dass die Datenmenge in jeder Partition nahezu gleich ist: Zusammenfassung Ich war schockiert, als ich erfuhr, dass es keine offizielle Erklärung für die enormen Fallstricke bei der Verwendung der KEY-Partition von MySQL gibt. Darüber hinaus gibt es einen MySQL-Fehler: Fehler Nr. 72428 Partitionierung durch KEY() führt zu ungleichmäßiger Datenverteilung Studierende, die diesen Artikel lesen und großes Interesse haben, können versuchen, tiefer in dieses Thema einzutauchen. Der Autor wird sich auch die Zeit nehmen, tiefer in den MySQL-Quellcode einzutauchen, um herauszufinden, warum die Implementierung des Hash-Algorithmus so empfindlich auf die Anzahl der Partitionen reagiert. Dies ist das Ende dieses Artikels über den blutigen Fall, der durch die KEY-Partitionierung von MySQL-Lerndatensätzen verursacht wurde. Weitere relevante Inhalte zum blutigen Fall der MySQL-KEY-Partitionierung finden Sie in den vorherigen Artikeln von 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, dass jeder 123WORDPRESS.COM in Zukunft unterstützen wird! Das könnte Sie auch interessieren:
|
<<: Erläuterung zu JavaScript-Anti-Shake und -Throttling
>>: Docker Compose-Installationsmethoden in verschiedenen Umgebungen
clip-path CSS-Eigenschaften verwenden Clipping, u...
Inhaltsverzeichnis 1. Übersicht 1.1 Verwendung vo...
Der erste Schritt besteht darin, das komprimierte...
Inhaltsverzeichnis 1. Schnittstelle zusammenführe...
Das Feld im JSON-Format ist ein neues Attribut, d...
Inhaltsverzeichnis Umgebungsbeschreibung Installi...
In diesem Artikelbeispiel wird der spezifische Ja...
Inhaltsverzeichnis Überblick 1. Einfaches Beispie...
<br />Hier ergibt sich ein Widerspruch: In k...
Die Methode hasOwnProperty() des Objekts gibt ein...
Vorwort Dieser Artikel stellt hauptsächlich die r...
Wenn wir eine neue CSS-Funktion verwenden möchten...
Unter Graustufenfreigabe versteht man eine Freiga...
Unter den klassischen Farbkombinationen kann wohl...
Inhaltsverzeichnis Vererbung und Prototypenkette ...