Heim >PHP-Framework >Laravel >Laravel verteilte die Verwendung eines eindeutigen ID-Generators

Laravel verteilte die Verwendung eines eindeutigen ID-Generators

Guanhui
Guanhuinach vorne
2020-06-17 17:20:545320Durchsuche

Laravel verteilte die Verwendung eines eindeutigen ID-Generators

In Anwendungen wird häufig eine weltweit eindeutige ID als Datenbank-Primärschlüssel benötigt. Wie generiert man eine weltweit eindeutige ID?

Zunächst müssen Sie feststellen, ob die global eindeutige ID eine Ganzzahl oder eine Zeichenfolge ist? Wenn es sich um eine Zeichenfolge handelt, erfüllt die vorhandene UUID die Anforderungen vollständig und es sind keine zusätzlichen Arbeiten erforderlich. Der Nachteil besteht darin, dass Zeichenfolgen als IDs viel Platz beanspruchen und die Indizierungseffizienz geringer ist als bei Ganzzahlen.

Wenn als ID eine Ganzzahl verwendet wird, wird zunächst der 32-Bit-int-Typ ausgeschlossen. Da der Bereich zu klein ist, muss der 64-bit-long-Typ verwendet werden.

Wie generiert man bei Verwendung von Ganzzahlen als IDs sich selbst erhöhende, global eindeutige und sich nicht wiederholende IDs?

Option 1: Mithilfe der sich selbst erhöhenden ID der Datenbank, beginnend bei 1, kann grundsätzlich eine kontinuierliche Inkrementierung erreicht werden. Oracle kann SEQUENCE verwenden, und MySQL kann AUTO_INCREMENT für Primärschlüssel verwenden. Obwohl es keine globale Eindeutigkeit garantieren kann, ist es für jede Tabelle eindeutig und erfüllt grundsätzlich die Anforderungen.

Der Nachteil der selbsterhöhenden ID in der Datenbank besteht darin, dass die ID nicht abgerufen werden kann, bevor die Daten eingefügt werden. Nach dem Einfügen der Daten ist die erhaltene ID zwar eindeutig, wird jedoch erst nach Übermittlung der Transaktion als gültig angesehen. Einige bidirektional referenzierte Daten müssen eingefügt und dann aktualisiert werden, was mühsam ist.

Die zweite Möglichkeit besteht darin, einen zentralen ID-Generator zu verwenden, bei dem es sich um Redis oder ZooKeeper handeln kann, oder Sie können eine Datenbanktabelle verwenden, um die zuletzt zugewiesene ID aufzuzeichnen.

Der größte Nachteil dieser Methode besteht darin, dass sie zu komplex ist, eine starke Abhängigkeit von Drittanbieterdiensten erfordert und die Codekonfiguration umständlich ist. Im Allgemeinen gilt: Je komplexer die Lösung, desto weniger zuverlässig ist sie und desto aufwendiger ist das Testen.

Die dritte Methode ähnelt dem Snowflake-Algorithmus von Twitter, der jeder Maschine eine eindeutige ID zuweist und dann über Zeitstempel + ID + automatische Inkrementierung eine global eindeutige ID implementiert. Der Vorteil dieser Methode besteht darin, dass der ID-Generierungsalgorithmus eine vollständig zustandslose Maschine ist, keine Netzwerkaufrufe hat und effizient und zuverlässig ist. Der Nachteil besteht darin, dass es bei der Wiederholung eindeutiger Bezeichner zu ID-Konflikten kommt.

Der Snowflake-Algorithmus verwendet einen 41-Bit-Millisekunden-Zeitstempel plus 10-Bit-Maschinen-ID und 12-Bit-Seriennummer. Theoretisch kann er bis zu 1024 Maschinen unterstützen, um 4096000 Seriennummern pro Sekunde zu generieren, was für die Größe von Twitter ausreicht. .

Für die meisten normalen Anwendungen sind jedoch nicht mehr als 4 Millionen IDs pro Sekunde erforderlich, und die Anzahl der Maschinen erreicht nicht 1024. Daher können wir sie verbessern und eine kürzere ID-Generierungsmethode verwenden:

53bitID ​​​​besteht aus einem 32-Bit-Zeitstempel der zweiten Ebene + 16-Bit-Autoinkrement + 5-Bit-Maschinenidentifikation. Es akkumuliert 32 Maschinen und kann 65.000 Seriennummern pro Sekunde generieren:

private static synchronized long nextId(long epochSecond) {
    if (epochSecond < lastEpoch) {
        // warning: clock is turn back:
        logger.warn("clock is back: " + epochSecond + " from previous:" + lastEpoch);
        epochSecond = lastEpoch;
    }
    if (lastEpoch != epochSecond) {
        lastEpoch = epochSecond;
        reset();
    }
    offset++;
    long next = offset & MAX_NEXT;
    if (next == 0) {
        logger.warn("maximum id reached in 1 second in epoch: " + epochSecond);
        return nextId(epochSecond + 1);
    }
    return generateId(epochSecond, next, SHARD_ID);}

Der Zeitstempel ist subtrahiert um einen festen Wert. Diese Lösung kann bis zu 2106 unterstützen.

Was ist, wenn 65.000 Seriennummern pro Sekunde nicht ausreichen? Es spielt keine Rolle, Sie können den Zeitstempel weiter erhöhen und die 65.000 Sequenznummern für die nächste Sekunde „ausleihen“.

Gleichzeitig wird auch das Problem der Zeitrückwahl gelöst.

Die Maschinenidentifikation verwendet ein einfaches Hostnamenschema. Solange der Hostname mit host-1 übereinstimmt, kann host-2 die Maschinenidentifikation automatisch extrahieren, ohne dass eine Konfiguration erforderlich ist.

Warum schließlich bis zu 53-Bit-Ganzzahlen anstelle von 64-Bit-Ganzzahlen verwenden? Dies liegt daran, dass es sich bei den meisten Anwendungen um Webanwendungen handelt. Wenn Sie mit JavaScript arbeiten möchten, beträgt die von JavaScript maximal unterstützte Ganzzahl 53 Ziffern. Darüber hinaus verliert JavaScript an Genauigkeit. Daher kann eine 53-Bit-Ganzzahl direkt von JavaScript gelesen werden. Wenn sie jedoch 53 Bit überschreitet, muss sie in einen String umgewandelt werden, um eine korrekte Verarbeitung durch JavaScript sicherzustellen, was zu zusätzlicher Komplexität der API-Schnittstelle führt. Dies ist auch der Grund, warum die API-Schnittstelle von Sina Weibo sowohl id als auch idstr zurückgibt.

Empfohlene Tutorials: „PHP“ „Laravel-Tutorial

Das obige ist der detaillierte Inhalt vonLaravel verteilte die Verwendung eines eindeutigen ID-Generators. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:learnku.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen