-
Die
vorliegende Erfindung bezieht sich auf eine Gleichzeitigkeitssteuerung
für einen
gemeinschaftlich verwendeten Zugriff einer Computerressource durch
kommunizierende Entitäten
und insbesondere auf eine effiziente, robuste, verteilte Mietverriegelung.
-
Bei
der anfänglichen
Entwicklung und schnellen Reifung elektronischer Kommunikationssysteme,
einschließlich
sowohl Kommunikationsmedien als auch Systemen, die intern innerhalb
Computersystemen eingegliedert sind, sowie Kommunikationsmedien
und Systemen, die gesonderte Computersysteme verbinden, wurde eine
breite Vielfalt von Verteilt-Anwendungsebene-
und Systemsoftware entwickelt, um eine gleichzeitige und simultane,
parallele Ausführung
von Prozessen zu ermöglichen,
die räumlich
und zeitlich innerhalb Computersystemen und unter verbundenen Prozessoren
und verbundenen Computersystemen verteilt sind. Zusätzlich können auch
verbundene Verarbeitungsentitäten,
wie beispielsweise Hardwaresysteme, die durch Logikschaltungen,
Firmware oder eine Kombination von Logikschaltungen und Firmware
gesteuert sind, parallel auf eine zusammenwirkende Weise laufen.
-
Bei
verteilten Systemen können
mehrere Prozesse und/oder Verarbeitungsentitäten verschiedene Vorrichtungs-
und Rechenressourcen, die über ein
Kommunikationssystem wie ein Computernetzwerk zugreifbar sind, gemeinschaftlich
verwenden. Damit verteilte Systeme ordnungsgemäß funktionieren, muss eine
gleichzeitige und simultane Konkurrenz durch mehrere Prozesse und/oder
Verarbeitungsentitäten
um Vorrichtungen und Rechenressourcen gesteuert werden, um einen
ungesteuerten, gleichzeitigen oder simultanen Zugriff auf Vorrichtungen
und Rechenressourcen zu verhindern, der zu Zeitabhängigkeiten
und einem nicht-deterministischen Verhalten führt. Derartige Zeitabhängigkeiten können zu
vielen unterschiedlichen pathologischen Befunden führen, einschließlich einer
Datenverfälschung,
Prozessabstürzen,
einer Systemblockierung und einer Prozessaushungerung. Es wurden
viele unterschiedliche Techniken zum Erleichtern eines gemeinschaftlichen
Verwendens von verteilten Ressourcen durch miteinander kommunizierende
Prozesse entwickelt. Gegenwärtig
verfügbare
Techniken weisen jedoch Zeitabhängigkeiten
bei Kommunikationsnachrichtensendung und -empfang auf und sind deshalb
verletzlich für
die Launen von Kommunikationssendeverzögerungen, einer Prozessinstabilität und anderen
Problemen, die bei einem verteilten System der realen Welt entstehen.
Außerdem
betreffen viele der Protokolle eines gemeinschaftlichen Verwendens
verteilter Ressourcen Nachrichtenaustauschineffizienzen, was einen
erheblichen Nachrichtenverkehr erfordert, um einen gemeinschaftlich verwendeten
Zugriff auf Vorrichtungs- und Rechenressourcen zu koordinieren.
Hersteller, Verkäufer, Entwickler
und Benutzer von verteilten Systemen suchen deshalb weiterhin nach
zuverlässigen,
robusten und effizienten Verfahren zum gemeinschaftlichen Verwenden
von verteilten Ressourcen.
-
Es
ist die Aufgabe der vorliegenden Erfindung, eine verteilte Verriegelung,
die kollektiv durch eine Anzahl miteinander kommunizierender Entitäten implementiert
ist, und ein Verfahren zum Steuern eines Zugriffs auf eine Ressource
durch mehrere gleichzeitig oder simultan zugreifende Entitäten mit verbesserten
Charakteristika zu schaffen.
-
Diese
Aufgabe wird durch eine verteilte Verriegelung gemäß Anspruch
1 und ein Verfahren gemäß Anspruch
21 gelöst.
-
Verschiedene
Ausführungsbeispiele
der vorliegenden Erfindung sind auf eine verteilte Verriegelung
und ein Verteilte-Verriegelung-Protokoll gerichtet, um zu ermöglichen,
dass mehrere kommunizierende Entitäten einen Zugriff auf eine
Rechenressource gemeinschaftlich verwenden. Bestimmte Ausführungsbeispiele
der vorliegenden Erfindung verwenden ein Datenspeicherungsregister,
das durch die kommunizierenden Entitäten implementiert ist.
-
Bevorzugte
Ausführungsbeispiele
der vorliegenden Erfindung werden nachfolgend Bezug nehmend auf
die beiliegenden Zeichnungen näher
erläutert.
Es zeigen:
-
1 ein
Beispiel eines verteilten Rechensystems;
-
2 – 3 einen
einfachen Typ eines Gleichzeitigkeitsproblems, das bei verteilten
Computersystemen angetroffen wird;
-
4 – 7 das
Konzept eines Verriegelns;
-
8 – 10 eines
der vielen Probleme, die bei verteilten Systemen entstehen, die
verteilte Verriegelungen auf naive Weise einsetzen, um einen Zugriff
auf Ressourcen durch miteinander kommunizierende Prozesse, die auf
verteilten Verarbeitungsentitäten
laufen, zu serialisieren;
-
11 – 17 den
grundlegenden Betrieb eines Speicherungsregisters, unter Verwendung
von Darstellungskonventionen, die in den 4 – 10 verwendet
werden;
-
18 die
Komponenten, die durch einen Prozess oder eine Verarbeitungsentität Pi verwendet werden, die zusammen mit einer
Anzahl anderer Prozesse und/oder Verarbeitungsentitäten Pj≠i ein
verteiltes Speicherungsregister implementiert;
-
19 eine
Bestimmung des aktuellen Werts eines verteilten Speicherungsregisters
mittels einer beschlussfähigen
Anzahl bzw. eines Quorums;
-
20 Pseudocode-Implementierungen
für die
Routinenhandhabungseinrichtungen und Operationsroutinen, die in 18 schematisch
gezeigt sind;
-
21 ein
Verteilte-Verriegelung-Protokoll, das auf einem verteilten Speicherungsregister
basiert, das ein Ausführungsbeispiel
der vorliegenden Erfindung darstellt;
-
22 ein
einfaches Verteilte-Verriegelung-Protokoll, das durch eine Routine „leaseResource" (Ressource mieten)
implementiert wird, die ein Ausführungsbeispiel
der vorliegenden Erfindung darstellt; und
-
23 eine
alternative, komplexere Implementierung der Routine „leaseResource", die ein alternatives
Ausführungsbeispiel
der vorliegenden Erfindung darstellt.
-
Ausführungsbeispiele
der vorliegenden Erfindung sind auf Verteilte-Verriegelung-Protokolle
gerichtet. Verteilte-Verriegelung-Protokolle
finden bei einer Implementierung verteilter Systeme, einschließlich verteilter
Anwendungen und verteilter Systemsoftware, Verwendung. Verteilte-Verriegelung-Protokolle
können
ferner innerhalb eines einzigen Computersystems Verwendung finden,
bei dem Prozesse und Verarbeitungsentitäten gleichzeitig oder simultan
auf gemeinschaftlich verwendete Ressourcen über nachrichtenbasierte Transaktionen
zugreifen, einschließlich
Paketen, die über
Busse gesendet werden, oder gemeinschaftlich verwendeter Speichernachrichten.
-
1 zeigt
ein Beispiel eines verteilten Rechensystems. Das verteilte Rechensystem
umfasst fünf
unterschiedliche Computersysteme 102 – 106, von denen zwei
große,
lokale Massenspeicherungsvorrichtungen 107 und 108,
ein Plattenarray 110 und einen High-End-Leitknoten bzw.
-Führungsknoten 112 aufweisen,
der die Verarbeitungsentitäten
und das Plattenarray mit zusätzlichen,
entfernten Computersystemen, Massenspeicherungsvorrichtungen und
anderen elektronischen Vorrichtungen verbindet. Bei einem verteilten
Netzwerksystem, wie beispielsweise diesem, das in 1 gezeigt
ist, werden Daten zwischen Prozessen und/oder Verarbeitungsentitäten, dem
Plattenarray und dem Router-Knoten durch eines oder mehrere Computernetzwerke 114 ausgetauscht.
Es werden viele unterschiedliche Typen von Computernetzwerken für derartige
Zwecke eingesetzt, einschließlich
High-End-Faserkanal-Verbindungen,
Ethernet-Verbindungen und vieler anderer Typen von Vernetzungssystemen
und -medien, die eine Vielfalt unterschiedlicher Protokolle und
Konfigurationen einsetzen und die gemäß einer Vielfalt unterschiedlicher
Nachrichtensendungsverfahren wirksam sind, einschließlich einer
busähnlichen
Sendung, einer ringähnlichen
Sendung, einer Punkt-zu-Punkt-Sendung und anderer Verfahren. Bei einem
verteilten System, wie beispielsweise dem verteilten System, das
in 1 gezeigt ist, können Prozesse, die simultan
oder gleichzeitig auf unterschiedlichen Computersystemen laufen,
eine oder mehrere Ressourcen gemeinschaftlich verwenden. Zum Beispiel
können
Prozesse, die sowohl auf dem Computersystem 102 als auch
auf dem Computersystem 103 laufen, auf die Massenspeicherungsvorrichtung 107 des
Computersystems 103 zugreifen. Als ein weiteres Beispiel
können
Prozesse, die auf allen der Computersysteme laufen, spezielle Speicherungsdatenträger bzw.
-volumen gemeinschaftlich verwenden, die durch das Plattenarray 110 vorgesehen
sind. Es ist zu beachten, dass ein Computersystem, wie beispielsweise
das Computersystem 102 einen bis zu einer großen Anzahl
einzelner Computerprozessoren umfassen kann und eine gleichzeitige
Ausführung
von Tausenden von Prozessen und eine simultane Ausführung von
Zig bis Hunderten von Prozessen unterstützen kann. Datenressourcen
sind lediglich ein Beispiel gemeinschaftlich verwendeter Ressourcen.
Es können
viele andere Typen von Ressourcen gemeinschaftlich verwendet werden.
Zum Beispiel können
bei verteilten Betriebssystemen Prozessoren innerhalb von Verarbeitungsentitäten durch logische
Verarbeitungsbereiche innerhalb des verteilten Betriebssystems gemeinschaftlich
verendet werden. Dateneingabe- und Ausgabevorrichtungen können zwischen
Verarbeitungsentitäten
gemeinschaftlich verwendet werden, Kommunikationsvorrichtungen können durch
mehrere Prozesse gemeinschaftlich verwendet werden und viele andere
Typen von Vorrichtungen, sowohl physisch als auch logisch, können unter
verteilten Prozessen gemeinschaftlich verwendet werden sowie auf
andere Typen von Vorrichtungen aktiv zugreifen und dieselben gemeinschaftlich
verwenden.
-
Ein
gemeinschaftliches Verwenden verteilter Ressourcen durch verteilte
Prozesse betrifft eine Verwaltung vieler unterschiedlicher Typen
von Gleichzeitigkeitsproblemen. 2 – 3 stellen
einen einfachen Typ eines Gleichzeitigkeitsproblems dar, das bei
verteilten Computersystemen angetroffen wird. An dem oberen Ende
der 2 ist eine Darstellung eines Abschnitts einer
Datenspeicherungsressource 202 gezeigt. Die Datenblöcke der
Datenspeicherungsressource, wie beispielsweise ein Datenblock 204,
sind logisch sequentiell in der Datenspeicherungsvorrichtung geordnet.
Ein Abschnitt der Datenressource, die in 2 dargestellt
ist, umfasst 13 Datenblöcke,
die sequentiell als Datenblöcke 73 – 85 adressiert
sind. Ein erster Prozess, der auf einer Verarbeitungsentität läuft, muss
drei aufeinanderfolgende Datenblockwerte 206, die in 2 durch
die Symbole „A", „B" und „C" dargestellt sind,
in den Blöcken der
Daten- und Speicherungsressource 78, 79 und 80 speichern.
Ein zweiter Prozess muss drei unterschiedliche Datenblockwerte 208,
die in 2 durch die Symbole „X", „Y" und „Z" dargestellt sind,
in den gleichen drei aufeinanderfolgenden Datenblöcken der
Datenspeicherungsressource 78 – 80 speichern. Bei
diesem Beispiel konkurrieren sowohl der erste als auch der zweite
Prozess um die Datenblöcke 78 – 80 der
Datenstruktur. Eines von zwei möglichen
Ergebnissen dieser Konkurrenz ist gültig und annehmbar. Ein Ergebnis
ist, dass der erste Prozess die Datenblockwerte „A", „B" und „C" zu den Datenblöcken 78 – 80 der
Datenressource 210 schreibt. Dies kann entweder in dem
Fall, dass der zweite Prozess die Datenblockwerte „X", „Y" und „Z" nicht zu der Datenspeicherungsressource
schreibt oder der zweite Prozess diese Datenblockwerte erfolgreich
zu der Datenspeicherungsressource schreibt, aber diese Datenblockwerte
dann mit den Datenblockwerten „A", „B" und „C" durch den ersten
Prozess überschrieben
werden, auftreten. Auf ähnliche
Weise ist ein zweites gültiges und
annehmbares Ergebnis 212, dass der zweite Prozess die Datenblockwerte „X", „Y" und „Z" erfolgreich zu den
Datenblöcken 78 – 80 der
Datenspeicherungsressource schreibt.
-
Es
gibt jedoch viele ungültige
und unannehmbare Ergebnisse der Konkurrenz, um einen Zugriff auf
die Datenspeicherungsressource durch den ersten und den zweiten
Prozess, einschließlich
eines Ergebnisses 214, bei dem der zweite Prozess es geschafft
hat, die Datenblockwerte „X" und „Y" zu den Blöcken 78 – 79 der
Datenspeicherungsressource zu schreiben, und der erste Prozess den
Wert „C" erfolgreich zu dem
Datenblock 80 der Datenspeicherungsressource geschrieben
hat. Das ungültige
und unannehmbare Ergebnis 214 in 2 ist lediglich
ein Beispiel vieler ungültiger
und unannehmbarer Ergebnisse, die aus der Konkurrenz um die gemeinschaftlich verwendete
Datenspeicherungsressource durch die Prozesse resultieren können.
-
3 stellt
eine Sequenz von Ereignissen dar, die zu dem ungültigen und unannehmbaren Ergebnis 214 in 2 führen können. Zuerst
schreibt der erste Prozess den Datenblockwert „A" zu dem Block 78 der gemeinschaftlich
verwendeten Datenspeicherungsressource 302. Dann schreibt
bei einer zweiten SCHREIBEN-Operation der erste Prozess den Datenblockwert „B" zu dem Block 79,
der gemeinschaftlich verwendeten Datenspeicherungsressource 304.
Als nächstes überschreibt
der zweite Prozess den Datenblock 78 mit dem Datenblockwert „X" 306. Dann überschreibt
der zweite Prozess den Datenblock 79 mit dem Datenblockwert „Y" 308. Dann schreibt
der zweite Prozess den Datenblock „Z" zu dem Datenblock 80 310.
Schließlich überschreibt der
erste Prozess den Datenblock 80 mit dem Datenblockwert „C" 312.
-
Das
in 2 – 3 dargestellte
Problem ist ein häufiges
Problem, das bei Datenbankverwaltungssystemen und gemeinschaftlich
verwendeten Dateisystemen entsteht. Die Datenblöcke 78 – 80 kann
man sich als eine große
Datenaufzeichnung speichernd vorstellen, von der unterschiedliche
Teile Referenzen zu anderen Teilen der Datenaufzeichnung oder anderen
Daten enthalten, die anderswo in der Datei gespeichert sind. Falls
Abschnitte der großen
Datenaufzeichnung mit inkonsistenten Daten überschrieben werden, wird die
Datenaufzeichnung als Ganzes inkonsistent und kann zu kaskadierenden Datenfehlern
durch nachfolgende Zugriffsoperationen führen und kann in schlimmeren
Fällen
zu einer Verfälschung
einer Datenbank oder eines Dateisystems und zu Abstürzen von
Prozessen, die auf die Daten zugreifen, führen.
-
Um
die verschiedenen Typen von ungültigen und
unannehmbaren Ergebnissen einer Ressourcenkonkurrenz wie dem in
den 2 – 3 dargestellten
Beispiel eines verfälschten
Datenblocks zu verhindern, wurden viele Techniken eingesetzt. Eine Technik
betrifft ein Verriegeln bzw. Sperren einer Ressource durch einen
Prozess, bevor durch den Prozess auf die Ressource zugegriffen wird. 4 – 7 stellen
das Konzept eines Verriegelns dar. Alle der 4 – 7 und
nachfolgende Figuren verwenden identische Darstellungskonventionen,
die im Interesse einer Kürze
lediglich für 4 beschrieben sind. 4 zeigt
fünf Computersysteme 402 – 406, die
durch ein Kommunikationsnetzwerk 408 miteinander und mit
einer gemeinschaftlich verwendeten Ressource R 410 verbunden
sind, auf die durch Prozesse zugegriffen wird, die auf den Computersystemen
laufen. Um die Ressource zu verriegeln, sendet ein Prozess P2, der auf der zweiten Verarbeitungsentität läuft, eine
Nachricht 412 zu anderen Prozessen, um anzugeben, dass
der Prozess P2 beabsichtigt, die Ressource
R für einen
Zugriff zu verriegeln. Wenn der Prozess P2 einmal
bestimmt, dass die Nachricht 412 erfolgreich gesendet ist,
betrachtet der Prozess P2 die Ressource
R 410 als für
einen ausschließlichen
Zugriff durch den Prozess P2 verriegelt,
was in 5 durch den gestrichelten Kreis 502 angegeben ist,
der die Ressource R umgibt. Wenn der Prozess P2 ein
Zugreifen auf die Ressource R einmal beendet, sendet der Prozess
P2 eine Entriegelungsnachricht 602 zu
den anderen Prozessen, wie es in 6 gezeigt
ist. Wie es in 7 gezeigt ist, betrachtet, wenn
der Prozess P2 einmal bestimmt, dass die
Entriegelungsnachricht erfolgreich gesendet wurde, der Prozess P2 die Verriegelung an der Ressource R als entfernt.
-
Leider
ist ein verteiltes Verriegeln von Ressourcen voll mit vielen möglichen
Problemen. 8 – 10 stellen
eines der vielen Probleme dar, die bei verteilten Systemen entstehen,
die verteilte Verriegelungen auf naive Weise einsetzen, um einen
Zugriff auf Ressourcen durch miteinander kommunizierende Prozesse,
die auf verteilten Verarbeitungsentitäten laufen, zu serialisieren.
In 8 wählt
der Prozess P2 802, auf eine Ressource
R 804 zuzugreifen, wobei zuerst eine Verriegelungsnachricht 806 durch das
Netzwerk zu anderen Prozessen gesendet wird, die auf anderen Computersystemen
laufen. Der Prozess P4 jedoch, der ebenfalls
auf die Ressource R zugreift, läuft
gegenwärtig
nicht 808. Wie es in 9 gezeigt
ist, betrachtet, wenn der Prozess P2 einmal bestimmt,
dass die Verriegelungsnachricht erfolgreich gesendet wurde, der
Prozess P2 die Ressource R als verriegelt 902.
An diesem Punkt beginnt der Prozess P4 804 wieder
zu laufen und entscheidet sich, auf die Ressource R zuzugreifen.
Weil der Prozess P4 nicht lief, als der
Prozess P2 802 die Verriegelungsnachricht
sendete, ist sich der Prozess P4 nicht dessen
bewusst, dass der Prozess P2 die Ressource
R als verriegelt betrachtet. Deshalb sendet der Prozess P4 eine Verriegelungsnachricht 904 zu den
anderen Prozessen, die auf den anderen Computersystemen laufen.
Wie es in 10 gezeigt ist, betrachtet,
wenn der Prozess P4 bestimmt, dass die Verriegelungsnachricht
erfolgreich gesendet wurde, der Prozess P4 die
Ressource R als verriegelt 1002 durch den Prozess P4 trotz der Tatsache, dass der Prozess P2 die Ressource R als verriegelt 902 durch den
Prozess P2 betrachtet. Beide Prozesse P2 und P4 konkurrieren
dann gleichzeitig um die Ressource R, was möglicherweise zu Problemen führt, wie
beispielsweise dem in 3 dargestellten Problem.
-
Es
gibt viele naive, mögliche
Lösungen
für das
oben in 8 – 10 dargestellte
Problem. Wenn z. B. der Prozess P2 eine
Verriegelungsnachricht von dem Prozess P4 empfängt, könnte der
Prozess P2 dann eine Warnnachricht zu dem
Prozess P4 senden, wobei der Prozess P4 informiert wird, dass der Prozess P2 die Ressource R als verriegelt betrachtet.
Diese Nachricht könnte
jedoch verloren oder verzögert
werden, wobei ermöglicht
wird, dass beide Prozesse P2 und P4 gleichzeitig um die Ressource R konkurrieren.
Eine andere Lösung
könnte
darin bestehen, eine Verarbeitungsentität einer Ressource R zuzuordnen
und zu ermöglichen,
dass die zugeordnete Verarbeitungsentität eine Verriegelung im Namen
der Ressource R verwaltet, wobei alle Verriegelungsanforderungen
eingereiht werden, um eine gleichzeitige Konkurrenz um die Ressource
R zu verhindern. Es kann jedoch der Fall sein, dass der Prozess
P2 aufeinander folgend eine Verriegelung
an der Ressource R erhält
und dann abstürzt.
Die Ressource R bleibt dann verriegelt, während die Ressource unbenutzt
ist, wobei verhindert wird, dass andere Prozesse auf die Ressource
R zugreifen, obwohl der Prozess P2 nicht
läuft.
Der Prozess P2 kann schlimmer noch wieder
starten und die Tatsache vergessen haben, dass der Prozess P2 in einer vorhergehenden Inkarnation die
Ressource R verriegelt hatte, und ist deshalb selbst nicht in der
Lage, auf die Ressource R zuzugreifen. Ein Versuch, derartige Probleme
zu handhaben, kann darin bestehen, Verriegelungen in der Verarbeitungsentität, die der
Ressource R zugeordnet ist, einen Zeitgeber zuzuordnen, so dass
Verriegelungen automatisch nach einer spezifizierten Zeitperiode
ablaufen. Wenn jedoch die Verriegelung abläuft, muss ein Prozess, der
die Verriegelung hält, über den
Ablauf informiert werden, um zu verhindern, dass dieser Prozess
gleichzeitig zusammen mit einem Prozess, der nachfolgend eine Verriegelung
an der Ressource erhält,
auf die Ressource zugreift. Derartige Benachrichtigungsnachrichten
können
jedoch verzögert
und verloren werden. Die Verarbeitungsentität, die der Ressource R zugeordnet
ist, kann, um derartige Probleme zu handhaben, zusammen mit der
Verriegelung einen zeitlich festgelegten Autorisierungscode zurückgeben
und einen Zugriff auf die Ressource überwachen, um sicherzustellen, dass
lediglich autorisierte Prozesse auf die Ressource zugreifen. Die
Verarbeitungsentität
jedoch, die der Ressource R zugeordnet ist, kann selbst abstürzen, Autorisierungsnachrichten
können
verloren oder verzögert
werden oder die Verarbeitungsentität, die der Ressource R zugeordnet
ist, kann selbst intern unter Problemen einer gleichzeitigen Konkurrenz
leiden, wenn versucht wird, die Ressource R im Auftrag gleichzeitig
konkurrierender entfernter Prozesse zu verriegeln oder freizugeben.
Es sind nachweisbar korrekte Verteilt-Verriegelung-Protokolle verfügbar, aber
diese Protokolle sind allgemein für Prozessabstürze empfindlich
und weisen bestimmte strikte Zeitabhängigkeiten auf, deren versehentliche
Verletzung zu einem Versäumnis
der verteilten Verriegelung, ein Eingreifen zu verhindern, einem
gleichzeitigen Zugriff durch mehrere Prozesse oder einer Systemblockade führen kann.
-
Ausführungsbeispiele
der vorliegenden Erfindung verwenden ein verteiltes Speicherungsregister,
das einer Ressource zugeordnet ist, um eine verteilte Verriegelung
für die
Ressource zu implementieren. 11 – 17 stellen
den grundlegenden Betrieb eines Speicherungsregisters unter Verwendung von
Darstellungskonventionen dar, die in 4 – 10 verwendet
werden. Wie es in 11 gezeigt ist, ist das verteilte
Speicherungsregister 1102 vorzugsweise ein abstraktes oder
virtuelles Register und nicht ein physisches Register, das in der
Hardware einer speziellen elekt ronischen Vorrichtung implementiert
ist. Jeder Prozess, der auf einem Prozessor oder Computersystem 1104 – 1108 läuft, verwendet eine
kleine Anzahl von Werten, die in einem dynamischen Speicher gespeichert
sind und optional in einem nicht-flüchtigen Speicher gesichert
sind, zusammen mit einer kleinen Anzahl von auf das verteilte Speicherungsregister
bezogenen Routinen, um das verteilte Speicherungsregister 1002 kollektiv
zu implementieren. Zumindest ist ein Satz von gespeicherten Werten
und Routinen jeder Verarbeitungsentität zugeordnet, die auf das verteilte
Speicherungsregister zugreift. Bei derartigen Implementierungen
kann jeder Prozess, der auf einem physischen Prozessor oder Mehrprozessorsystem
läuft,
die eigenen gespeicherten Werte und Routinen desselben verwalten und
bei anderen Implementierungen können
Prozesse, die auf einem speziellen Prozessor oder Mehrprozessorsystem
laufen, die gespeicherten Werte und Routinen gemeinschaftlich verwenden,
vorausgesetzt, dass das gemeinschaftliche Verwenden lokal koordiniert
ist, um Probleme eines gleichzeitigen Zugriffs durch mehrere Prozesse,
die auf dem Prozessor laufen, zu verhindern.
-
In 11 behält jedes
Computersystem einen lokalen Wert 1110 – 1114 für das verteilte
Speicherungsregister bei. Allgemein sind die lokalen Werte, die
durch die unterschiedlichen Computersysteme gespeichert sind, normalerweise
identisch und gleich dem Wert des verteilten Speicherungsregisters 1102. Gelegentlich
sind jedoch die lokalen Werte eventuell nicht alle identisch, wie
bei dem in 11 gezeigten Beispiel, in welchem
Fall, falls eine Mehrheit der Computersysteme aktuell einen einzigen
lokal gespeicherten Wert beibehält,
dann der Wert des verteilten Speicherungsregisters der mehrheitlich
gehaltene Wert ist.
-
Bei
dem in 11 gezeigten Beispiel, das ein
Ausführungsbeispiel
der vorliegenden Erfindung darstellt, verwenden Prozesse, die auf
den fünf
Computersystemen 1104 – 1108 laufen,
das verteilte Speicherungsregister 1102 als eine verteilte
Verriegelung, um einen Zugriff auf eine entfernte Ressource 1110R zu
serialisieren. Eine auf einem verteilten Speicherungsregister basierte
verteilte Verriegelung kann verwendet werden, um einen gleichzeitigen
Zugriff durch entfernte Prozesse auf eine einzige Ressource oder
auf eine Sammlung von Ressourcen zu steuern, wobei die Sammlung
von Ressourcen selbst möglicherweise über einer
Anzahl von miteinander kommunizierenden, elektronischen Vorrichtungen verteilt
ist.
-
Ein
verteiltes Speicherungsregister stellt einer Anzahl von miteinander
kommunizierenden Prozessen, die kollektiv das verteilte Speicherungsregister
implementieren, zwei grundlegende Funktionen auf hoher Ebene bereit.
Wie es in 12 gezeigt ist, kann ein Prozess
eine LESEN-Anforderung 1202 an das verteilte Speicherungsregister 1102 richten.
Falls das verteilte Speicherungsregister aktuell einen gültigen Wert
hält, wie
es in 13 durch den Wert „B" innerhalb des verteilten
Speicherungsregisters 1102 gezeigt ist, wird der aktuelle,
gültige
Wert zu dem anfordernden Prozess zurückgegeben 1302, wie
es in 13 gezeigt ist. Falls jedoch,
wie es in 14 gezeigt ist, das verteilte
Speicherungsregister 1102 gegenwärtig keinen gültigen Wert
enthält,
dann wird der Wert NIL 1402 zu dem anfordernden Prozess
zurückgegeben.
Der Wert NIL ist ein Wert, der kein gültiger Wert sein kann, der
innerhalb des verteilten Speicherungsregisters gespeichert ist.
-
Ein
Prozess kann auch einen Wert zu dem verteilten Speicherungsregister
schreiben. In 15 richtet ein Prozess eine
SCHREIBEN-Nachricht 1502 an das verteilte Speicherungsregister 1102,
wobei die SCHREIBEN-Nachricht 1502 einen neuen Wert „X" umfasst, der zu
dem verteilten Speicherungsregister 1102 geschrieben werden
soll. Falls der Wert, der zu dem verteilten Speicherungsregister übertragen
wird, gleich welchen Wert, der aktuell in dem verteilten Speicherungsregister
gespeichert ist, erfolgreich überschreibt,
wie es in 16 gezeigt ist, dann wird ein Boolscher
Wert „WAHR" zu dem Prozess, der
die SCHREIBEN-Anforderung
an das verteilte Speicherungsregister gerichtet hat, zurückgegeben 1602.
Andernfalls, wie es in 17 gezeigt ist, schlägt die SCHREIBEN-Anforderung
fehl und ein Boolscher Wert „FALSCH" wird zu dem Prozess,
der die SCHREIBEN-Anforderung an das verteilte Speicherungsregister
gerichtet hat, zurückgegeben 1702, wobei
der Wert, der in dem verteilten Speicherungsregister gespeichert
ist, durch die SCHREIBEN-Anforderung unverändert ist. Bei bestimmten Implementierungen
gibt das verteilte Speicherungsregister Binärwerte „OK" und „NOK" zurück,
die äquivalent
zu den Boolschen Werten „WAHR" und „FALSCH" sind.
-
18 zeigt
die Komponenten, die durch einen Prozess oder eine Verarbeitungsentität Pi verwendet werden, die zusammen mit einer
Anzahl anderer Prozesse und/oder Verarbeitungsentitäten, Pj≠i, ein
verteiltes Speicherungsregister implementiert. Ein Prozessor oder
eine Verarbeitungsentität
verwendet drei Grundelemente auf niedriger Ebene: einen Zeitgebermechanismus 1802,
eine eindeutige ID 1804 und einen Takt 1806. Der
Prozessor oder die Verarbeitungsentität Pi verwendet
einen lokalen Zeitgebermechanismus 1802, der ermöglicht,
dass Pi einen Zeitgeber für eine spezifizierte
Zeitperiode setzt und dann darauf wartet, dass der Zeitgeber abläuft, wobei
Pi bei einem Ablauf des Zeitgebers benachrichtigt
wird, um eine gewisse Operation fortzusetzen. Ein Prozess kann einen
Zeitgeber setzen und eine Ausführung
fortsetzen, wobei der Zeitgeber auf einen Ablauf hin überprüft oder
abgefragt wird, oder ein Prozess kann einen Zeitgeber setzen, eine
Ausführung
aussetzen und wieder aufgeweckt werden, wenn der Zeitgeber abläuft. In
jedem Fall ermöglicht der
Zeitgeber, dass der Prozess eine Operation logisch aussetzt und
nachfolgend die Operation nach einer spezifizierten Zeitperiode
wieder aufnimmt oder eine gewisse Operation für eine spezifizierte Zeitperiode
durchführt,
bis der Zeitgeber abläuft.
Der Prozess oder die Verarbeitungsentität Pi muss
auch eine zuverlässig
gespeicherte und zuverlässig
wiedererlangbare lokale Prozess-ID („PID") 1804 aufweisen. Jeder Prozessor
oder jede Verarbeitungsentität
muss eine lokale PID aufweisen, die mit Bezug auf alle anderen Prozesse
und/oder Verarbeitungsentitäten
eindeutig ist, die zusammen das verteilte Speicherungsregister implementieren.
Schließlich
muss der Prozessor oder die Verarbeitungsentität Pi einen
Echtzeittakt 1806 aufweisen, der grob mit irgendeiner absoluten
Zeit koordiniert ist. Die Echtzeittakte aller der Prozesse und/oder
Verarbeitungsentitäten,
die kollektiv ein verteiltes Speicherungsregister implementieren,
müssen
nicht präzise
synchronisiert sein, aber müssen
irgendein gemeinschaftlich verwendetes Konzept einer absoluten Zeit
vernünftig
wiederspiegeln. Die meisten Computer, einschließlich Personalcomputer, umfassen
einen durch eine Batterie mit Leistung versorgten Systemtakt, der
einen aktuellen, universellen Zeitwert wiederspiegelt. Für die meisten Zwecke,
einschließlich
einer Implementierung eines verteilten Speicherungsregisters, müssen diese
Systemtakte nicht präzise
synchronisiert sein, sondern lediglich eine aktuelle, universelle
Zeit näherungsweise
wiederspiegeln.
-
Jeder
Prozessor oder jede Verarbeitungsentität Pi umfasst
einen flüchtigen
Speicher 1808 und bei einigen Ausführungsbeispielen einen nicht-flüchtigen
Speicher 1810. Der flüchtige
Speicher 1808 wird zum Speichern von Anweisungen für eine Ausführung und
lokaler Werte einer Anzahl von Variablen verwendet, die für das Verteilt-Speicherungsregister-Protokoll verwendet
werden. Der nicht-flüchtige Speicher 1810 wird
zum beständigen
Speichern der Anzahl verwendeter Variablen für das Verteilt-Speicherungsregister-Protokoll
bei einigen Ausführungsbeispielen
verwendet. Eine beständige
Speicherung von variablen Werten liefert eine relativ einfache Wiederaufnahme
einer Teilnahme eines Prozesses bei der kollektiven Implementierung
eines verteilten Speicherungsregisters nach einem Absturz oder einer
Kommunikationsunterbrechung. Eine beständige Speicherung ist jedoch
nicht erforderlich. Solange die variablen Werte in einem dynamischen
Speicher gespeichert sind, werden anstelle dessen bei Ausführungsbeispielen
einer nicht-beständigen
Speicherung, falls dieselben verloren werden, alle zusammen verloren
und vorausgesetzt, dass die Variablen ordnungsgemäß reinitialisiert
werden, ist das Verteilt-Speicherungsregister-Protokoll
korrekt wirksam und ein Fortschritt von Prozessen und Verarbeitungsentitäten, die
das verteilte Speicherungsregister verwenden, ist beibehalten. Jeder
Prozess Pi speichert drei Variablen: (1)
val 1834, die den aktuellen, lokalen Wert für das verteilte
Speicherungsregister hält;
(2) val-ts 1836, die den Zeitstempelwert angibt, der dem aktuellen,
lokalen Wert für
das verteilte Speicherungsregister zugeordnet ist; und (3) ord-ts 1838,
die den jüngsten
Zeitstempel angibt, der einer SCHREIBEN-Operation zugeordnet ist.
Die Variable val ist besonders bei Ausführungsbeispielen einer nicht-beständigen Speicherung
auf einen Wert NIL initialisiert, der von irgendeinem Wert, der
zu dem verteilten Speicherungsregister durch Prozesse oder Verarbeitungsentitäten geschrieben
wird, unterschiedlich ist und der deshalb von allen anderen Verteilt-Speicherungsregister-Werten
unterscheidbar ist. Gleichermaßen
sind die Werte der Variablen val-ts und ord-ts auf den Wert „initialTS" initialisiert, ein Wert weniger irgendeines
Zeitstempelwerts, der durch eine Routine „newTS" zurückgegeben
wird, die verwendet wird, um Zeitstempelwerte zu erzeugen. Vorausgesetzt,
dass val, val-ts und ord-ts gemeinsam auf diese Werte reinitialisiert
werden, toleriert das kollektiv implementierte, verteilte Speicherungsregister
Kommunikationsunterbrechungen und Prozess- und Verarbeitungsentitätsabstürze, vorausgesetzt,
dass zumindest eine Mehrheit von Prozessen und Verarbeitungsentitäten sich
erholt und eine Korrekturoperation wieder aufnimmt.
-
Jeder
Prozessor oder jede Verarbeitungsentität P1 kann
mit anderen Prozessen und Verarbeitungsentitäten Pj≠i über ein
nachrichtenbasiertes Netzwerk verbunden sein, um Nachrichten von
den anderen Prozessen und Verarbeitungsentitäten Pj≠i zu
empfangen 1812 und zu denselben zu senden 1814.
-
Jeder
Prozessor oder jede Verarbeitungsentität Pi umfasst
eine Routine „newTS" 1816, die
einen Zeitstempel TSi zurückgibt,
wenn dieselbe aufgerufen wird, wobei der Zeitstempel TSi größer als
ein gewisser Anfangswert „initialTS" ist. Jedes Mal,
wenn die Routine „newTS" aufgerufen wird,
gibt dieselbe einen Zeitstempel TSi zurück, der
größer als
irgendein Zeitstempel ist, der vorhergehend zurückgegeben wurde. Ferner sollte
irgendein Zeitstempelwert TSi, der durch
die newTS zurückgegeben
wird, die durch einen Prozessor oder eine Verarbeitungsentität Pi aufgerufen wird, von irgendeinem Zeitstempel
TSj unterschiedlich sein, der durch newTS
zurückgegeben
wird, die durch einen anderen Prozessor oder eine andere Verarbeitungsentität Pj aufgerufen wird. Ein praktisches Verfahren
zum Implementieren von newTS besteht darin, dass newTS einen Zeitstempel
TS zurückgibt,
der die Verkettung der lokalen PID 1804 mit der aktuellen
Zeit aufweist, die durch den Systemtakt 1806 berichtet
wird. Jeder Prozessor oder jede Verarbeitungsentität Pi, die das verteilte Speicherungsregister
implementiert, umfasst vier unterschiedliche Handhabungseinrichtungsroutinen:
(1) eine READ-Handhabungseinrichtung (LESEN-Handhabungseinrichtung) 1818;
(2) eine ORDER-Handhabungseinrichtung (ORDNEN-Handhabungseinrichtung) 1820;
(3) eine WRITE-Handhabungseinrichtung
(SCHREIBEN-Handhabungseinrichtung) 1822; und (4) eine ORDER&READ-Handhabungseinrichtung
(ORD-NEN&LESEN-Handhabungseinrichtung) 1824.
Es ist wichtig, anzumerken, dass Handhabungseinrichtungsroutinen
als kritische Abschnitte implementiert sein sollten oder durch Verriegelungen
eingereiht sein sollten, um Wettlaufbedingungen bei einem Testen
und Setzen lokaler Variablenwerte zu verhindern. Jeder Prozessor
oder jede Verarbeitungsentität
Pi muss ferner vier Operationsroutinen aufweisen:
(1) READ (LESEN) 1826; (2) WRITE (SCHREIBEN) 1828;
(3) RECOVER (REGENERIEREN) 1830; und (4) MAJORITY (MEHRHEIT) 1832.
Sowohl die vier Handhabungseinrichtungsroutinen als auch die vier
Operationsroutinen sind unten detailliert erörtert.
-
Ein
korrekter Betrieb eines verteilten Speicherungsregisters und eine
Lebendigkeit, oder ein Fortgang, von Prozessen und Verarbeitungsentitäten, die
ein verteiltes Speicherungsregister verwenden, hängt von einer Anzahl von Annahmen
ab. Es wird angenommen, dass jeder Prozess oder jede Verarbeitungsentität Pi sich nicht bösartig verhält. Mit anderen Worten hält sich
jeder Prozessor oder jede Verarbeitungsentität Pi treu
an das Verteilt-Speicherungsregister-Protokoll. Eine andere Annahme
besteht darin, dass eine Mehrzahl der Prozesse und/oder Verarbeitungsentitäten Pi, die kollektiv ein verteiltes Speicherungsregister
implementieren, entweder niemals abstürzen oder schließlich aufhören abzustürzen und
zuverlässig
ausführen.
Wie es oben erörtert
ist, ist eine Implementierung eines verteilten Speicherungsregisters
tolerant gegenüber
verlorenen Nachrichten, Kommunikationsunterbrechungen und Prozess-
und Prozessentitätsabstürzen, die
zu irgendeiner gegebenen Zeit eine Minderheit von Prozessen und
Verarbeitungsentitäten
beeinflussen. Wie es oben erwähnt
ist, sind alle der Prozesse und/oder Verarbeitungsentitäten durch
ein nachrichtenbasiertes Netzwerk vollständig verbunden. Das nachrichtenbasierte
Netzwerk ist asynchron ohne Grenzen an Nachrichtenübertragungszeiten.
Es wird jedoch eine gute Verlusteigenschaft für das Netzwerk angenommen,
was im Wesentlichen garantiert, dass, falls Pi eine
Nachricht m von Pj empfängt, dann Pj die Nachricht
m gesendet hat, und ebenfalls im Wesentlichen garantiert, dass,
falls Pi die Nachricht m wiederholt zu Pj überträgt, Pj schließlich
die Nachricht m empfängt,
falls Pj ein korrekter Prozess oder eine
korrekte Verarbeitungsentität
ist. Wie es oben erörtert ist,
wird wiederum angenommen, dass die Systemtakte für alle Prozesse oder Verarbeitungsentitäten alle
einen gewissen gemeinschaftlich verwendeten Zeitstandard vernünftig wiederspiegeln,
aber dieselben müssen
nicht präzise
synchronisiert sein.
-
Diese
Annahmen sind nützlich,
um eine Korrektheit des Verteilt-Speicherungsregister-Protokolls zu
beweisen und um einen Fortschritt zu garantieren. Bei praktischen
Implementierungen jedoch kann eine oder mehrere der Annahmen verletzt
sein und dennoch eine vernünftig
korrekte und nützliche
verteilte Verriegelung erhalten werden. Außerdem können zusätzliche Schutzmaßnahmen
in die Handhabungseinrichtungsroutinen und Operationsroutinen eingebaut
sein, um spezielle Mängel
bei den Hardwareplattformen und Verarbeitungsentitäten zu überwinden.
-
Ein
Betrieb des verteilten Speicherungsregisters basiert auf dem Konzept
eines Quorums. 19 stellt eine Bestimmung des
aktuellen Werts eines verteilten Speicherungsregisters mittels eines Quorums
dar. 19 verwendet ähnliche
Darstellungskonventionen, wie dieselben in 11 – 17 verwendet
werden. In 19 behält jeder der Prozesse oder
jede der Verarbeitungsentitäten 1902 – 1906 die
lokale Variable, vaöl-ts,
bei, wie beispielsweise eine lokale Variable 1907, die
durch den Prozess oder die Verarbeitungsentität 1902 beibehalten wird,
die einen lokalen Zeitstempelwert für das verteilte Speicherungsregister
hält. Falls
wie in 19 eine Mehrheit der lokalen
Werte, die durch die verschiedenen Prozesse und/oder Verarbeitungsentitäten beibehalten
sind, die kollektiv das verteilte Speicherungsregister implementieren,
sich aktuell auf einen Zeitstempelwert val-ts einigen, der dem verteilten
Speicherungsregister zugeordnet ist, dann wird der aktuelle Wert
des verteilten Speicherungsregisters 1908 als der Wert
der Variable val betrachtet, die durch die Mehrheit der Prozesse
oder Verarbeitungsentitäten
gehalten wird. Falls eine Mehrheit der Prozesse und Verarbeitungsentitäten sich
nicht auf einen Zeitstempelwert val-ts einigen können, oder es keinen einzigen
von der Mehrheit gehaltenen Wert gibt, dann sind die Inhalte des
verteilten Speicherungsregisters undefiniert. Jedoch kann dann ein
von einer Minderheit gehaltener Wert durch eine Mehrheit von Prozessen
und/oder Verarbeitungsentitäten
ausgewählt
werden und dieselben können
sich auf denselben einigen, um das verteilte Speicherungsregister
zu regenerieren.
-
20 zeigt
Pseudocode-Implementierungen für
die Routinenhandhabungseinrichtungen und Operationsroutinen, die
in 18 schematisch gezeigt sind. Es ist zu beachten,
dass diese Pseudocode-Implementierungen eine detaillierte Fehlerhandhabung
und spezifische Details von Kommunikationsgrundelementen auf niedriger
Ebene, eine lokale Verriegelung und andere Details weglassen, die Fachleuten
auf dem Gebiet einer Computerprogrammierung gut ersichtlich sind
und durch dieselben einfach implementiert werden. Die Routine „majority" 2002 sendet
in Zeile 2 eine Nachricht von einem Prozess oder einer Verarbeitungsentität Pi zu sich selbst und zu allen anderen Prozessen
oder Verarbeitungsentitäten
Pj≠i,
die gemeinsam mit Pi kollektiv ein verteiltes
Speicherungsregister implementieren. Die Nachricht wird periodisch
wieder gesendet, bis eine angemessene Anzahl von Antworten empfangen wird,
und bei vielen Implementierungen wird ein Zeitgeber gesetzt, um
an diesem Schritt eine finite Zeit- und Ausführungsbegrenzung zu setzen.
Dann wartet in Zeilen 3 – 4
die Routine „majority", um Antworten auf
die Nachricht zu empfangen, und gibt dann die empfangenen Antworten
in Zeile 5 zurück.
Die Annahme, dass eine Mehrheit von Prozessen korrekt ist, wie es
oben erörtert
ist, garantiert im Wesentlichen, dass die Routine „majority" schließlich zurückkehrt,
ob ein Zeitgeber verwendet wird oder nicht. Bei praktischen Implementierungen
erleichtert ein Zeitgeber ein Handhaben von Fehlerauftretensfällen in einer
zeitigen Weise. Es ist zu beachten, dass eine derartige Nachricht
eindeutig identifiziert ist, allgemein mit einem Zeitstempel oder
einer anderen eindeutigen Nummer, so dass Antworten, die durch den Prozess
Pi empfangen werden, mit einer vorhergehend
gesendeten Nachricht korreliert werden können.
-
Die
Routine „read" 2004 liest
einen Wert aus dem verteilten Speicherungsregister. In Zeile 2 ruft die
Routine „read" die Routine „majority" auf, um eine LESEN-Nachricht
zu sich selbst und zu jedem der anderen Prozesse oder Verarbeitungsentitäten Pj≠i zu senden.
Die LESEN-Nachricht umfasst eine Angabe, dass die Nachricht eine
LESEN-Nachricht ist, sowie den Zeitstempelwert, der dem lokalen,
aktuellen Verteilt-Speicherungsregister-Wert zugeordnet ist, der durch
den Prozess Pi gehalten ist, val-ts. Falls
die Routine „majority" einen Satz von Antworten
zurückgibt,
die alle den Boolschen Wert „WAHR" enthalten, wie es
in Zeile 3 bestimmt ist, dann gibt die Routine „read" den lokalen, aktuellen Verteilt-Speicherungsregister-Wert
val zurück.
Andernfalls ruft die Routine „read" in Zeile 4 die Routine „recover" auf.
-
Die
Routine „recover" 2006 versucht,
einen aktuellen Wert des verteilten Speicherungsregisters durch
eine Quorum-Technik
zu bestimmen. Zuerst wird in Zeile 2 ein neuer Zeitstempel ts durch
ein Aufrufen der Routine „newTS" erhalten. Dann wird
in Zeile 3 die Routine „majotity" aufgerufen, um ORDNEN&LESEN-Nachrichten
zu allen der Prozesse und/oder Verarbeitungsentitäten zu senden.
Falls irgendein Status in den Nachrichten, die durch die Routine „majority" zurückgegeben
werden, „FALSCH" ist, dann gibt „recover" den Wert NIL in Zeile
4 zurück.
Andernfalls wird in Zeile 5 der lokale, aktuelle Wert des verteilten
Speicherungsregisters, val, zu dem Wert gesetzt, der dem Zeitstempel
mit dem höchsten
Wert in dem Satz von Antworten zugeordnet ist, die durch die Routine „majority" zurückgegeben
werden. Als nächstes
wird in Zeile 6 die Routine „majority" erneut aufgerufen,
um eine SCHREIBEN-Nachricht zu senden, die den neuen Zeitstempel
ts, der in Zeile 2 erhalten wird, und den neuen lokalen, aktuellen
Wert des verteilten Speicherungsregisters, val, umfasst. Falls der
Status in allen der Antworten den Boolschen Wert „WAHR" aufweist, dann war
die SCHREIBEN-Operation erfolgreich und eine Mehrheit der Prozesse
und/oder Verarbeitungsentitäten
stimmen nun mit diesem neuen Wert überein, der in der lokalen
Kopie val in Zeile 5 gespeichert ist: Andernfalls gibt die Routine „recover" den Wert NIL zurück.
-
Die
Routine „write" 2008 schreibt
einen neuen Wert zu dem verteilten Speicherungsregister. Ein neuer
Zeitstempel ts wird in Zeile 2 erhalten. Die Routine „majority" wird in Zeile 3
aufgerufen, um eine ORDNEN-Nachricht, die den neuen Zeitstempel
umfasst, zu allen der Prozesse und/oder Verarbeitungsentitäten zu senden.
Falls irgendwelche der Statuswerte, die in Antwortnachrichten zurückgegeben
werden, die durch die Routine „majority" zurückgegeben werden, „FALSCH" sind, dann wird
der Wert „NOK" durch die Routine „write" in Zeile 4 zurückgegeben. Andernfalls
wird der Wert val zu den anderen Prozessen und/oder Verarbeitungsentitäten in Zeile
5 durch ein Senden einer SCHREIBEN-Nachricht über die Routine „majority" geschrieben. Falls
alle die Statuswerte in Antworten, die durch die Routine „majority" zurückgegeben
werden, „WAHR" sind, wie es in
Zeile 6 bestimmt wird, dann gibt die Routine „write" den Wert „OK" zurück.
Andernfalls gibt in Zeile 7 die Routine „write" den Wert „NOK" zurück.
Es ist zu beachten, dass sowohl bei dem Fall der Routine „recover" 2006 als
auch der Routine „write" die lokale Kopie des
Verteilt-Speicherungsregister-Werts val und die lokale Kopie des
Zeitstempelwerts val-ts beide durch lokale Handhabungseinrichtungsroutinen
aktualisiert werden, wie es unten erörtert ist.
-
Als
nächstes
werden die Handhabungseinrichtungsroutinen erörtert. Zu Beginn ist zu beachten, dass
die Handhabungseinrichtungsroutinen empfangene Werte mit lokalen
Variablenwerten vergleichen und dann lokale Variablenwerte gemäß dem Ergebnis
der Vergleiche setzen. Diese Typen von Operationen sollten streng
serialisiert und gegen Wettlaufbedingungen innerhalb jedes Prozesses
und/oder jeder Verarbeitungsentität geschützt sein. Eine lokale Serialisierung
wird ohne weiteres unter Verwendung kritischer Abschnitte oder lokaler
Verriegelungen basierend auf atomaren Testen- und Setzen-Anweisungen erzielt. Die
LESEN-Handhabungseinrichtungsroutine 2010 empfängt eine
LESEN-Nachricht und antwortet auf die LESEN-Nachricht mit einem
status-Wert, der angibt, ob die lokale Kopie des Zeitstempels val-ts
in dem Empfangsprozess oder der Entität gleich dem Zeitstempel, der
in der LESEN-Nachricht empfangen wird, ist oder nicht und ob der
Zeitstempel ts, der in der LESEN-Nachricht empfangen wird, größer oder gleich
dem aktuellen Wert einer lokalen Variable ord-ts ist oder nicht.
Die SCHREIBEN-Handhabungseinrichtungsroutine 2012 empfängt eine SCHREI-BEN-Nachricht, bestimmt
einen Wert für eine
lokale Variable status in Zeile 2, die angibt, ob die lokale Kopie
des Zeitstempels val-ts in dem Empfangsprozess oder der Entität größer als
der Zeitstempel, der in der SCHREIBEN-Nachricht empfangen wird,
ist oder nicht und ob der Zeitstempel ts, der in der Schreiben-Nachricht
empfangen wird, größer oder
gleich dem aktuellen Wert einer lokalen Variable ord-ts ist oder
nicht. Falls der Wert der lokalen status-Variable „WAHR" lautet, wie es in
Zeile 3 bestimmt ist, dann aktualisiert die SCHREIBEN-Handhabungseinrichtungsroutine
den lokal gespeicherten Wert und den Zeitstempel, val und val-ts, in Zeilen 4 – 5 sowohl
in einem dynamischen Speicher als auch in einem beständigen Speicher
mit dem Wert und dem Zeitstempel, die in der SCHREIBEN-Nachricht empfangen
werden. Schließlich
wird in Zeile 6 der Wert, der in der lokalen Variable status gehalten
ist, zu dem Prozess oder der Verarbeitungsentität zurückgegeben, die die SCHREIBEN-Nachricht gesendet
hat, die durch die SCHREIBEN-Handhabungseinrichtungsroutine 2012 gehandhabt
wird.
-
Die
ORDNEN&LESEN-Handhabungseinrichtung 2014 berechnet
einen Wert für
die lokale Variable status in Zeile 2 und gibt diesen Wert zu dem Prozess
oder der Verarbeitungsentität
zurück,
von der eine ORDNEN&LESEN-Nachricht
empfangen wurde. Der berechnete Wert von status ist ein Boolscher
Wert, der angibt, ob der Zeitstempel, der in der ORD-NEN&LESEN-Nachricht
empfangen wird, größer als
beide Werte, die in den lokalen Variablen val-ts und ord-ts gespeichert
sind, ist oder nicht. Falls der berechnete Wert von status „WAHR" lautet, dann wird
der empfangene Zeitstempel ts sowohl in einen dynamischen Speicher
als auch einen beständigen Speicher
in der Variable ord-ts gespeichert.
-
Auf ähnliche
Weise berechnet die ORDNEN-Handhabungseinrichtung 2016 einen
Wert für eine
lokale Variable status in Zeile 2 und gibt diesen Status zu dem
Prozess oder der Verarbeitungsentität zurück, von der eine ORDNEN-Nachricht
empfangen wurde. Der Status spiegelt wieder, ob der empfangene Zeitstempel
größer als
die Werte, die in lokalen Variablen val-ts und ord-ts gehalten sind,
ist oder nicht. Falls der berechnete Wert von status „WAHR" lautet, dann wird
der empfangene Zeitstempel ts sowohl in einem dynamischen Speicher
als auch einem beständigen
Speicher bei der Variable ord-ts gespeichert.
-
Ein
Satz von Prozessen und/oder Verarbeitungsentitäten, der ein verteiltes Speicherungsregister
aufweist, das durch die gespeicherten Werte, Handhabungseinrichtungsroutinen
und Operationsroutinen, die oben erörtert sind, implementiert ist, kann
ein verteiltes Speicherungsregister einer oder mehreren Ressourcen
zuordnen, für
die ein Zugriff serialisiert werden sollte, um ein gleichzeitiges
gemeinschaftliches Verwenden der einen oder mehreren Ressourcen
durch die Prozesse und/oder Verarbeitungsentitäten zu ermöglichen, die das zugeordnete
verteilte Speicherungsregister kollektiv implementieren. 21 zeigt
ein Verteilt-Verriegelung-Protokoll,
das auf einem verteilten Speicherungsregister basiert und ein Ausführungsbeispiel der
vorliegenden Erfindung darstellt. Wie es in 21 gezeigt
ist, hält
das verteilte Speicherungsregister 2104 die verketteten
Werte einer PID für
einen Prozess, der die verteilte Verriegelung hält, und eine Ablaufzeit für die Verriegelung.
Wenn das verteilte Speicherungsregister einen PID-/Ablaufzeitwert
hält, wird
die Ressource oder die Ressourcen, die dem verteilten Speicherungsregister
zugeordnet sind, durch den Prozess oder die Verarbeitungsentität mit der
PID als verriegelt 2106 betrachtet. Wenn kein Prozess oder
keine Verarbeitungsentität
die Verriegelung hält,
dann wird die Ressource oder die Ressourcen, die dem verteilten
Speicherungsregister zugeordnet sind, als nicht verriegelt betrachtet.
Ein spezieller Wert „KEINER" bzw.
-
„KEIN" oder „KEIN PROZESS" kann verwendet werden,
um anzugeben, dass kein Prozess aktuell die verteilte Verriegelung
hält. Die
verteilte Verriegelung ermöglicht
somit, dass irgendein gegebener Prozess oder eine Verarbeitungsentität die Ressource
oder die Ressourcen, die dem verteilten Speicherungsregister zugeordnet
sind, für
eine spezifizierte Zeitperiode zu mieten.
-
Es
ist zu beachten, dass eine Vielfalt unterschiedlicher Verriegelungssemantik
einer verteilten Verriegelung zugeordnet sein kann. Die verteilte
Verriegelung kann eine Verriegelung lediglich mit Bezug auf bestimmte
Typen von Operationen sein, wie beispielsweise SCHREIBEN-Operationen,
die auf eine Ressource gerichtet sind, oder kann eine Ressource für alle Operationen
verriegeln, die auf die Ressource durch Prozesse und/oder Verarbeitungsentitäten gerichtet
sind, die die Verriegelung nicht halten. Zusätzlich kann die Verriegelung
ermöglichen,
dass bis zu einer spezifizierten maximalen Anzahl von Prozessen
gleichzeitig auf die Ressource oder die Ressourcen zugreift, die
der Verriegelung zugeordnet sind. Wie es oben erörtert ist, können Ressourcen
Vorrichtungen, Daten, Speicherregionen, Datenstrukturen, logische
Entitäten
einschließlich
Datenträgern
und irgendeine andere Vorrichtung oder Rechenressource sein, um
die mehrere Prozesse oder Verarbeitungsentitäten eventuell gleichzeitig,
simultan oder sowohl gleichzeitig als auch simultan konkurrieren.
-
Verschiedene
unterschiedliche Verteilt-Verriegelung-Protokolle können implementiert
werden, um die verteilte Verriegelung zu erzeugen, basierend auf
einem verteilten Speicherungsregister, wie es in 21 dargestellt
ist. Zwei alternative Implementierungen werden als nächstes beschrieben.
Wie bei dem Verteilt-Speicherungsverriegelung-Protokoll, das oben
erörtert
ist, wird erneut angenommen, dass Prozesse und/oder Verarbeitungsentitäten, die
eine Ressource unter Verwendung der verteilten Verriegelung zusammenwirkend
gemeinschaftlich verwenden, sich nicht bösartig verhalten und sich treu
an das Verteilt-Verriegelung-Protokoll
halten.
-
22 zeigt
ein einfaches Verteilt-Verriegelung-Protokoll, das durch eine Routine „leaseResource" implementiert wird.
Die Routine „leaseResource" wird durch einen
Prozess oder eine Verarbeitungsentität aufgerufen, um eine Ressource
oder einen Satz von Ressourcen, die einem verteilten Speicherungsregister
zugeordnet sind, für
eine spezifizierte Zeitperiode zu verriegeln. Bei einem Schritt 2202 empfängt die
Routine „leaseResource" einen Identifizierer
R, der die spezielle Ressource oder die speziellen Ressourcen identifiziert,
für die
eine Verriegelung erwünscht
ist, und eine Mietzeit t, für
die die Verriegelung erwünscht
ist. Es ist zu beachten, dass ein Prozess oder eine Verarbeitungsentität gleichzeitig
auf eine Anzahl unterschiedlicher Ressourcen oder Sätze von
Ressourcen, die jeweils einer getrennten verteilten Verriegelung
zugeordnet sind, durch ein Verriegeln der unterschiedlichen Ressourcen
durch getrennte Aufrufe zu „leaseResource" zugreifen kann. Bei
einem Schritt 2204 liest die Routine „leaseResource" die Inhalte des
verteilten Speicherungsregisters, das der Ressource oder den Ressourcen
R zugeordnet ist, unter Verwendung des oben beschriebenen Verteilt-Speicherungsregister-Protokolls.
Falls die LESEN-Operation bei dem Schritt 2204 den Wert NIL
zurückgibt,
wie es bei einem Schritt 2206 bestimmt wird, dann gibt
die Routine „leaseResource" den Wert „FALSCH" bei einem Schritt 2208 zurück. Falls
die Ablaufzeit, die von dem verteilten Speicherungsregister gelesen
wird, geringer als die aktuelle Zeit ist, die von dem lokalen Systemtakt
erhalten wird, oder die PID, die von dem verteilten Speicherungsregister
gelesen wird, den Wert „KEINER" oder „KEIN PROZESS" aufweist, wie es
bei einem Schritt 2210 bestimmt wird, dann schreibt andernfalls
bei einem Schritt 2212 die Routine „leaseResource" die lokale PID des
Prozesses oder der Verarbeitungsentität, die die Routine „leaseResource" aufruft, und einen
Zeitwert gleich t+aktuelle Systemzeit+δ zu dem verteilten Speiche rungsregister,
das der Ressource oder den Ressourcen R zugeordnet ist. Falls die SCHREIBEN-Operation,
die bei dem Schritt 2212 ausgeführt wird, den Boolschen Wert „WAHR" zurückgibt,
wie es bei einem Schritt 2214 bestimmt wird, dann gibt
die Routine „leaseResource" einen Wert „WAHR" bei einem Schritt 2216 zurück. Andernfalls
gibt die Routine „leaseResource" den Boolschen Wert „FALSCH" bei dem Schritt 2208 zurück. Es ist zu
beachten, dass bei dem Schritt 2210 der Vergleich der Ablaufzeit
mit der aktuellen Zeit ausreichend ist, um zu garantieren, dass
die Vermietung abgelaufen ist, weil der Wert δ, der zu der Ablaufzeitberechnung bei
dem Schritt 2212 hinzugefügt wird, die Ablaufzeit auffüllt, um
die fehlende präzise
Synchronisation zwischen Systemtakten der verschiedenen Prozesse und
Verarbeitungsentitäten
zu berücksichtigen.
Es ist ebenfalls zu beachten, dass ein Prozess oder eine Verarbeitungsentität nicht
versuchen sollte, auf die Ressource oder den Satz von Ressourcen
nach einem Ablauf einer Vermietung zuzugreifen, ohne erneut die
Routine „leaseResource" aufzurufen. Der Wert δ kann von
Kommunikationsmedien und -systemen abhängen und kann in dem Bereich
von Millisekunden, Sekunden, Minuten, zig Minuten oder längeren Zeitintervallen
liegen. Ein Prozess kann, unter anderen Verfahren, durch ein Setzen
eines Zeitgebers auf ein in Anspruch Nehmen einer Vermietung hin
und ein Überprüfen auf
einen Zeitgeberablauf vor einem Zugreifen auf die gemietete Ressource
oder den gemieteten Satz von Ressourcen garantieren, dass sich derselbe
an das Verteilt-Verriegelung-Protokoll hält. Es ist ebenfalls zu beachten,
dass, wenn viele Prozesse oder Verarbeitungsentitäten um die Ressource
oder den Satz von Ressourcen über
eine Zeitperiode hinweg konkurrieren, ein Zugriff auf die Ressource
oder die Ressourcen innerhalb eines speziellen Zeitintervalls irgendeinem
einzelnen Prozess oder einer Verarbeitungsentität durch die Implementierung
der Routine „leaseResource", die in 22 gezeigt
ist, nicht garantiert ist.
-
23 zeigt
eine alternative, komplexere Implementierung der Routine „leaseResource". Die alternative
Implementierung, die in 23 gezeigt ist,
verwendet eine Anzahl der gleichen Schritte wie die in 22 gezeigte
Implementierung gemeinschaftlich. Schritte 2302, 2304, 2306, 2308, 2312, 2314 und 2316 bei
der in 23 gezeigten, alternativen Implementierung
sind den Schritten 2202, 2204, 2206, 2208, 2210, 2212, 2214 und 2216 in 22 ähnlich oder
identisch zu denselben und werden im Interesse der Kürze nicht
erneut beschrieben. Bei der alternativen Implementierung wird bei
einem Schritt 2302 eine lokale Variable numwaits auf 0
initialisiert. Bei der alternativen Implementierung wird bei einem
Schritt 2303 ein LESEN-Zeitgeber auf einen spezifizierten
Wert gesetzt. Falls die LESEN-Operation
bei dem Schritt 2304 fehlschlägt, wie es bei dem Schritt 2306 bestimmt
wird, kann die LESEN-Operation neu versucht werden, bis die LESEN-Operation für eine Zeitperiode
erfolgreich ist, für
die der LESEN-Zeitgeber bei dem Schritt 2303 gesetzt ist.
Ein neuer Schritt 2305 prüft auf einen Zeitgeberablauf hin,
bevor die LESEN-Operation wiederholt wird. Bei einem Schritt 2307 wird,
falls der Wert, der von dem verteilten Speicherungsregister bei
der LESEN-Operation
des Schritts 2304 gelesen wird, eine Angabe umfasst, dass
kein Prozess aktuell die Ressource oder den Satz von Ressourcen
verriegelt hat, dann der Vergleich von Ablauf mit aktueller Zeit
bei einem Schritt 2309 weggelassen. Bei dem Schritt 2309 wird die
aktuelle Zeit, die aus dem Systemtakt bestimmt wird, mit der Ablaufzeit
verglichen. Falls die aktuelle Zeit größer ist, dann werden bei dem
Schritt 2310 die Inhalte der lokalen Variable numwaits
inkrementiert. Falls die Inhalte der lokalen Variable numwaits größer als
eine Konstante MAXWAITS sind, wie es bei einem Schritt 2311 bestimmt
wird, dann gibt die Routine „leaseResource" den Wert „FALSCH" bei dem Schritt 2308 zurück. Andernfalls
wird eine Wartezeit wait bei Schritten 2313 und 2315 berechnet
und die Routine „leaseResource" wartet bei einem
Schritt 2317 die berechnete Zeit wait lang, bevor dieselbe eine
Erlangung der Verriegelung begin nend bei dem Schritt 2303 wiederholt.
Die Wartezeit ist die Zeit, bis die aktuelle Vermietung abläuft, wie
es bei dem Schritt 2313 bestimmt wird, plus eine gewisse
zusätzliche
Zeitperiode, die durch die Funktion δ() basierend auf dem aktuellen
Wert von numwaits berechnet wird. Diese Berechnung der Wartezeit
ermöglicht deshalb
eine Unterstützungsprozedur,
so dass während
Perioden einer starken Konkurrenz, Prozesse längere Zeitperioden warten,
bevor dieselben erneut versuchen, die Ressourcen zu mieten. Es ist
zu beachten, dass die Vermietung-Neuversuch-Operation der Schritte 2310, 2311, 2313, 2315 und 2317 erst ausgeführt wird,
wenn ein anderer Prozess oder eine andere Verarbeitungsentität die verteilte
Verriegelung gegenwärtig
hält, wie
es bei den Schritten 2307 und 2309 bestimmt wird.
Dann versucht bei den Schritten 2312, 2314 und 2316 die
Routine „leaseResource", die Ressource oder
den Satz von Ressourcen auf die gleiche Weise wie die erste Version
der Routine „leaseResource" zu mieten, wie es
in 22 gezeigt ist, mit einer Ausnahme dessen, dass,
falls das SCHREIBEN fehlschlägt,
der Neuversuch-Prozess, der bei dem Schritt 2310 beginnt,
aufgerufen wird.
-
Es
ist zu beachten, dass es keine strikten Zeitabhängigkeiten gibt, die auf die
verteilte Vermietung bezogen sind, die ein Ausführungsbeispiel der vorliegenden
Erfindung darstellt. Das verteilte Speicherungsregister, das der
verteilten Vermietung zugrunde liegt, stützt sich lediglich auf einen
Systemtakt, der für
alle miteinander kommunizierenden Prozesse und/oder Verarbeitungsentitäten zugreifbar
ist. Es ist auch zu beachten, dass die verteilte Vermietung selbst
dann wirksam sein kann, wenn eine Anzahl von Prozessen oder Verarbeitungsentitäten ausgefallen
ist. Die verteilte Vermietung ist somit robust und zuverlässig. Die
verteilte Vermietung ist ferner effizient mit Bezug auf die Anzahl
von Nachrichten, die zwischen Prozessen und/oder Verarbeitungsentitäten übertragen
werden, um eine Ressource zu verriegeln.
-
Obwohl
die vorliegende Erfindung im Hinblick auf ein spezielles Ausführungsbeispiel
beschrieben wurde, soll die Erfindung nicht auf dieses Ausführungsbeispiel
begrenzt sein. Modifikationen innerhalb der Wesensart der Erfindung
sind Fachleuten auf dem Gebiet ersichtlich. Zum Beispiel sind eine
beinahe unbegrenzte Anzahl unterschiedlicher Implementierungen des
Verteilt-Speicherungsregister-Protokolls und des Verteilt-Verriegelung-Protokolls
unter Verwendung unterschiedlicher Programmiersprachen, unterschiedlicher
modularer Organisationen, Steuerstrukturen und anderer typischer Programmiervariationen
möglich.
Außerdem
können beide
Protokolle in einer Firmware, einer Software oder in Hardware-Logikschaltungen
implementiert sein. Zusätzlich
kann irgendeine Kombination von Hardware-Logikschaltungen, einer Firmware und
einer Software verwendet werden, um sowohl das Verteilt-Speicherungsregister-Protokoll als auch
das Veteilt-Verriegelung-Protokoll zu implementieren. Das verteilte
Speicherungsregister ist lediglich ein Beispiel eines Quorum-basierten
abstrakten Registers, das verwendet werden kann, um ein Verteilt-Verriegelung-Protokoll
zu implementieren. Irgendein abstraktes Register, das für zuverlässige, atomare
LESEN- und SCHREIBEN-Operationen durch verteilte Prozesse sorgt,
kann verwendet werden, um die verteilte Verriegelung zu implementieren.
Mehrere alternative Ausführungsbeispiele
der „leaseResource"-Routine sind oben
erörtert.
Zusätzlich
zu diesen Routinen kann eine Mieten-Wiedermieten-Routine einfach
durch ein Ermöglichen
implementiert werden, dass ein Prozess oder eine Verarbeitungsentität den Wert „KEI-NER" oder „KEIN PROZESS" zu dem verteilten
Speicherungsregister schreibt, wenn der Prozess oder die Verarbeitungsentität, die die
Mieten-Wiedermieten-Routine aufruft, gegenwärtig die verteilte Verriegelung
hält. Zusätzliche
Typen von Verteilt-Verriegelung-Protokollen sind ebenfalls möglich. Beispielsweise
kann anstelle eines Implementierens einer Mieten-Routine, wie es
oben erörtert
ist, eine einfache Verriegelungsroutine ohne einer zugeordneten
Ablaufzeit durch ein Entfernen der Ablaufzeit aus den Werten implemen tiert
werden, die in dem verteilten Speicherungsregister gespeichert sind.
Viele zusätzliche
Variationen einer verteilten Verriegelung sind ebenfalls möglich. Bei
bestimmten Implementierungen speichert das verteilte Speicherungsregister
eventuell lediglich einen von zwei Werten: „VERRIEGELT" und „UNVERRIEGELT", wobei Prozesse
oder Verarbeitungsentitäten,
die die verteilte Verriegelung erfolgreich erlangen, für ein Sicherstellen
verantwortlich sind, dass dieselben lokal eine Verriegelungserlangung
verfolgen, und mit einer verteilten Einrichtung zum Löschen einer
verteilten Verriegelung, wenn eine Verarbeitungsentität, die die verteilte
Verriegelung hält,
ausfällt.
Bei anderen Implementierungen können
sowohl ein binärer
Verriegelt/Unverriegelt-Wert als auch eine Ablaufzeit in dem verteilten
Speicherungsregister gespeichert sein. Wie es oben erörtert ist,
kann die verteilte Verriegelung kollektiv implementiert und für eine Steuerung
eines gleichzeitigen Zugriffs durch Prozesse oder Verarbeitungsentitäten, die
durch ein Nachrichtenleitsystem miteinander kommunizieren, verwendet
werden. Obwohl verteilte Prozesse und/oder Verarbeitungsentitäten, die
durch ein Computernetzwerk verbunden sind, ein nützliches Beispiel eines Systems
sind, bei dem verteilte Verriegelungen Gebrauch finden können, können verteilte
Verriegelungen, die durch das Verfahren der vorliegenden Erfindung
implementiert werden, ferner Gebrauch für eine Gleichzeitigkeitssteuerung
mehrerer Prozesse, Teilprozesse (threads) oder anderer derartiger
Verarbeitungsentitäten
Gebrauch finden, die innerhalb einer einzigen Verarbeitungsentität ausführen, wobei
die Prozesse, Teilprozesse oder anderen Verarbeitungsentitäten durch
eine gewisse Form eines Nachrichten Leitens miteinander kommunizieren,
einschließlich eines
Nachrichten Leitens eines gemeinschaftlich verwendeten Speichers.
-
Die
vorhergehende Beschreibung verwendete zu Erläuterungszwecken eine spezifische
Nomenklatur, um ein gründliches
Verständnis
der Erfindung zu liefern. Es ist einem Fachmann auf dem Gebiet jedoch
ersichtlich, dass die spezifischen Details nicht erforderlich sind,
um die Erfindung zu praktizieren. Die vorhergehenden Beschreibungen
spezifischer Ausführungsbeispiele
der vorliegenden Erfindung sind zu Darstellungs- und Beschreibungszwecken vorgelegt.
Dieselben sollen nicht erschöpfend
sein oder die Erfindung auf die präzisen, offenbarten Formen begrenzen.
Offensichtlich sind viele Modifikationen und Variationen angesichts
der obigen Lehren möglich.
Die Ausführungsbeispiele
sind gezeigt und beschrieben, um die Prinzipien der Erfindung und
die praktischen Anwendungen derselben am besten zu erläutern, um
dadurch anderen Fachleuten auf dem Gebiet zu ermöglichen, die Erfindung und
verschiedene Ausführungsbeispiele
mit verschiedenen Modifikationen, wie dieselben für die spezielle
betrachtete Verwendung geeignet sind, am besten zu nutzen. Es ist
beabsichtigt, dass der Schutzbereich der Erfindung durch die folgenden
Ansprüche
und die Äquivalente
derselben definiert ist.