Synchronisation von verteilten Prozessen Verteilte Systeme Hochschule Regensburg Vorlesung 9, 13.06.2012 Universitätsstraße 31, 93053 Regensburg Die Synchronisation verteilter Prozesse ist verwandt mit deren Kommunikation ◮ ◮ für abgestimmte Zusammenarbeit für effizientes Ressourcen-Sharing Wir sehen uns daher genauer an: ◮ Prof. Dr. Jan Dünnweber ◮ ◮ ◮ ◮ Verfahren zur verteilten Synchronisation Absolute & logische Zeit (timestamps) Verteilter globaler Status Datenbankzugriffe mit JDBC und Pro*C Transaktionen in verteilten Systemen Prof. Dr. Jan Dünnweber, Folie 2 von 46 Uhren-Synchronisation Uhren-Synchronisation: Allgemein Die Systemzeit wird i.d.R. vom Betriebssystem verwaltet und für Anwendungen bereitgestellt Beispiel: Das Unix-Programm make ◮ ◮ Verteilte Systeme wertet die Zeiten aus, zu denen Quell- und Objektdateien zuletzt geändert wurden (mittels timestamps) entscheidet welche Dateien neu kompiliert werden sollen Mehrere Uhren ⇒ Probleme im verteilten System: Man ermittelt exakte Zeit mittels Atomuhren und passt sie der Sonnenzeit an (daylight saving DST) Diese Zeit (UTC: Universal Coordinated Time) wird von einem Sender in den USA (WWV) bereitgestellt Wenn es in einem verteilten System einen Server mit WWV-Empfänger gibt, synchronisiert diese die anderen Computer Die regelmäßige Synchronisation kann mittels verschiedener Algorithmen bewerkstelligt werden Prof. Dr. Jan Dünnweber, Folie 3 von 46 Verteilte Systeme Prof. Dr. Jan Dünnweber, Folie 4 von 46 Verteilte Systeme Synchronisation: Berücksichtigung von Latenzen Die Maschine mit dem WWV-Empfänger heißt Zeit-Server Periodisch fragt jede Maschine beim Zeit-Server nach der aktuellen Zeit, der Server reagiert so schnell wie möglich: Uhren-Synchronisation: Algorithmen Berkeley-Algorithmus: ◮ ◮ für Systeme, wo kein WWV-Empfänger vorhanden ist Der Zeit-Server fragt die verteilten Uhren periodisch ab und broadcastet die durchschnittliche Zeit andere Mittelwert-Algorithmen: ◮ ◮ Der Sender darf nicht einfach die empfangene Zeit übernehmen: das würde evtl. zur rückwärts laufenden Zeit führen. Die Client-Uhr wird deshalb schrittweise “verlangsamt” Die Round-Trip Time (RTT) muss berücksichtigt werden (Cristian-Algorithmus, 1989), z. B. durch RTT := (T1 − T0 )/2 Prof. Dr. Jan Dünnweber, Folie 5 von 46 Verteilte Systeme Logische Uhren funktionieren wie Cristian und Berkeley mit Zeitkorrekturen, aber nicht zentralisiert alle Maschinen senden ihre Zeiten und daraus werden lokal Mittelwerte errechnet Es gibt noch viele andere Algorithmen zur Uhren-Synchronisation Prof. Dr. Jan Dünnweber, Folie 6 von 46 Verteilte Systeme Lamport-Zeitstempel: Motivation Zeitstempel: Methode zur Synchronisierung logischer Uhren In vielen Applikationen ist es ausreichend, wenn sich alle Rechner über dieselbe Zeit einig sind Relation “passiert vor” auf Ereignissen: a → b gdw. für alle Prozesse das Ereignis b nach a stattfindet Beachte: Es ist nicht immer unbedingt erforderlich, dass diese Zeit mit der realen Zeit übereinstimmt! Ziel: jedem Ereignis a einen Zeitwert/Zeitstempel C (a) zuordnen, so dass (a → b) ⇒ (C (a) < C (b)) Insbesondere muss gelten: In solchen Fällen spricht man von logischen Uhren Es wurde gezeigt (L. Lamport, Ende der 70-er) ◮ ◮ miteinander arbeitende Prozesse müssen sich nur über die Reihenfolge von Ereignissen einig sein Prozesse, die nicht zusammenarbeiten, müssen ihre Uhren überhaupt nicht synchronisieren Prof. Dr. Jan Dünnweber, Folie 7 von 46 Verteilte Systeme ◮ ◮ wenn a und b zwei Ereignisse innerhalb eines Prozesses sind, und a vor b auftritt, dann gilt C (a) < C (b) ist a das Senden einer Nachricht und b das Empfangen der gleichen Nachricht, dann gilt C (a) < C (b) Darüber hinaus: Korrekturen an der Zeit sind nur durch Addition möglich, nicht durch Subtraktion, da die Zeit nicht rückwärts laufen darf! Prof. Dr. Jan Dünnweber, Folie 8 von 46 Verteilte Systeme Lamport-Zeitstempel: Der Algorithmus Ergänzung zum Lamport-Alg. : Vollständige Reihenfolge Betrachten wir das Beispiel mit drei Prozessen, auf drei Maschinen, mit jeweils eigener Uhr Zusätzliche Forderung ist oft wünschenswert: es gibt niemals zwei Ereignisse, die zu selben Zeit auftreten Dies kann man durch Zuweisen des gleichen Zeitpunkts mit Extra-Prozessnumern sicherstellen, z. B.: 40.1 und 40.2 Somit erreicht man folgende vollständige Reihenfolge aller Ereignisse in einem verteilten System: ◮ ◮ Abb. (a): während für Messages A und B eine plausible Übertragungszeit herauskommt, ist sie für C und D unmöglich (negativ)! Abb. (b): Der Lamport-Algorithmus korrigiert dies: beim Empfangen wird die Zeit ggf. auf (Sendezeit+1) gesetzt Prof. Dr. Jan Dünnweber, Folie 9 von 46 Verteilte Systeme Vollständig sortierter Multicast: Beispiel Motivierendes Beispiel: eine Datenbank repliziert über mehrere Systeme, d. h. Kopien an Orten A und B Ein Kunde zahlt $100,- auf das Konto mit $1000,- ein, und ein Angestellter initiiert gleichzeitig eine Zinsgutschrift von 10% Wenn die Reihenfolge auf Kopien verschieden ist, dann wird an einem Ort das Konto 1200,- und am anderen 1210,aufweisen. ◮ wenn a im selben Prozess vor b auftritt, dann gilt C (a) < C (b) wenn a und b das Senden und Empfangen einer Nachricht darstellen, dann gilt C (a) < C (b) für alle anderen Ereignisse a und b gilt: C (a) 6= C (b) Prof. Dr. Jan Dünnweber, Folie 10 von 46 Verteilte Systeme Vollständig sortierter Multicast: Algorithmus In der o. g. Situation benötigt man einen vollständig sortierten Multicast Man implementiert dies mit Lamport-Zeitstempeln, Annahmen: keine verlorenen Nachrichten, Nachrichten gleiches Senders werden in der Reihenfolge des Absendens empfangen: ◮ ◮ ◮ eine Nachricht wird inkl. ihrer Sendezeit (Zeitstempel) per Multicast an alle geschickt, auch an den Sender Der Empfänger sendet per Multicast eine Bestätigung an alle und fügt die Nachricht in die lokale Warteschlange ein, gemäß ihrem Zeitstempel Mithilfe vom Lamport-Algorithmus werden die lokalen Uhren angepasst, so dass gilt: der Zeitstempel einer Nachricht ist immer kleiner als der Zeitstempel ihrer Bestätigung Zeitstempel sind verschieden und reflektieren eine konsistente globale Reihenfolge der Ereignisse Prof. Dr. Jan Dünnweber, Folie 11 von 46 Verteilte Systeme Prof. Dr. Jan Dünnweber, Folie 12 von 46 Verteilte Systeme Vollständig sortierter Multicast (Forts.) Eigenschaft: Alle Prozesse haben irgendwann dieselbe Kopie der lokalen Warteschlange Eine Nachricht wird von einem Prozess an seine Applikation ausgeliefert gdw. sie am Anfang der Warteschlange steht und von allen anderen Prozessen bestätigt wurde Die ausgelieferte Nachricht wird aus der Warteschlange entfernt und der Applikation übergeben; die zugehörigen Bestätigungen werden gelöscht Weil jeder Prozess dieselbe Kopie der Warteschlange besitzt, werden alle Nachrichten überall in derselben Reihenfolge ausgeliefert = vollständig sortierter Multicast Vektor-Zeitstempel Mit Lamport-Zeitstempeln wird zwar garantiert, dass wenn Ereignis a vor Ereignis b stattgefunden hat, dann gilt: C (a) < C (b) Wenn gilt C (a) < C (b), dann impliziert dies jedoch nicht unbedingt, dass a vor b stattgefunden hat D.h. Lamport-Zeitstempel lösen nicht das Problem der Kausalität Dafür werden Vektor-Zeitstempel benutzt, Vi für Prozess Pi : ◮ ◮ Vi [i] ist die Anzahl der Ereignisse, die bisher in Pi aufgetreten sind; dieser Wert wird beim Auftreten eines neuen Ereignisses in Pi inkrementiert wenn Vi [j] = k, dann erkennt Pi , dass auf Pj bisher k Ereignisse aufgetreten sind Für die kausale Nachrichtenauslieferung wird beim Versenden jeder Nachricht der aktuelle Vektor des Prozesses mitgegeben; (vgl. [Tanenbaum, van Steen]) Prof. Dr. Jan Dünnweber, Folie 13 von 46 Verteilte Systeme Globaler Status Prof. Dr. Jan Dünnweber, Folie 14 von 46 Verteilte Systeme Momentaufnahme und Schnitte Der globale Status eines verteilten Systems besteht aus dem lokalen Status jedes Prozesses, zusammen mit den Nachrichten, die zwar gesendet aber noch nicht ausgeliefert wurden in Abb. (a) ist der Schnitt konsistent: alle empfangenen Nachrichten besitzen eine Aufzeichnung des Sendens in Abb. (b) ist der Schnitt inkonsistent: die Momentaufnahme enthält kein Sendeereignis für die Nachricht m2 , empfangen durch P3 Der lokale Status eines Prozesses ist davon abhängig, woran wir interessiert sind: Datensätze, Variablen, etc. Die Kenntnis des globalen Status ist oft hilfreich: z. B. zur Analyse der aktuellen Situation (Deadlock, erfolgreiches Beenden, etc.) Das Aufzeichnen des globalen Status basiert auf dem Konzept einer verteilten Momentaufnahme, engl. snapshot, die einen konsistenten globalen Status reflektiert Prof. Dr. Jan Dünnweber, Folie 15 von 46 Verteilte Systeme Prof. Dr. Jan Dünnweber, Folie 16 von 46 Verteilte Systeme Der Snapshot Algorithmus von Chandy und Lamport Verteilte Snapshot: Ablauf Voraussetzung: unidirektionalen FIFO Verbindungen (z. B. TCP) und jeder Prozess kann (im Applikationsbetrieb) den Snapshot initiieren Der Initiator zeichnet seinen lokalen Status auf, und sendet dann eine Markierung üher jeden ausgehenden Kanal Wenn Prozess Q eine Markierung erhält: ◮ ◮ ◮ wenn Q seinen lokalen Status noch nicht gespeichert hat, zeichnet er seinen lokalen Status auf und sendet eine Markierung üher jeden ausgehenden Kanal hat Q seinen Status bereits aufgezeichnet, ist die Markierung ein Kennzeichen dafür, dass Q den Status des eingehenden Kanals mit der Markierung aufzeichnen sollte dieser Status wird durch die Abfolge der Nachrichten gebildet, die von Q empfangen wurden, seit Q zuletzt seinen eigenen lokalen Status aufgezeichnet und bevor er die Markierung empfangen hat →research.microsoft.com/en-us/um/people/lamport/pubs/chandy.pdf Prof. Dr. Jan Dünnweber, Folie 17 von 46 Verteilte Systeme Verteilte Momentaufnahme: Anwendung Ein Prozess hat seinen Teil des Algorithmus abgeschlossen, wenn er auf jedem seiner eingehenden Kanäle eine Markierung empfangen und verarbeitet hat Sein aufgezeichneter lokaler Status sowie der Status für jeden Kanal werden gesammelt und an den initiierenden Prozess gesendet Beachte: Gleichzeitig mit der Momentaufnahme können auf dem verteilten System Applikationen sowie Momentaufnahmen initiiert von anderen Prozessen laufen Anwendung: Erkennung einer verteilten Terminierung: ◮ ◮ ◮ es muss entschieden werden, ob alle Prozesse ihre Aktivitäten beendet haben insbesondere muss berücksichtigt werden, ob es sich keine Nachrichten in Übertragung befinden, die weitere Aktivitäten verursachen könnten Dafür benutzt man den snapshot Algorithmus Prof. Dr. Jan Dünnweber, Folie 19 von 46 Verteilte Systeme Prof. Dr. Jan Dünnweber, Folie 18 von 46 Verteilte Systeme Verteilte Momentaufnahme: Implementierung Zur Veranschaulichung des Chandy & Lamport-Algorithmus sehen wir uns die Implementierung von Vijay K. Garg an Der komplette Quelltext ist auf der Homepage http://users.ece.utexas.edu/~garg zu finden und in Gargs Buch Concurrent and Distributed Computing in Java dokumentiert (IEEE Press, ISBN: 9780471432302) Die für uns relevanten Codefragmente und Folien sind auch auf unserer Vorlesungsseite verlinkt Idee: ◮ ◮ ◮ Wir assoziieren jeden Prozess mit einer Farbe: weiß oder rot, initial sind alle Prozess weiß Der globale Snapshot stimmt mit dem Zustand überein bevor alle Prozess rot werden Der lokale Zustand eines Prozesses ist somit der Zustand bevor dieser Prozess rot wird Prof. Dr. Jan Dünnweber, Folie 20 von 46 Verteilte Systeme Verteilte Momentaufnahme in Java: Eigenschaften Das Interface für globale Momentaufnahmen public interface Camera extends MsgHandler { void globalState(); } Das Interface für lokale Momentaufnahmen public interface CamUser extends MsgHandler { void localState(); } Jede Farbänderung wird an alle Nachbarprozesse kommuniziert Sobald eine entsprechende Nachricht eingeht, ändert der empfangende Prozess die eigene Farbe ⇒ folglich werden, sobald ein Prozess rot wird, auch alle direkt oder indirekt von diesem Prozess aus erreichbaren Prozesse rot Prof. Dr. Jan Dünnweber, Folie 21 von 46 Verteilte Systeme Datenbankzugriffe mit Pro*C Die Darstellung einzelner Prozesse in Java Grundlegende Pozess-Struktur bei Vijay K. Garg public class Process implements MsgHandler { int N, myId; public Process(...) { ... myId = comm.getMyId(); N = comm.getNumProc(); } public synchronized void handleMsg(...) { ... } public void sendMsg(int destId, String tag, String msg) { Util.println("Sending msg to " + destId + ":" + tag ...); comm.sendMsg(destId, tag, msg); } public Msg receiveMsg(int fromId) { try { return comm.receiveMsg(fromId); } catch (IOException e) { System.out.println(e); comm.close(); return null; } } Eine Demoprogramm (aus Gargs Buch) zur Veranschaulichung des snapshot-Verfahrens von Chandy und Lamport mit process coloring findet sich auf: http://users.ece.utexas.edu/~garg/dist/dprogs/CameraTester.java Prof. Dr. Jan Dünnweber, Folie 22 von 46 Verteilte Systeme Alternative JDBC in Java Zeiten und Kausalitäten sind v. a. im Zhg. mit Datenbanktransaktionen von Bedeutung int main(int argc, char **argv) { int a; EXEC SQL BEGIN DECLARE; INTEGER a; EXEC SQL END DECLARE; /* ... */ EXEC SQL SELECT salary INTO :a FROM Employee WHERE SSN=876543210; printf("The salary is %d\n", a); return 0u; } Ein C Programm, das auf eine Datenbank zugreift, kann z. B. Embedded SQL (Pro*C) verwenden Die Programme werden unter UNIX mittels proc vorkompiliert, um SQL durch die entsprechenden Bibliotheksaufrufe zu ersetzen Die nötige Konfiguration der Entwicklungsumgebung (z. B. Visual Studio → Übung) für das korrekte Linken der Bibliotheken kann durchaus aufwändig sein Prof. Dr. Jan Dünnweber, Folie 23 von 46 Verteilte Systeme Grundlegend ist das Konzept der (nativen) Treiber (→ Übung) Prof. Dr. Jan Dünnweber, Folie 24 von 46 Verteilte Systeme Ablauf eines Datenbankzugriffs in JDBC 1 Treiber laden 2 Connection URL definieren 3 Verbindung aufbauen 4 Statement Object erzeugen 5 Query ausführen 6 Ergebnisse verarbeiten 7 Verbindung schließen Wir sehen uns diesen Ablauf nun in Java an (→ nächste Folie bzw. Übung) JDBC: Beispeil try { /* load the driver: */ Class.forName("oracle.jdbc.driver.OracleDriver"); } catch { ClassNotFoundException cnfe) { System.out.println("Error loading driver: " cnfe); String host = "dbhost.yourcompany.com"; String dbName = "someName"; int port = 1234; /* def. URL */ String oracleURL = "jdbc:oracle:thin:@" + host + ":" + port + ":" + dbName; Connection connection = /*establish the connection */ DriverManager.getConnection(oracleURL,"MrX", "topsecret"); /* create Statement */ Statement statement = connection.createStatement(); String query = /* exec. Query: */ "SELECT col1, col2, col3 FROM sometable"; ResultSet resultSet = statement.executeQuery(query); while(resultSet.next()) { /* process results */ System.out.println(resultSet.getString(1) + " " + resultSet.getString(2) + " " + resultSet.getString(3)); } connection.close() ; /* close */ ... Obiges Codefragment enthält den gesamten Ablauf einer Datenbankabfrage Prof. Dr. Jan Dünnweber, Folie 25 von 46 Verteilte Systeme Transaktionen in verteilten Systemen: Motivation Motivierendes Beispiel: Flugreservierung mit zwei Zwischenlandungen, d. h. insgesamt drei Buchungsvorgänge Ist der dritte Flug ausgebucht, so wird die ganze Aktivität (Transaktion) angebrochen, und die Ergebnisse der beiden ersten Buchungen werden rückgängig gemacht Zum Programmieren von Transaktionen werden vom Betriebssystem oder vom Laufzeitsystem der Programmiersprache spezielle Funktionen bereitgestellt: BEGIN, END, ABORT, READ, ... Prof. Dr. Jan Dünnweber, Folie 26 von 46 Transaktionen: die ACID-Eigenschaften Transaktionen (TR) haben ACID-Eigenschaften, wie folgt ◮ ◮ ◮ ◮ Prof. Dr. Jan Dünnweber, Folie 27 von 46 Verteilte Systeme Verteilte Systeme Atomar: jede TR wird entweder vollständig, unteilbar ausgeführt (die Zwischenzustände sind nach außen unsichtbar), oder überhaupt nicht Consistent: wenn das System bestimmte Invarianten hat, die immer gelten müssen, und diese vor der TR gelten, dann müssen sie auch nach der TR gelten Isolated: werden mehrere TR gleichzeitig ausgeführt, dann sehen alle Prozesse das Ergebnis so, als wären die TR sequentiell in einer bestimmten Reihenfolge ausgeführt worden Durable: egal was passiert, die Ergebnisse einer TR werden nach dem Festschreiben permanent und können auch durch einen Fehler nicht rückgängig gemacht werden Prof. Dr. Jan Dünnweber, Folie 28 von 46 Verteilte Systeme Klassifizierung von Transaktionen Verschachtelte vs. verteilte Transaktionen Flache TR: Operationsfolge mit ACID-Eigenschaften. Nachteil: evtl. wertvolle Teilergebnisse gehen verloren Verschachtelte TR: ◮ ◮ ◮ wird aus mehreren untergeordneten TR aufgebaut die oberste TR kann untergeordnete TR erzeugen, die parallel zueinander ausgeführt werden beachte: wird eine umschließende TR unterbrochen, müssen auch alle ihr untergeordneten TR abgebrochen werden Verteilte TR: logisch eine flache TR, die auf verteilten Daten arbeitet Prof. Dr. Jan Dünnweber, Folie 29 von 46 Verteilte Systeme Implementierung von Transaktionen Prof. Dr. Jan Dünnweber, Folie 30 von 46 Verteilte Systeme Transaktionsschema Erste Methode: Privater Arbeitsbereich ◮ ◮ ein Prozess erhält einen privaten Arbeitsbereich, mit allen Dateien, auf die er Zugriff hat, und alle Lese- und Schreibzugriffe erfolgen in diesem Bereich Nachteil: Die Kosten des Kopierens sind evtl. zu hoch Optimierung 1: wird eine Datei nur gelesen, dann wird sie nicht kopiert Optimierung 2: bei einer Datei zum Schreiben wird nur der Index der Datei kopiert (z.B. unter Unix: Inode, der angibt in welchem Block der Festplatte sich die Datei befindet) Prof. Dr. Jan Dünnweber, Folie 31 von 46 Verteilte Systeme Wird ein Dateiblock zuerst modifiziert, wird eine Kopie des Blocks angelegt und die Adresse der Kopie wird in den Index eingefügt. Prof. Dr. Jan Dünnweber, Folie 32 von 46 Verteilte Systeme Verarbeitung von Transaktionen Festschreiben von Transaktionen Wenn die Transaktion abbricht, wird der private Arbeitsbereich gelöscht und alle Privatdaten auf die Freiliste zurückgesetzt Wird die Transaktion festgeschrieben, werden die privaten Indizes atomar in den Arbeitsbereich des übergeordneten Prozesses verschoben Bei verteilten Transaktionen: ◮ ◮ ◮ ein Prozess wird auf jeder Maschine mit relevanten Dateien gestartet, und erhält seinen eigenen privaten Arbeitsbereich. wird die TR abgebrochen, verwerfen alle Prozesse jeden privaten Arbeitsbereich die Aktualisierungen werden lokal weitergegeben: wird die TR festgeschrieben, ist sie bereits abgearbeitet Prof. Dr. Jan Dünnweber, Folie 33 von 46 Verteilte Systeme Writeahead-Protokoll Verteilte Systeme Nebenläufigkeit von Transaktionen Die Dateien werden verändert, dabei wird in ein Protokoll (Log) geschrieben welche TR welche Änderungen vornimmt Wird die TR abgebrochen, wird mittels Log der ursprüngliche Status wiederhergestellt – sog. Rollback Für verteilte TR: jede Maschine verwaltet ein eigenes Log und nimmt ggf. einen separaten Rollback vor Prof. Dr. Jan Dünnweber, Folie 35 von 46 Prof. Dr. Jan Dünnweber, Folie 34 von 46 Verteilte Systeme Ziel der Nebenläufgkeitskontrolle: eine konsistente Ausführung mehrerer TR gleichzeitig sicherzustellen Das Endergebnis muss dasselbe sein, als wären die TR sequentiell ausgeführt worden Modell der Kontrolle besteht aus drei Schichten: ◮ ◮ ◮ Datenmanager: führt Lese/Schreibaktionen aus Scheduler: plant die einzelnen Lese/Schreiboperationen so ein, dass Isolation und Konsistenz von TR beibehalten wird TR-Manager: stellt die Atomizität von TR sicher Prof. Dr. Jan Dünnweber, Folie 36 von 46 Verteilte Systeme Serialisierbarkeit (Isolation) Konflikte bei Nebenläufigkeit Bei gleichzeitiger Ausführung sollen TR isoliert bleiben, d.h. das Endergebnis sollte dasselbe sein, als wären sie nacheinander in einer bestimmten Reihenfolge ausgeführt worden Beispiel in der Abb.: drei TR, von drei Prozessen ausgeführt: möglicher Endwert von x: 1,2 oder 3, abhängig von der Reihenfolge Verschiedene Reihenfolgen: Schablone 1 – serialisiert; Sch. 2 – nicht serialisiert, erlaubt; Sch. 3 - nicht erlaubt, Ergebnis: 5. Das Konzept hinter der Nebenläufigkeitskontrolle ist, Konflikte erzeugende Operationen korrekt einzuplanen Zwei Operationen erzeugen einen Konflikt, wenn sie auf demselben Datenelement arbeiten und mindestens eine von Ihnen eine Schreiboperation ist Ansätze zur Kontrolle: wechselseitiger Ausschluss (Sperren) oder eine Festlegung der Reihenfolge durch Zeitstempel Vorgehen: pessimistisch (Konflikte lösen bevor sie auftreten) oder optimistisch (Synchronisierung erst am Ende einer TR; wurde ein Konflikt festgestellt, wird die TR abgebrochen) Prof. Dr. Jan Dünnweber, Folie 37 von 46 Verteilte Systeme Zwei-Phasen-Sperren Prof. Dr. Jan Dünnweber, Folie 38 von 46 Verteilte Systeme Schema für Zwei-Phasen-Sperren Sperre: Prozesse fordern die Sperre vom Scheduler, der Sperren so erteilen soll, dass nur gültige Schablonen entstehen Zwei-Phasen-Sperre (2PL, 2 Phase Locking): eine TR fordert zuerst alle Sperren an und gibt sie anschließend wieder frei ◮ ◮ ◮ Wenn der Scheduler eine Operation vom TR-Manager erhält, überprüft er, ob sie im Konflikt mit einer Operation ist, für die bereits eine Sperre erteilt wurde. Bei Konflikt wird die Operation verzögert, sonst wird eine Sperre erteilt Transaktionen die eine Sperre freigegeben haben bekommen sie vom Scheduler nicht wieder erneut erteilt Prof. Dr. Jan Dünnweber, Folie 39 von 46 Verteilte Systeme Prof. Dr. Jan Dünnweber, Folie 40 von 46 Verteilte Systeme Strenge Zwei-Phasen-Sperren Strenge Zwei-Phasen-Sperre: alle Sperren werden zum selben Zeitpunkt freigegeben. Vorteil: Es wird immer ein Wert von bereits festgeschriebenen TR gelesen, somit werden keine Werte gesehen, die ggf. zurückgenommen werden Sperren: Deadlocks und Implementierungsmechanismen Beachte: beide Versionen von 2PL können zu Deadlocks führen: ◮ ◮ ◮ Ursache: zwei Prozesse versuchen, dasselbe Paar von Sperren in entgegengesetzter Richtung zu erhalten Vermeidung: Sperren-Anforderung in einer kanonischen Reihenfolge, damit werden Zyklen verhindert Erkennung: mit Time-Outs, falls die Sperrzeiten bekannt sind Implementierung: Jeder TR-Manager bekommt Sperren von seinem Scheduler und spricht dann direkt mit Datenmanagern Zwei Möglichkeiten: ◮ ◮ Prof. Dr. Jan Dünnweber, Folie 41 von 46 Verteilte Systeme Pessimistische Zeitstempel-Reihenfolge Jede Transaktion T erhält beim Start einen Zeitstempel ts(T ). (Lamport-Uhr garantiert eindeutige Zeitstempel) Jede Operation einer TR bekommt auch den Zeitstempel ts(T ) Jedes Datenelement x im System bekommt: ◮ ◮ ◮ Prof. Dr. Jan Dünnweber, Folie 42 von 46 Verteilte Systeme Pessimistische Zeitstempel: Mögliche Abläufe Transaktion T1 ist festgeschrieben, T2 und T3 starten nebenläufig (ts(T2 ) < ts(T3 )) (a-b): T2 schreibt x, T3 ist später ⇒ Schreiben akzeptiert (c-d): T2 schreibt x, aber T3 ist früher ⇒ Abbruch von T2 einen Lese-Zeitstempel: tsRD (x) – Zeitstempel der TR, die zuletzt x gelesen hat einen Schreib-Zeitstempel: tsWR (x) – Zeitstempel der TR, die zuletzt x geändert hat Bei einem Konflikt verarbeitet der Datenmanager zuerst diejenige mit dem kleinsten Zeitstempel Beispiel: Scheduler bekommt read(T , x) mit dem Zeitstempel ts: ◮ Primäre 2PL: jedem Datenelement wird eine primäre Kopie zugeordnet; der Scheduler auf der Maschine dieser Kopie ist fürs Erteilen/Freigeben von Sperren verantwortlich Verteilte 2PL: Daten über mehrere Maschinen repliziert. Die Scheduler auf jeder Maschine kümmern sich nicht nur ums Erteilen/Freigeben von Sperren, sondern auch für die Replikation (Weitergabe von Operationen an Datenmanager) wenn ts < TSWR (x) – die Transaktion T wird abgebrochen wenn ts > TSWR (x) – die Leseoperation wird stattfinden, tsRD (x) wird auf max{ts, tsRD (x)} gesetzt Für eine Schreibe-Operation: analog bzgl. tsRD (x) Prof. Dr. Jan Dünnweber, Folie 43 von 46 Verteilte Systeme (e): T2 liest ohne Konflikte (f): T2 wartet auf Schreiben von T3 (g-h): Abbruch von T2 da zu spät (T3 festgeschrieben) Vergleich: Zeitstempel vs. Sperren: ◮ ◮ Abbruch bei Zeitstempeln statt Warten bei Sperren Dafür keine Deadlocks! Prof. Dr. Jan Dünnweber, Folie 44 von 46 Verteilte Systeme Optimistische Zeitstempel Zusamenfassung Nebenläufigkeitskontrolle ist in diesem Fall einfach: Es wird beobachtet was gelesen/geschrieben wurde Erst beim Festschreiben werden alle anderen TR geprüft: wenn sich Elemente seit dem TR-Beginn geändert haben, wird die TR abgebrochen, sonst festgeschrieben Gut geeignet wenn die Implementierung auf privaten Bereichen basiert: jede TR ändert ihre Daten privat; am Ende wird entweder festgeschrieben oder abgebrochen Vorteile: Deadlock-Freiheit und maximale Parallelverarbeitung Nachteil: Gefahr der Abbrüche, besonders bei hohen Lasten Prof. Dr. Jan Dünnweber, Folie 45 von 46 Verteilte Systeme Synchronisierung: “zur richtigen Zeit passiert das Richtige” Allg. Problem: die Uhren in Computern gehen unterschiedlich Verschiedene Ansätze zur Uhr-Abstimmung mittels Nachrichten (Atomuhren, Mittelwerte usw.) Oft ausreichend: “logische Uhren”, d.h. die Event-Reihenfolge Lamport & Chandy-Alg.: Globale Einigung auf Event-Reihenfolge mittels Markern Eine Veranschaulichung des snapshot-Verfahrens liefert die Implementierung von Garg (→ Übung) Globaler Status eines VS: lokaler Status der Prozesse + gerade übertragene Nachrichten; kann durch Momentaufnahme ohne Systemunterbrechung aufgezeichnet werden Datenbankzugriffe mittels JDBC oder Pro*C (→ Übung) Transaktionen: die ACID-Eigenschaften; Implementierung und Nebenläufigkeitssteuerung (Sperren und Zeitstempel) Prof. Dr. Jan Dünnweber, Folie 46 von 46 Verteilte Systeme