\documentclass[bibtotocnumbered, headsepline,normalheadings]{scrreprt} \usepackage[latin1]{inputenc} \usepackage{german} \usepackage{scrpage} \usepackage{eurosym} \usepackage{alltt} \usepackage{graphicx} \usepackage{hyperref} \pagestyle{headings} \begin{document} \title{Vorlesungsmitschrift \\ Verteilte Systeme \\ SS 2007 FH-Aachen} \author{Bei Prof. Dr.-Ing. O{\ss}mann \\ \\ Getext von Paul B\"{u}tow} \date{Letzte Aktualisierung: \today} \maketitle \tableofcontents \newcommand{\m}[1]{$~\qquad {#1}$\\} \newcommand{\n}[1]{$~\qquad {#1}$} \newcommand{\q}{$ ~ \qquad $} \newcommand{\bs}{$\backslash$} \newcommand{\pre}[1]{\texttt{{#1}}} \newcommand{\set}[1]{\{{#1}\}} \newcommand{\ra}{ \rightarrow } \newcommand{\Ra}{ \Rightarrow } \newcommand{\E}{$\epsilon$} \newcommand{\N}{\mbox{$I\!\!N$}} \chapter{Diverses} \section{Ein bischen Blabla...} Ich garantiere nicht, dass der Inhalt dieses Dokuments weder korrekt noch vollst\"{a}ndig ist. \textit{Kursiv geschriebene Kommentare habe ich selbst hinzugef\"{u}gt.} Bei Fehlern bitte per E-Mail (\texttt{skript@paul.buetow.org}) an mich wenden! \subsection{Anmerkung zu den Grafiken} Die Grafiken sind etwas pixelig/unscharf. Ich bitte dies zu entschuldigen. Sie erf\"{u}llen jedoch ihren Zweck. \subsection{Download URL} Das aktuelle Dokument mitsamt Sourcen liegt unter:\\ \url{ftp://ftp.buetow.org/pub/studium/FHAC\_VS-SS07/} \subsection{Technische Informationen} Falls es interessiert: Dieses Dokument wurde erstellt mithilfe von: \begin{itemize} \item LaTeX, rubber, make \item Dia (http://www.gnome.org/projects/dia/) \item Vim (http://www.vim.org) \item FreeBSD (http://www.FreeBSD.org) \end{itemize} \chapter{Vorlesung} \section{\"{U}berblick} \begin{itemize} \item Grundeigenschaften \item Systemmodelle \item Netzwerke, Interprozesskommunikation \item Verteilte Objekte, entfernte Aufrufe \item Verteilte Dateisysteme \item Namensdienste \item Zeit und globale Zust\"{a}nde \item Koordination und Nebenl\"{a}ufigkeitskontrolle \item Transaktionen \item Replikationen \end{itemize} \section{Literatur} \begin{itemize} \item Coulouris, Dollimore, Kindberg ``Verteilte Systeme'' \item Tanenbaum, van Steen ``Verteilte Systeme'' \end{itemize} \section{Grundeigenschaften} Grundeingenschaften verteilter Systeme: Zusammenarbeit mehrerer Komponenten auf vernetzten Computern. Koordination und Kommunikation erfolgt durch den Austausch von Nachrichten.\\ \\ Daraus ergibt sich die Nebenl\"{a}ufigkeit der Komponenten. Keine globale Uhr. Unabh\"{a}ngige Ausf\"{a}lle von Komponenten. \section{Beispiele} \begin{itemize} \item Tauschb\"{o}rsen \item Sichere Speicherung auf verteilten Servern \item Mobiles und Allgegenw\"{a}rtiges \item Rechnen \end{itemize} \section{Motivation} Motivation f\"{u}r den Aufbau verteilter Systeme: Gemeinsame Nutzung von Ressourcen.\\ \\ Was ist der Unterschied zur Betriebssystem-Motivation? \begin{itemize} \item Heterogenit\"{a}t der Komponenten \item Offenheit (weltweit akzeptierte Standards) \item Sicherheit bei Teilausf\"{a}llen (Fehler, Angriffe) \item Skalierbarkeit (Systeme wachsen) \end{itemize} \section{Beispiele f\"{u}r gemeinsam genutzte Ressourcen} \begin{itemize} \item Hardware: Drucker, Festplatten \item Daten: Dateien \item Dienste z.B. Suchmaschinen \end{itemize} \section{Client Server Modell} In verteilten Systemem verwendet man oft das ``Client Server Modell''. Ein Server bietet einen Dienst (Service) an (``passiv''). Ein Client fragt bei einem Server nach einen Dienst (``request for service'').\\ \\ Die Dienste bergrenzen den Ressourcenzugriff auf eine wohldefinierte Operationsmenge. Implementation von Servern erfolgt \"{u}blicher Weise durch einen Prozess auf einem vernetzten Computer. \begin{enumerate} \item Client: Ruft eine Operation auf dem Server auf \item Server: Schickt Antwort \item Client: Erh\"{a}lt die Antwort \end{enumerate} $\ra$ ``Eine Interaktion'', ``remote invocation''\\ \\ Remote hei{\ss}t nicht ``geometrisch entfernt''. Besser: Es wird ein Dienst erbracht, der in einem anderen Adressraum bereitliegt. \begin{figure}[htbp] \begin{center} \includegraphics[width=100mm]{vs1.png} \end{center} \end{figure} \subsubsection{Frage} Gibt es in Java einen Adressraum? Antwort: Ja (Siehe NullPointerException).\\ \\ Ein Prozess kann gleichzeitig Client und Server sein. \begin{figure}[htbp] \begin{center} \includegraphics[width=105mm]{vs3.png} \end{center} \end{figure} \"{A}hnliche Beziehung: Funktions- bzw. Methodenaufruf. Server werden ``st\"{a}ndig'' ausgef\"{u}hrt. Clients reden mit der \"{u}bergeordneten Applikation. Das Client-Server Modell beschreibt viele verteilte Systeme (nicht alle). \section{Ziele beim Design eines verteilten Systems} Ber\"{u}cksichtigt werden: \begin{itemize} \item Heterogenit\"{a}t \item Offenheit \item Skalierbarkeit \item Sicherheit (gegen Angriffe) \item Fehlertoleranz \item Nebenl\"{a}ufigkeit \item Transparenz \end{itemize} \subsection{Heterogenit\"{a}t} Heterogenit\"{a}t in den Bereichen \begin{itemize} \item Netzwerk \item Computerhardware \item Betriebssysteme \item Programmiersprachen \end{itemize} Wesentliches Hilfsmittel zur Implementation heterogener Systeme: Einf\"{u}hrung einer Middleware. Middleware ist eine Softwareschicht, die eine Programmierabstraktion zur Verf\"{u}gung stellt, und die Heterogenit\"{a}t des darunterliegenden Systems verbirgt. \begin{figure}[htbp] \begin{center} \includegraphics[width=30mm]{vs4.png} \end{center} \end{figure} \\ Beispiele: Java, RMI, CORBA, SQL, RPC. (Bereitstellung einer einheitlichen Programmierschnittstelle). \subsection{Offenheit} Ziel Offenheit (Um sp\"{a}ter Erweiterungen vornehmen zu koennen). Z.B. Hinzuf\"{u}gung neuer Dienste f\"{u}r unterschiedliche Client-Programme. \begin{itemize} \item Ziel wird erreicht durch Offenlegung der Spezifikation aller Softwareschnittstellen \item Wird unterst\"{u}tzt durch Standardisierung der Schnittstellen. \end{itemize} Beispiele f\"{u}r Offenheit: \begin{itemize} \item Internet-Protokolle \item RFC (Request For Comment)\\ \url{http://www.ietf.org} \end{itemize} \subsection{Skalierbarkeit} Die Leistungsf\"{a}higkeit von Systemen soll durch Hinzuf\"{u}gen von Komponenten steigen. Steigender Bedarf an Dienstleistungen mu{\ss} mit beschr\"{a}nkten Kosten befriedigt werden.\\ \\ Ist ein Linux-Cluster ein skalierbares System? Nur schwer skalierbar (wg. Neuverkabelung bei Hinzunahme neuer Rechner).\\ \\ Wachstum bringt oft (relativen) Verlust an Leistung. Beispiel: Finden eines Objekts unter $n$ (Skalierungsgr\"{o}{\ss}e) Objekten. \begin{itemize} \item Bei linearem Suchen: Aufwand $\sim n$ \item Bei bin\"{a}rem Suchen: Aufwand $\sim log(n)$ \end{itemize} Angestrebt wird ein Aufwandswachstum $\approx log(n)$ ($n$ ``Gr\"{o}{\ss}e des Systems'').\\ \\ Weiteres Problem: Manche Ressourcen ersch\"{o}pfen sich! Beispiel: IP-Adressen. Leistungsengp\"{a}sse sollten durch Dezentralisierung vermieden werden!\\ \\ Anfangs: Ein zentraler DNS-Server, der ``alles'' in einer Datei wusste. \subsection{Behandlung von Fehlern} Erkennen von Fehlern: \begin{itemize} \item Pr\"{u}fsummen (``leicht m\"{o}glich'') \item Absturz eines Servers schwer zu erkennen \end{itemize} Maskierung von Fehlern: \begin{itemize} \item Mehrfaches \"{U}bertragen von Nachrichten \item Mehrfache Speicherung von Daten \end{itemize} Frage: Greifen diese Ma{\ss}nahmen garantiert? Nein. Absolute Garantien kann man nie erwarten. Im Normalfall kann man die Sicherheit jedoch ausreichend ``hochschrauben''.\\ \\ ``Tolerieren von Fehlern'' ist eine weitere Vorgehensweise. \begin{itemize} \item Weiterleitung von Fehlern an den Benutzer (\"{u}bergeordnete Schicht). Beispiele: \begin{enumerate} \item Browser findet Seite nicht \item Java: Exception \item C: Nichts (nur einen Crash) \end{enumerate} \item Oft kann die Schicht, die den Fehler feststellt, nicht entscheiden, wie weiter vorzugehen ist. \end{itemize} Zur Maskierung von Fehlern verwendet man oft redundante Komponenten. Beispiele: \begin{itemize} \item Mehrere Routen im Netzwerk \item DNS: Jede Tabelle auf mehreren Servern \item Replizierte Datenbanken (Techniken sp\"{a}ter im Detail) \end{itemize} \subsection{Nebenl\"{a}ufigkeit} ``Gleichzeitige'' Benutzung von einer Ressource durch mehrere Benutzer. Ohne Nebenl\"{a}ufigkeit h\"{a}tten wir die sequentielle Benutzung von Ressourcen. $\ra$ Schlechter Durchsatz. \begin{figure}[htbp] \begin{center} \includegraphics[width=33mm]{vs5.png} \end{center} \end{figure} Im Allgemeinen lassen Server viele Clients gleichzeitig zu. Ressource sei als Objekt gekapselt (Siehe Bild).\\ \\ In vielen F\"{a}llen ist die Synchronisation notwendig um inkonsistente Ergebnisse zu vermeiden. Objekte, die gemeinsam genutzte Ressourcen verwalten, m\"{u}ssen in einer nebenl\"{a}ufigen Umgebung \underline{korrekt} arbeiten. \subsection{Transparenz} Transparenz bedeutet, dass der Benutzer gewisse Details nicht ber\"{u}cksichtigen mu\ss, die die Implementation effizient machen. \begin{itemize} \item \textbf{Zugriffstransparenz:} Lokale und entferne Zugriffe auf Objekte erfolgen mit den gleichen Methoden. Wenn man Sockets verwendet, kann man Nachrichten lokal und entfernt gleichartig verschicken. \item \textbf{Orts- und Positionstransparenz:} Man kann auf Ressourcen zugreifen, ohne ihren Ort zu kennen. Man kann die Ressourcen von verschiedensten Orten aus benutzen. \item \textbf{Nebenl\"{a}ufigkeitstransparenz:} Gemeinsame ``gleichzeitige'' Nutzung ohne Beeintr\"{a}chtigung. \item \textbf{Replikationstransparenz:} Man arbeitet mit Repliken (Kopien) ohne Beeintr\"{a}chtigung. \item \textbf{Fehlertransparenz:} Partielle (teilweise) Ausf\"{a}lle beeintr\"{a}chtigen den Benutzer nicht. \item \textbf{Leistungs- und Skalierungstransparenz:} Das System kann neu konfiguriert oder erweitert werden, um h\"{o}here Leistungen zu erzielen. \end{itemize} \section{Systemmodelle} Modelle heben strukturierte Eigenschaften von Systemen hervor und erm\"{o}glichen eine einheitliche Sichtweise auf verschiedenartige Realisationen. \begin{itemize} \item \textbf{Architektonisches Modell:} Platzierung von Komponenten. Verbindungen und Beziehungen zwischen Komponenten. \item \textbf{Interaktionsmodell:} Zusammenspiel zwischen Teilen beim Nachrichtentausch. \item \textbf{Fehlermodell:} Beschreibung von Fehlerm\"{o}glichkeiten der Prozesse und Kommunikationskan\"{a}le. Festlegung was man als ``korrekt'' bzw. ``zuverl\"{a}ssig'' interpretiert. \item \textbf{Sicherheitsmodell:} Beschreibung von Gefahren durch Angriffe und Abwehrma{\ss}nahmen. \end{itemize} \subsection{Beispiele f\"{u}r architektonische Modelle} \begin{itemize} \item Client - Server \item Peer to Peer (gleichrangige Prozesse) \item Schichten-Architektur \end{itemize} \begin{figure}[htbp] \begin{center} \includegraphics[width=60mm]{vs6.png} \end{center} \end{figure} Die Middleware stellt zur Verf\"{u}gung: \begin{itemize} \item Entfernte Methodenaufrufe \item Kommunikation in Gruppen \item Benachrichtigung \"{u}ber Ereignisse \item Replikation von Daten \item Namensdienste (z.B. Matr.-Nr. in einer HS) \item Sicherheitskonzepte \item Transaktionen \end{itemize} Die \"{U}bertragung von Aufgaben an die Middleware vereinfacht den Entwurf und die Implementation von verteilten Systemen.\\ \\ Aber es gibt Funktionalit\"{a}ten, die vollst\"{a}ndig und zuverl\"{a}ssig nur bei Kenntnis der Applikation implementiert werden k\"{o}nnen. Solche Funktionen kann man nicht vollst\"{a}ndig in Middleware verstecken.\\ \\ \textbf{Beispiel:} Ist TCP/IP die geeigente Middleware um Sicherheit beim Transport von E-Mails zu gew\"{a}hrleisten?\\ \\ $\ra$ TCP/IP ist daf\"{u}r nicht geeignet, weil z.B. keine geeigneten Ma{\ss}nahmen gibt, um l\"{a}ngere Ausf\"{a}lle von Servern zu maskieren! \section{Interaktionsmodelle} \begin{itemize} \item Wer kommuniziert mit wem, wann, warum, ... ? \item Wie beeinflusst das Timing von Nachrichten die Kommunikation und den Ablauf? \item Was ist der ``Zustand'' von einem verteilten Algorithmus? \end{itemize} \subsection{Synchrones verteiltes System} \begin{itemize} \item F\"{u}r die Ausf\"{u}hrungszeit zu jedem Schritt eines Prozesses gibt es bekannte obere und untere Schranken. \item Jede Nachricht wird innerhalb einer begrenzten Zeit (fehlerfrei) empfangen. \item Die Abweichungsgeschwindigkeit von lokalen Uhren im Bezug wahren Zeit ist beschr\"{a}nkt. (\textit{Uhren gehen eigentlich nie zu 100 Prozent gleich. Die Abweichungsgeschwindigkeit ist das, wie schnell Uhren ``auseinanderwandern''}) \end{itemize} Das sind sehr harte Forderungen! Von normalen Systemen sind diese nicht zu erf\"{u}llen. \textit{Dieses Modell ist eigentlich ein Wunschmodell.} (Wahrscheinliche Werte, Mittelwerte usw. sind oft leicht zu erf\"{u}llen). \subsection{Asynchrones verteiltes System} \begin{itemize} \item Keine Begrenzung f\"{u}r Prozessausf\"{u}hrung \item Unbegrenzte Nachrichtenverz\"{o}gerung \item Uhrabweichungen \end{itemize} Schon das ``Einigungsproblem'' zwischen 2 Teilnehmern im asynchronen System ist nicht l\"{o}sbar. \section{Zeit und globale Zust\"{a}nde} F\"{u}r Ereignisse gilt: \begin{itemize} \item Man will wissen, ob ein Ereignis vor oder nach einem anderen Ereignis stattfand (\textit{Wir denken bisher mit vor und nach an die Zeit, sp\"{a}ter werden wir auch an was Anderes denken}). \item Man will wissen, ob man alle Informationen hat, die zu einem bestimmten Ereignis gef\"{u}hrt haben. \item Man will wissen, ob ein System (aus mehreren Komponenten) sich (zu einem Zeitpunkt) in einem Zustand befunden hat. \end{itemize} \textbf{Ansatz 1:} Versuche Uhren zu bauen\\ \\ \q $N$ Prozesse (evtl. auf verschiedenen Rechnern)\\ \\ \q Die echte wahre Zeit sei $t$.\\ \\ \q Hardwareuhr: $H_i(t) \quad i = 1, ..., N$\\ \\ \q Softwareuhr: $C_i(t) = \alpha * H_i(t) + \beta$\\ \\ Ziele: \begin{enumerate} \item $C_i(t) \approx t$\\ \\ $C_i(t) - t$ hei{\ss}t Uhrabweichung von Uhr $i$ zum Zeitpunkt $t$. \item $C_i(t) \approx C_j(t)$\\ \\ $C_i(t) - C_j(t)$ hei{\ss}t Synchronisationsfehler zwischen den Uhren $i$ und $j$ zum Zeitpunkt $t$. \end{enumerate} Uhren werden ``synchronisiert''. $S(t)$ sei eine Referenzuhr (z.B. UTC). \begin{figure}[htbp] \begin{center} \includegraphics[width=115mm]{gps.png} \end{center} \end{figure} \begin{enumerate} \item \underline{Externe Synchronisierung} \"{u}ber einem Zeitintervall gilt f\"{u}r alle $t \in I$:\\ \\ \q $|S(t) - C_i(t) | < D$ f\"{u}r alle $i = 1, ..., N$\\ \\ So heissen die Uhren $C_i$ mit $i = 1, ..., N$ extern synchronisiert mit Genauigkeit $D$. ($D$ ist fest f\"{u}r alle $i$, $t$). Uhrabweichung in $I$ ist kleiner als $D$.\\ \\ $5$ Sekunden Abweichungen pro Tag: $\frac{5s}{24 * 3600s} = 57 * 10^{-6} = 57ppm$\\ \\\textit{Bei billigen Uhren die man im Laden bekommt kann man leicht $10ppm$ erreichen. Atomuhren liegen bei einem Faktor von ca. $10^{-15}$.} \item \underline{Interne Synchronisierung} git f\"{u}r alle $t \in I$ und $i,j \in {1, ..., N}$ dass\\ \\ \q $|C_i(t) - C_j(t) | < D$\\ \\ so heissen die Uhren intern synchronisiert mit Genauigkeit $D$. (Uhren stimmen untereiander bis auf $D$ \"{u}berein. \end{enumerate} Ist ein System extern $D$-Synchronisiert, ist es intern garantiert $2D$-synchronisiert. Wenn ein System intern $D$-Synchronisiert ist, kann das zugeh\"{o}rige externe $D$ beliebig gro{\ss} sein. \subsection{Einige Korrektheitsbegriffe f\"{u}r Uhren} \textit{Eine Uhr die still steht, geht 2 mal am Tag richtig. Eine Uhr die 1 Minute vor geht, geht immer falsch?!? Es ist nicht einfach die Korrektheit einer Uhr zu definieren.} \ \begin{enumerate} \item Eine Hardwareuhr hei{\ss}t korrekt, wenn ihre Abweichgeschwindigkeit (drift-rate) durch eine Schranke $\rho > 0$ begrenzt ist.\\ \\ D.h., der Fehler beim Messen von Intervallen zwischen Echtzeiten $t$ und $t'$ ist begrenzt durch:\\ \\ \q $(1-\rho) (t'-t) \le H(t') - H(t) \le (t'-t) (1+\rho)$\\ \\ \q $ \Leftrightarrow 1-\rho \le \frac{H(t')-H(t)}{t'-t} \le 1 + \rho$\\ \\ \q $ \ra -\rho \le \frac{H(t')-H(t)}{t'-t} -1 \le \rho$ (Gangabweichungsgeschwindigkeit)\\ \\ Erster Korrektheitsbegriff: Gangabweichungsgeschwindigkeit beschr\"{a}nkt.\\ \\ Frage: Darf eine in dem Sinne korrekte Uhr ``springen''? Antwort: \underline{nein}! \textit{Differenzierbare Funktionen m\"{u}ssen stetig sein}. Derartige Uhren d\"{u}rfte man nicht synchronisieren (``stellen''). $\ra$ Dieser Korrektheitsbegriff ist oft zu stark. \item Ein weiterer Korrektheitsbegriff: Eine Hardwareuhr hei{\ss}t korrekt, wenn sie ``monoton'' ist.\\ \\ \q $t < t' \ra H(t) < H(t')$\\ \\ $\ra$ Das ist oft ein zu schwacher Korrektheitsbegriff. \item Eine Hardwareuhr hei{\ss}t korrekt, wenn sie monoton ist und die Gangabweichung zwischen Synchronisationspunkten begrenzt ist. \end{enumerate} \section{Methoden zur Synchronisation} \subsection{Interne Synchronisation in einem synchronem System} Annahme: Die Transportzeit einer Nachricht (vom Senden zum Empfangen) liegt garantiert zwischen $t_{min}$ und $t_{max}$. D.h. $t_{min} \le t_{tr} \le t_{max}$. Die anderen Zeiten seien vernachl\"{a}ssigibar. Nenne $t_{max} - t_{min}$ die ``Unsicherheit''.\\ \\ Prozess $P_1$ senden seine Zeit $t$ in einer Nachricht zu Prozess $P_2$.\\ \begin{figure}[htbp] \begin{center} \includegraphics[width=85mm]{vs7.png} \end{center} \end{figure} $P_2$ setzt beim Empfang seine Zeit auf:\\ \\ \q $t_2 = t + \frac{1}{2}(t_{max} + t_{min}) \ra$ Synchronisationsfehler $< \frac{U}{2}$\\ \\ Wenn man so $N$ Uhren intern synchronisiert, ist der Fehler $\le U(1-\frac{1}{N})$\\ \\ In asynchronen Systemen k\"{o}nnen keine Garantien gegeben werden.\\ \\ Beobachtung: Die Round-Trip Zeit (RTT) in realen Systemen ist oft relativ kurz. \subsection{Christians Methode zur externen Synchronisation} \begin{itemize} \item Es handelt sich um einen ``probabilistischen Algorithmus''. \item Mit Wahrscheinlichkeit $> p_0$ ist eine Synchronisation m\"{o}glich. \item Typische Roundtrip-Zeiten sind $1, ..., 10ms$ \item Abweichungsgeschwindigkeit der lokalen Uhr die zur Roundtrip-Zeimessung benutzt wird, ist vernachl\"{a}ssigbar klein. \item Der Prozess, der mit Round-Trip den Zeitserver nach der Zeit gefragt hat, setzt seine Zeit auf $t$ (Zeitpunkt des Servers) $ + \frac{T_{round}}{2}$ sofern man keine zus\"{a}tzlichen Informationen hat. \end{itemize} Christians Methode: Benutze die Round-Trip Zeit, um die Transportzeit von Nachrichten f\"{u}r den Einzelfall zu ``kennen''.\\ \\ Der Prozess p setzt seine eigene Zeit auf $t + \frac{T_{round}}{2}$. Mit $t :=$ Zeitstempel des Servers. \begin{figure}[htbp] \begin{center} \includegraphics[width=70mm]{vs8.png} \end{center} \end{figure} Annahme: Es ist etwas mehr bekannt, n\"{a}mlich eine untere Schranke $T_{min}$ f\"{u}r den Nachrichtentransport ($\ra T_{round} \le T_{min}$). \begin{figure}[htbp] \begin{center} \includegraphics[width=75mm]{vs9.png} \end{center} \end{figure} Client setzt seine Uhr wie vorher auf $t + \frac{T_{round}}{2}$. Die Genauigkeit ist $\pm(\frac{T_{round}}{2} - T_{min})$.\\ \\ Synchronisiere nur, wenn die beobachte Round-Trip-Zeit klein genug ist. Vorsicht: Beim Synchronisieren sind ggf. Korrektheitsbedinungen (Monotonie o.\"{A}...) zu beachten! \begin{itemize} \item Schutz gegen Ausfall: Einrichtung mehrerer Server. \item Erreichen kleinerer Round-Trip-Zeit: Benutze ``nahe'' Server. \item Problem: Betr\"{u}gerische Server: Kryptologische Methoden (Authentifizierung). \\ Abgleich mehrerer Servern. \end{itemize} \subsection{Berkeley Algorithmus zur internen Synchronisierung} \begin{itemize} \item Auswahll eines Koordinierungsmasters. \item Der Master fragt die Slaves ab. Diese senden ihre eigene Uhrzeiten zur\"{u}ck. \item Der Master sch\"{a}tzt die lokalen Zeiten der Slaves durch Beobachtung der Roundtrip-Zeit. \item Der Master bildet (durch gewichtete Mittelung) eine ``m\"{o}glichst genaue'' Referenzzeit. \item Der Master schickt allen Slaves ``Korrekturwerte'' die angeben, wie sie jeweils aus ihrer lokalen Zeit die Referenzzeit berechnen k\"{o}nnen. \end{itemize} Experiment: 15 Computer kann man in \"{u}blichen LANs relativ leicht auf ca. 25$\mu$s synchronisieren. (Bei ca 10ms Roundtrip)\\ \\ Keine Garantien!\\ \\ Problem (weiterhin): Uhren erm\"{o}glichen es nicht immer, die Frage zu beantworten, ob ein Ereignis a vor einem Ereignis b stattgefunden hat.\\ \\ Einf\"{u}hrung eines anderen Konzepts: \section{Logische Zeit und logische Uhren} Beobachtung: \begin{enumerate} \item Innerhalb eines Prozesses ist es leicht zu entscheiden, was ``fr\"{u}her'' oder ``sp\"{a}ter'' ist. \item Prozesse treten nur mit Nachrichten in Kontakt. (Keine Back-Channels) \end{enumerate} \textbf{Modellvorstellung:} Ein Prozess ist eine wohldefinierte Abfolge von Ereignissen.\\ \\ \textbf{Typische Ereignisse:} Senden einer Nachricht, Empfangen einer Nachricht, Berechnung eines Ergebnisses, \"{A}nderung eines Attributes eines Objekts, Speichern einer Datei. \\ \\ Idee (Lamport) definiere eine ``geschehen vor'' Relation. Relation zwischen zwei Ereignissen.\\ Schreibweise ``$\ra$''\\ \\ Zuerst f\"{u}r Ereignisse in einem Prozess $i$:\\ \\ $l_1 \ra_i l_2 \qquad l_1$ und $l_2$ im selben Prozess, dann ist die Reihenfolge klar.\\ \\ Die durch $\ra_i$ sortierte Folge der Ereignisse in einem Prozess nennt man eine ``history''. Klar ist: Eine Nachricht kann erst empfangen werden, nachdem sie gesendet wurde.\\ \\ Definiere die ``geschehen-vor'' Relation $\ra$ nun wie folgt: \begin{enumerate} \item Falls es einen Prozess $i$ gibt, so dass\\ $l \ra_i e'$ dann gillt $l \ra e'$ \item F\"{u}r jede Nachricht $m$ gilt\\ send($m$)$\ra$receive($m$) \item Es gilt $e\ra e'$ und $e'\ra e''$ dann gilt $e\ra e''\\$ \end{enumerate} Beispiel: \newpage \begin{figure}[htbp] \begin{center} \includegraphics[width=90mm]{vs10.png} \end{center} \end{figure} Ergibt:\\ \\ Wegen 1.: $\quad a\ra b \qquad c\ra d \qquad e\ra f$\\ Wegen 2.: $\quad b\ra c \qquad d\ra f$\\ \begin{figure}[htbp] \begin{center} \includegraphics[width=60mm]{vs11.png} \end{center} \end{figure} \\ Frage: Gilt $e\ra c$?? Kann es sein, dass f\"{u}r zwei Ereignisse $e$ und $e'$ sowohl $e\ra e'$ als auch $e'\ra e$ gilt? Antwort: Nein! \begin{figure}[htbp] \begin{center} \includegraphics[width=70mm]{vs12.png} \end{center} \end{figure} Hier gibt es zwei Begr\"{u}ndungen f\"{u}r $a\ra f$.\\ \\ Es gilt weder $a\ra e$ noch $e\ra a$ so bezeichnet man $a$ und $e$ als nebenl\"{a}ufig. Schreibweise: $a||e$\\ \\ Die ``geschehen vor'' Relation stellt einen m\"{o}glichen Datenfluss dar. Fragen der Art: ``Hat Ereignis $e_i$ das Ereignis $e_j$ m\"{o}glicherweise beeinflusst?'' sollen beantwortet werden.\\ \\ Wie stellt man ``$\ra$'' auf einem Rechner fest?\\ \\ Erster Ansatz: \subsection{Logische Uhr von Lamport} \begin{itemize} \item Jeder Prozess $i$ hat seine eigene logische Uhr $L_i$. $L_i$ w\"{a}chst monoton. \item Die eigene Zeit wird Nachrichten als Zeitstempel mitgegeben. \end{itemize} Wie wird $L_i$ jeweils aktualisiert? $L_i$ wird vor (bei) einem Ereignis in $P_i$ erh\"{o}t. \begin{itemize} \item Sendet Prozess $P_i$ eine Nachricht $m$, so wird der Nachricht der Zeitstempel $t=L_i$ mitgegeben. \item Beim Empfang einer Nachricht berechnet Prozess $P_j$ das Wort $L_j = max(L_j, t)+1$ und weist diesen Stempel dem Empfangsereignis zu. \item Die $L_i$ (Lamport-Zeitstempel) werden mit $0$ initialisiert. \end{itemize} \textit{Diese Definition wurde W\"{o}rtlich aus dem Buch abgeschrieben, nicht ganz Widerspruchsfrei. Daher wirds im Folgenden nochmal Veranschaulicht dargestellt}.\\ \begin{figure}[htbp] \begin{center} \includegraphics[width=110mm]{vs13.png} \end{center} \end{figure} \\ Anschaulich: Das Empfangsereignis bekommt einen Zeitstempel der sowohl h\"{o}her ist als der Stempel des Sendeereignis als auch der Zeitstempel, der im eigenem Prozess vor ihm liegt.\\ \\ Frage: Was kann man aus Lamport-Zeitstempeln ableiten? Beispiel:\\ \begin{figure}[htbp] \begin{center} \includegraphics[width=100mm]{vs14.png} \end{center} \end{figure} \begin{itemize} \item Wenn $e\ra e'$ dann gilt $L(e) < L(e')$ \item Es gilt nicht: $L(e) < L(e') \Ra e\ra e'$ (Ein Beispiel: $L(b) > L(e)$ aber $e||b$) \item Man kann aus $L(e) < L(e')$ nur folgern $e' \not \rightarrow e$ \end{itemize} Manchmal gibt es Probleme, bei welchen sich alle Teilnehmer \"{u}ber eine Reihenfolge einig sein m\"{u}ssen, wobei egal ist, welche Reihenfolge es ist.\\ \\ \textbf{Beispiel:} Eine Bank f\"{u}hrt Konten mehrfach damit man gegen Abst\"{u}rze einzelner Server gesichert ist. Transaktionen (\"{U}berweisungen) werden an alle Server geschickt. F\"{u}r den Kunden ist die Ausf\"{u}hrungsreihenfolge von Transaktionen egal.\\ \\ Korrektheitsforderung: \begin{itemize} \item Jede einzele Transaktion mu{\ss} korrekt gesendet werden. \item Alle Server m\"{u}ssen zu dem gleichen Ergebnis kommen. D.h. die Server m\"{u}ssen sich auf eine (beliebige) Reihenfolge einigen. \end{itemize} Wenn die Server sich nicht einigen k\"{o}nnte folgendes passieren: \begin{figure}[htbp] \begin{center} \includegraphics[width=100mm]{vs15.png} \end{center} \end{figure} \begin{itemize} \item Kunde hat 1000 EUR \item Transaktion A: Einzahlung 100 \officialeuro \item Transaktion B: Verzinsung um 1\% \end{itemize} Dieses Probem kann mit Lamport-Zeitstempeln gel\"{o}st werden, wie im Folgendem gezeigt wird:\\ \\ Grundidee der L\"{o}sung: Alle Server m\"{u}ssen die Transaktionen in der gleichen Reihenfolge ausf\"{u}hren. Angewandtes Konzept ist ein ``vollst\"{a}ndig geordneter Multicast'' (Totally Ordered Multicast).\\ \\ \begin{figure}[htbp] \begin{center} \includegraphics[width=90mm]{vs16.png} \end{center} \end{figure} \begin{figure}[htbp] \begin{center} \includegraphics[width=90mm]{vs16b.png} \end{center} \end{figure} Unterscheide von jetzt an konzeptionell zwischen dem Empfang von Nachrichten und der Auslierferung von Nachrichten. Bei einem ``vollst\"{a}ngig geordneten Multicast'' sorgt die Middleware daf\"{u}r, dass alle Anwendungen die Nachrichten in der gleichen Reihenfolge ausgeliefert bekommen.\\ \begin{enumerate} \item Teilschritt zur Realisation eines vollst. geordn. Multicasts mit Hilfe von Lamport Zeitstempeln: Erweitere die Lamport-Zeitstempel um die Rechner-Nummer (Prozess-ID o.\"{A}.) als Nachkommastelle!\\ \\ $\Ra$ Es gibt keine gleichen Zeitstempel mehr! D.h. f\"{u}r zwei verschiedene Ereignisse $e_1$ und $e_2$ gilt jetzt entweder $L(e_1) < L(e_2)$ oder $L(e_2) < L(e_1)$. \item Teilschritt: Implementiere damit den ``Totally Ordered Multicast'' wie folgt:\\ \\ Jede Nachricht bekommt den Zeitstempel des Senders und wird auch an den Absender gesandt. Empfangene Nachrichten werden in eine lokale Warteschlange eingef\"{u}gt die nach Zeitstempeln geordnet wird.\\ \begin{figure}[htbp] \begin{center} \includegraphics[width=70mm]{vs17.png} \end{center} \end{figure} \\ Nun stelle eine weitere Forderung auf: Die Nachrichten die \underline{ein Sender} abschickt, kommen bei allen Empf\"{a}ngern in der Reihenfolge des Absendens an! \begin{figure}[htbp] \begin{center} \includegraphics[width=70mm]{vs17b.png} \end{center} \end{figure} Diese Forderung ist entscheidend, aber relativ leicht zu erf\"{u}llen (z.B. durch Nummerierung von Paketen oder verbindungsorientiertem Protokoll).\\ \\ Der Empf\"{a}nger einer Nachricht multicastet eine Best\"{a}tigungsnachricht (ACK Acknowledge) an alle anderen Prozesse. (Nachricht bekommt Zeitstempel und wird an den eigenen Absender gesandt!) Nun sammeln sich in den Warteschlangen die Originalnachrichten (die vollst. \textit{geordnet} ausgeliefert werden sollten) und die zugeh\"{o}rigen Best\"{a}tigungen.\\ \\ Eine Nachricht wird aus der Hold-Back Queue ausgeliefert, wenn sie an der Spitze steht und man von allen Prozessen die zugeh\"{o}rige ACK-Meldung bekommen hat. \begin{figure}[htbp] \begin{center} \includegraphics[width=70mm]{vs18.png} \end{center} \end{figure} Damit werden Nachrichten erst ausgeliefert, wenn klar ist, dass alle anderen Prozesse diese Nachricht auch empfangen haben.\\ Vorsicht: Jede Nachricht die ``gemulticastet'' werden soll hat bei $N$ Teilnehmern $N^2$ ACK-Nachrichten zur Folge. \end{enumerate} Die Lamport-Zeitstempel waren nicht geeignet, die ``$\ra$''-Relation auf einfache Weise zu \"{u}berpr\"{u}fen. Deswegen: Erweiterung des Konzepts. \subsection{Vektor-Zeitstempel} \begin{itemize} \item $N$-Prozesse, jeder Prozess $I$ f\"{u}hrt seine eigene Vektor-Uhr $V_i$. Jede Vektor-Uhr $V_i$ ist ein Vektor mit $N$ Eintr\"{a}gen $V_i[j]$. \item Idee: $V_i[j] \quad$ (mit $i \ne j$) ist die Anzahl von Ereignissen in $P_j$, von welchen eventuell ein Datenfluss zu $P_i$ erfolgen konnte. \item $V_i[i]$ ist die Anzahl der Ereignisse, welchen $P_i$ selbst Zeitstempel zugewiesen hat. \item Initialisierung: $V_i[j] = 0 \quad$ f\"{u}r alle $i, j = 1 ..N$. \end{itemize} \begin{figure}[htbp] \begin{center} \includegraphics[width=85mm]{vs19.png} \end{center} \end{figure} Zuweisung eines Zeitstempels zu einem Ereignis: \begin{enumerate} \item Eigenzeit erh\"{o}hen $V_i[i] := V_i[i]+1$ \item Bei einem Sendeereignis schickt man den eigenen Zeitstempel in der Nachricht mit, d.h. die korrekte Vektoruhr. \item Beim Empfang: Nach Erh\"{o}hen der Eigenzeit (vgl. 1) Bildung des Maximums aus empfangenem Zeitstempel und eigener Vektoruhr (elementweise) ergibt neue Vektoruhrzeit. \end{enumerate} \subsubsection{Vergleich von Vektorzeitstempeln} \begin{itemize} \item $v=v' \quad$ iff $\quad v[j] = v'[j]\quad$ ist f\"{u}r alle $j$ \item $v\le v' \quad$ iff $\quad v[j] \le v'[j]\quad$ ist f\"{u}r alle $j$ \item $v< v' \quad$ iff $\quad v[j] \le v'[j]$ und $v\ne v'\quad$ ist f\"{u}r alle $j$ \end{itemize} Man kann zeigen: $e\ra e' \Ra v(e) < v(e')$ \textit{Das ging auch schon bei Lamport-Zeitstempeln}. $\quad$ und $v(e) a$. \item Der folgende Ablauf hat stattgefunden. Dabei bezeichnen $E$ das Editieren der lokalen Dateikopie, $S$ das Senden der lokalen Dateikopie und $R$ das Empfangen der lokalen Dateikopie. Man gebe jeweils die Zeitstempel an, die die Dateikopien erhalten! \item \begin{enumerate} \item Gibt es einen Zeitpunkt, zu dem $b > a$ wahr ist? \item Gilt ``m\"{o}glicherweise $b > a$? \item Gilt ``definitiv $b > a$? \end{enumerate} Sch\"{o}pft also der Systemadministrator in den vorliegenden Situationen Verdacht? Kann er anhand seiner Kenntnisse beweisen, dass $P_2$ unerlauberweise die Datei ge\"{a}ndert hat? \item Wie sieht ein Verlauf aus, in welchem ``m\"{o}glicherweise $b > a$'' nicht gilt? Sie d\"{u}rfen z.B. zus\"{a}tzliche Nachrichten versenden. \item Wie sieht ein Verlauf aus, in welchem ``definitiv $b > a$'' gilt, also ein Ablauf in welchem der Systemadministrator den Nachweis des Verstosses gegen die Regel erbringen kann. Sie d\"{u}rfen z.B. zus\"{a}tzliche Nachrichten einzeichnen. \end{enumerate} \subsubsection{L\"{o}sung} \begin{enumerate} \item Wird $P_2$ nur durch Empfang neuer Versionen von $P_1$ den Wert von $b$ erh\"{o}t, kann nie $b > a$ sein (sofern sich $P_2$ an die Regeln h\"{a}lt). \begin{figure}[htbp] \begin{center} \includegraphics[width=90mm]{vsu3a2.png} \end{center} \end{figure} \item \textit{Was ist jedoch wenn $P_2$ sich nicht an die Regeln h\"{a}lt? Kann man das feststellen?} \begin{figure}[htbp] \begin{center} \includegraphics[width=90mm]{vsu3a2b.png} \end{center} \end{figure} Auswertung der ``$\ra$''-Relation kann der Systemadministrator mit Vektorzeitstempeln durchf\"{u}hren.\\ \item \begin{enumerate} \item Nach $E_3$ und vor $E_2$ ist $a = 4711$ und $b = 4712$ \item ``m\"{o}glicherweise ist $b > a$'\\ \\ Im folgender Linearisierung\\ \\ $E_1 S_1 R_1 E_3 | E_2$\\ \\ gibt es einen globalen Zustand (der mit dem angedeuteten Schnitt aassoziert ist) in welchem $a = 4711\quad b = 4712$ ist, d.h. $b > a$. Es ist also m\"{o}glicherweise $b > a$. \item \textit{Frage anders ausgedr\"{u}ckt:} Gibt es in \underline{jeder} Linearisierung einen globalen Zustand (d.h. Schnitt) in welchen $b > a$?\\ \\ Um zu zeigen, dass (definitiv...) nicht gilt, reicht es also, eine Linearisierung zu finden bei welcher in keinem Zustand $b > a$ ist.\\ \\ \begin{tabular}{|l|l|l|l|l|l|} ~ & $E_1$ & $S_1$ & $R_1$ & $E_2$ & $E_3$ \\ $a=4710$ & $4711$ & $4711$ & $4711$ & $4712$ & $4712$\\ $b=4710$ & $4710$ & $4710$ & $4711$ & $4711$ & $4712$ \end{tabular} \end{enumerate} \end{enumerate} \subsection{Aufgabe 3} \subsubsection{Aufgabenstellung} In einem verteilten System wollen zwei Prozesse hintereinander auf einen gemeinsamen Drucker drucken. Durch einen ``Token'' soll der Zugriff geregelt werden. Nur der Prozess, der das ``Token'' hat, darf drucken. Ein Prozess darf durch Nachrichten an den anderen Prozess versuchen, das Token zu bekommen. Er erh\"{a}lt das Token ebenfalls durch Nachrichtenversand. Veranschaulichen Sie sich, welche Arten von Abl\"{a}ufen mit Ereignissen sich prinzipiell ergeben. Wie kann man erreichen, dass\\ \\ $~ \quad $ m\"{o}glicherweise(``$P_1$ druckt'' und ``$P_2$ druckt'')\\ \\ nicht wahr ist! Gehen sie davon aus, dass Nachrichten fehlerfrei gesendet und empfangen werden. \subsubsection{L\"{o}sung} Ereignisse: $A$ Anfang des Druckens, $E$ Ende des Druckens. \begin{figure}[htbp] \begin{center} \includegraphics[width=100mm]{vsu3a3.png} \end{center} \end{figure} Man m\"{o}chte nicht, dass sich Druckerbelegungen \"{u}berlappen. D.h. man will wechselseitigen Ausschluss.\\ \\ Wenn zwei Prozesse in einem globalen Zustand (d.h. konsistenten Schnitt) jeweils $A$ gemacht haben, und noch keiner $E$, dann sei das Pr\"{a}dikat ``Konflikt'' wahr. \begin{figure}[htbp] \begin{center} \includegraphics[width=100mm]{vsu3a3b.png} \end{center} \end{figure} In einem so programmierten System ist das Pr\"{a}dikat definitiv ($\overline{Konfkikt}$) wahr. Denn in jeder Linearisierung gibt es den angedeuteten Zustand $A_1 | ...$ in welchem $\overline{Konflikt}$ wahr ist.\\ \\ Deswegen ist das Pr\"{a}dikat ``definitiv ($\overline{Konflikt}$)'' f\"{u}r diese Aufgabenstellung nicht hilfreich.\\ \\ Das Pr\"{a}dikat m\"{o}glicherweise (Konflikt) ist besser. Wenn m\"{o}glicherweise (Konflikt) unwahr ist, hei{\ss}t das, dass es in keiner Linearisierung irgendeinen globalen Zustand gibt, in welchem ein Konfliktkt besteht. Das ist das, was man will.\\ \\ Man regele Zugriff durch ein Token. Ein Prozess darf $A$ nur ausf\"{u}hren , wenn er das Token besitzt. Solange ein Prozess ``zwischen $A$ und $E$ ist, darf er das Token nicht versenden. Wir gehen $P_1$ am Anfang des Tokens. Durch die Regeln ist jetzt die Konfliktfreiheit sichergestellt. \subsection{Aufgabe 4} \subsubsection{Aufgabenstellung} Es sei $\varphi$ ein Pr\"{a}dikat in einem verteilten System. Beweisen Sie, dass aus definitiv (nicht $\varphi$) nicht folgt nicht (m\"{o}glicherweise($\varphi$)). \subsubsection{L\"{o}sung} Zu zeigen ist: Aus definitiv($\overline{\varphi}$) folgt nicht $\overline{moeglicherweise \quad \varphi}$.\\ \\ Es reicht, ein Beispiel bei welchen definitiv $\overline{\varphi}$ gilt und m\"{o}glicherweise $\varphi$. \begin{itemize} \item definitiv $\overline{\varphi}$: In jeder Linearisierung gibt es jeweils einen globalen Zustand, so dass $\varphi$ unwahr ist. \item m\"{o}glicherweise $\varphi$: Es gibt eine Linearisierung, so dass $\varphi$ wahr ist. \end{itemize} Pr\"{a}dikate werden in globalen Zust\"{a}nden (Schritten) ausgewertet. Ihr Wahrheitswert kann sich \"{a}ndern.\\ \\ Betrachte Zuweisungen an Variable als Ereignisse. \begin{figure}[htbp] \begin{center} \includegraphics[width=60mm]{vsu3a4.png} \end{center} \end{figure} Im Schnitt $S$ hat $x$ den Wert 5, d.h. $x == 5$ ist ``true''. \begin{figure}[htbp] \begin{center} \includegraphics[width=60mm]{vsu3a4b.png} \end{center} \end{figure} Pr\"{a}dikat $\varphi$: $x = 1$. Im zweiten Bild wird gezeigt:\\ \\ $S_1$ zeigt, dass 1 gilt\\ $S_2$ zeigt, dass 2 gilt \section{\"{U}bung 4} \subsection{Aufgabe 1} \subsubsection{Aufgabenstellung} Der Algorithmus von Maekawa zum wechselseitigen Ausschluss soll f\"{u}r $N=16$ Prozesse implementiert werden. Es soll die in der Vorlesung behandelte einfache Methode zur Bestimmung der W\"{a}hlermengen angewandt werden. Die Prozesse seien von $1..16$ durchnummeriert. \begin{enumerate} \item Geben Sie f\"{u}r die Prozesse $1, 2, 5, 6, 8$ die W\"{a}hlermengen an! \item In wievielen W\"{a}hlermengen ist ein Prozess jeweils enthalten? \item Eine Fordernung an die W\"{a}hlermengen ist, dass je zwei W\"{a}hlermengen mindestens ein gemeinsames Element haben m\"{u}ssen. Ist diese Forderung auch erf\"{u}llt, wenn man die W\"{a}hlermengenbestimming z.B. f\"{u}r $N=12=3*4$ mit einer rechteckigen $3*4$ Matrix anstelle mit einer quadratischen Matrix durchf\"{u}hrt. Kann man stattdessen auch eine $1$x$12$ Matrix nehmen? \end{enumerate} \subsubsection{L\"{o}sung} \begin{tabular}{cccc} 1 & 2 & 3 & 4 \\ 5 & 6 & 7 & 8 \\ 9 & 10 & 11 & 12 \\ 13 & 14 & 15 & 16 \end{tabular} \\ \\ $V_1 = \{1, 2, 3, 4, 5, 9, 13\}$\\ $V_2 = \{1, 2, 3, 4, 6, 10, 14\}$\\ $V_5 = \{1, 5, 6, 7, 8, 9, 13\}$\\ $V_6 = \{2, 4, 5, 7, 8, 10, 14\}$\\ $V_8 = \{4, 5, 6, 7, 8, 12, 16\}$\\ \\ Jede W\"{a}hlermenge hat $7 = 2*4-1 = 2*\sqrt{16} - 1 = 2 * \sqrt{N} - 1$ Elemente.\\ \\ Jeder Teilnehmer ist in $7 = \sqrt{N} - 1$ Mengen enthalten.\\ \\ \begin{tabular}{cccc} 1 & 2 & 3 & 4 \\ 5 & 6 & 7 & 8 \\ 9 & 10 & 11 & 12 \end{tabular} \\ \\ $V_1 = \{2, 5, 6, 7, 8, 10\}$\\ \\ \textit{Man darf es auch mit einer rechteckigen Matrix machen: Jeder kommt gleichviel in jeder W\"{a}hlermenge vor.}\\ \\ \begin{tabular}{cccccccccccc} 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10 & 11 & 12 \end{tabular} \\ \\ $V_1 = \{1, 2, .., 12\}$\\ \\ \textit{Man darf es auch mit einer extrem rechteckigen Matrix machen. Jeder kommt gleichviel in jeder W\"{a}hlermenge vor.}\\ \\ Erweiterung: Was macht man f\"{u}r $N = 13$\\ \\ \begin{tabular}{cccc} 1 & 2 & 3 & 4 \\ 5 & 6 & 7 & 8 \\ 9 & 10 & 11 & 12 \\ 13 & & & \end{tabular} \\ \\ Wenn man nun die ``Zeilen-Spalten''-Konstruktion macht, ist die Frage, ob man noch W\"{a}hlermengen erh\"{a}lt, die wechselseitigen Ausschluss sichern. \\ \\ $V_1 = \{1, 2, 3, 4, 5, 9, 13\}$ hat 7 Elemente\\ $V_2 = \{1, 2, 3, 4, 6, 10\}$ hat 6 Elemente\\ $V_{13} = \{1, 6, 9, 13\}$ hat 4 Elemente\\ \\ Die W\"{a}hlermengen sind nicht mehr alle gleich gross und Teilnehmer sind verschieden oft in W\"{a}hlermengen enthalten.\\ \\ Durch Eintragen ``von oben'' ist gesichert, dass 1 gemeinsames Element bleibt.\\ \\ Wenn ein Teilnehmer abst\"{u}rzt, mu{\ss} man neue W\"{a}hlermengen bestimmen. Frage: Darf man den abgest\"{u}rzten Teilnehmer einfach aus allen W\"{a}hlermengen rausnehmen?\\ \\ \begin{tabular}{cccc} 1 & 2 & 3 & 4 \\ 5 & 6 & 7 & 8 \\ 9 & 10 & 11 & 12 \\ 13 & & & \end{tabular} \\ \\ \textit{Wenn man Teilnehmer 13 rausnehmen w\"{u}rde, dann g\"{a}be es kein Problem.} Falls 5 abst\"{u}rzt und entfernt wird, ist $V_7 = \{3,\not{5}, 6, 7, 8, 11\}$ und $V_{13} = \{1,\not{5}, 9, 13 \}$. D.h. $V_7$ und $V_{13}$ haben kein gemeinsames Element mehr. Die Vorgehensweise, abgest\"{u}rzte Teilnehmer in allen W\"{a}hlermengen zu streichen ist unzul\"{a}ssig. \subsection{Aufgabe 2} \subsubsection{Aufgabenstellung} Das Durchf\"{u}hren einer Zentral-Abiturpr\"{u}fung kann als Operation in einem verteitel System betrachtet werden, wobei die Aufgaben per MULTICAST in die Teilnehmer versandt werden. \begin{enumerate} \item Unterscheidet man bei diesem Problem zwischen ``Empfang'' und ``Auslieferung'' der Nachrichten? Wann wird ausgeliefert? \item Wie wird bei dieser Aufgabe das Problem gel\"{o}st, dass dadurch entsteht, dass es in einem verteilten System keine globale Zeit gibt? \item Liegt einer solchen Prf\"{u}fungsopteration eher ein ``synchrones'' oder ein ``asynchrones'' Systemmodell zugrunde? Wie wird mit ''Nachrichtenverlust'' umgegangen? \item Finden Sie andere Beispiele daf\"{u}r, dass zwischen ``Empfang'' und ``Auslieferung'' einer Nachricht unterschieden wird! \end{enumerate} \subsubsection{L\"{o}sung} \begin{enumerate} \item Die Aufgaben werden per Multicast an die Teilnehmer der Pr\"{u}fung verteilt. Im Normalfall treffen die Aufgaben ``beim Lehrer'' ein, werden aber an die Teilnehmer noch nicht ausgeliefert. Lehrer ist stellvertretend f\"{u}r die Middleware. \item Man verhindert die Kommunikation der Teilnehmer von dem Zeitpunkt an, bei dem die erste Aufgabe ausgeliefert wird. Weil es keine globale Zeit gibt, stoppt man die Kommunikation schon etwas vorher. Dabei setzt man implizit voraus, dass das System synchron ist. Die Aufgaben werden in der Realit\"{a}t einen gewissen Zeitraum vor der Auslieferung versandt um sicherzustellen, dass sie rechtzeitig da sind. Darauf kann man sich nur in einem synchronen System verlassen. Man will, dass entweder alle die gleichen Aufgaben l\"{o}sen, oder keiner irgendeine. \item Beim Design gehen alle davon aus, dass das System sich synchron verh\"{a}lt. Im Normalfall verh\"{a}lt sich die Realit\"{a}t f\"{u}r ein Zentralabitur auch ``synchron genug''. \end{enumerate} \subsection{Aufgabe 3} \subsubsection{Aufgabenstellung} In der Vorlesung wurde ein Algorithmus zum zuverl\"{a}ssigem Multicast vorgestellt. \begin{enumerate} \item Wieviele Nachrichten werden dabei \"{u}ber 1:1 Kan\"{a}le versandt, wenn $N$ Prozesse teilnehmen und keine Prozesse abst\"{u}rzen? Ist die Anzahl davon abh\"{a}ngig, in welcher Reihenfolge Nachrichten bei Prozessen eintreffen? \item Sie modifizieren den Algorithmus dergestalt, dass ein Prozess nur noch an die Prozesse multicastet, von welchen er selbst noch keine Nachricht erhalten hat. \"{U}berlegen Sie sich f\"{u}r den Fall $N=4$ wie solch ein Ablauf dann aussehen kann. Kann man sagen, mit wievielen nachrichten man in deinem g\"{u}nstigen Fall auskommt? \end{enumerate} \subsubsection{L\"{o}sung} \begin{enumerate} \item Jeder Prozess (Teilnehmer) schickt irgendwann im Rahmen seines Basic-Multicasts an jeden Teilnehmer eine Nachricht. D.h. insgesamt werden bei $N$ Teilnehmern $N^2$ Nachrichten verschickt. \item Im Schlimmsten Fall senden alle Teilnehmer nach dem Empfang der ersten Nachricht so schnell, dass sie keine weitere Nachricht empfangen, bevor sie mit dem Senden fertig sind. Dann $N + (N-1)^2$ Nachrichten. \begin{figure}[htbp] \begin{center} \includegraphics[width=65mm]{vsu4a2.png} \end{center} \end{figure} \begin{figure}[htbp] \begin{center} \includegraphics[width=85mm]{vsu4a2b.png} \end{center} \end{figure} Im optimalen Fall sind vermutlich $1 + 2 + 3 + ... + N = N + (N-1) + ... + 1$ Nachrichten erforderlich $= \frac{N * (N+1)}{2} \approx \frac{N^2}{2}$. Ist die gleiche Gr\"{o}ssenordnung aber immerhin Reduktion um $\frac{1}{2}$. \end{enumerate} \subsection{Aufgabe 4} \subsubsection{Aufgabenstellung} Die ``ELECTION'' Schnittstelle stellt zwei entfernte Methoden bereit: \begin{itemize} \item VOTE: Diese Methode verarbeitet zwei Parameter, mit denen ein Client den Namen eines Kandidaten (String) und die Nummer eines W\"{a}hlers (32-Bit Integer) \"{u}bergibt. \item RESULT: Diese Methode verarbeitet zwei Parameter, \"{u}ber die der Server dem Client den Namen des Kandidaten und die Anzahl der Stimmen f\"{u}r diesen Kandidaten mitteilt. \end{itemize} Welche Parameter dieser Methoden sind jeweils Eingabe-, welche Ausgabe-Parameter? Erkl\"{a}ren Sie Marshalling und Un-Marshalling an diesen Parametern. \subsubsection{L\"{o}sung} \begin{itemize} \item \texttt{VOTE} wird beim W\"{a}hlen aufgerufen \item \texttt{RESULT} wird nach der Wahl aufgerufen \end{itemize} \texttt{VOTE(name: STRING; Vnumber: int32)} Beides sind ``in-Parameter''.\\ \\ Darstellung in einer Nachricht \begin{itemize} \item Methoden-ID: int32, Big-Endian 4 Bytes \item \texttt{STRING}: \begin{enumerate} \item Variante: L\"{a}nge 1 Byte gefolgt von 16-Bit Zeichen, und zwar so viele, wie die L\"{a}nge angibt. \item Variante: Folge von Zeichen (z.B. Unicode) gefolgt von einem Terminierungszeichen. \end{enumerate} \begin{figure}[htbp] \begin{center} \includegraphics[width=80mm]{vsu4a4.png} \end{center} \end{figure} \end{itemize} Eventuell baut man ``R\"{u}ckabeparameter'' ein, um aufgetretene Fehler identifizieren zu k\"{o}nnen. Der Proxy k\"{o}nnte evtl. liefern: \begin{itemize} \item ~0: Ich habe eine positive Antwort vom Election-Interface bekommen \item -1: Time-Out, keine Antwort in vorgegebener Zeit \item ... \end{itemize} Das w\"{a}re als ``out-Parameter'' zu betrachten und in der IDL so anzugeben.\\ \\ RESULT: Man gibt einen Kandidatennamen an und erh\"{a}lt wieviele Stimmen er in der Wahl erhalten hat.\\ \\ \texttt{RESULT(in Cname: STRING; out Cvotes: int32)}\\ \\ Marshalling wie oben. Eventuell zus\"{a}tzlich: Detektierte Fehler weiterreichen. \subsection{Aufgabe 5} \subsubsection{Aufgabenstellung} Der ELECTION Dienst mu{\ss} sicherstellen, dass eine Wahl aufgezeichnet wird, wenn ein W\"{a}hler annimmt, dass er seine Wahl abgegeben hat. Beschreiben Sie, welche Auswirkung eine Vielleicht-Aufrufsemantik auf den ELECTION-Dienst hat. Ist eine Mindestens-Einmal Semantik f\"{u}r den ELECTION-Dienst ausreichend oder ist eine H\"{o}chstens-Einmal Semantik empfohlen. \subsubsection{L\"{o}sung} Bei einer ``Vielleicht'' Aufruf Semantik werden Stimmen, deren Nachrichten verloren gehen, nicht gez\"{a}hlt. Da nicht auf Antworten gewartet wird, wird auch nicht wiederholt. Da Nachrichtenverlust (z.B. bei UDP-Paketen) vorkommt, ist diese Korektheitsforderung zu schwach.\\ \\ Variante: Mindestens einmal: \begin{itemize} \item Es werden so lange \texttt{VOTE}-Nachrichten geschickt, bis eine Antwort antrifft. \end{itemize} Bei dieser Variante filtert der Empf\"{a}nger mehrfach eintreffende \texttt{VOTE}-Aufrufe nicht und \texttt{VOTE} wird deswegen eventuell mehrfach aufgerufen und Stimmen werden dann mehrfach gez\"{a}hlt.\\ \\ In diesem Sinne sollte man eine ``H\"{o}chstens einmal``-Semantik implementieren. \subsection{Aufgabe 6} \subsubsection{Aufgabenstellung} Skizzieren Sie eine Implementierung des ELECTION-Dienstes, die sicherstellt, dass Ihre Aufzeichnungen konsistent bleiben, wenn durch mehrere Clients nebenl\"{a}ufig zugregriffen wird. \subsubsection{L\"{o}sung} \begin{itemize} \item Versuche \texttt{VOTE} so zu implementieren, dass mehrfache Stimmenabgabe nur einmal gez\"{a}hlt wird. \item Implementiere \texttt{VOTE} idempotent! \end{itemize} Um herauszubekommen, wer schon Stimmen abgegeben hat, wird eine Hash-Tabelle implementiert mit dem W\"{a}hlernamen als Schl\"{u}ssel. (\texttt{W\"{A}HLER\_TABELLE}).\\ \\ \texttt{W\"{A}HLER\_TABELLE.ISIN(W\"{A}HLER)} liefert \texttt{TRUE} genau dann wenn der W\"{a}hler gew\"{a}hlt hat.\\ \\ Weitere Datenstruktur z\"{a}hlt f\"{u}r jeden Kandidaten die Stimme. (\texttt{VOTES[KANDIDAT]})\\ \\ W\"{a}hlertabelle ist am Anfang leer. \texttt{VOTES} hat am Anfang f\"{u}r alle Kandidaten den Wert 0.\\ \\ \textbf{Implementation:}\\ \\ \texttt{if (! W\"{A}HLER\_TABELLE.ISIN(W\"{A}HLER)) then \{}\\ $~\qquad$ \texttt{ W\"{A}HLER\_TABELLE.PUTIN(W\"{A}HLER, CANDIDATE);}\\ $~\qquad$ \texttt{ VOTES[CANDIDATE]++;}\\ \texttt{\}}\\ \\ Bei einer Wahl soll diese Methode nebenl\"{a}ufig benutzt werden k\"{o}nnen, und f\"{u}r jede eintreffende \texttt{VOTE}-Nachricht wird dann ein \texttt{THREAD} erzeugt, welcher \texttt{VOTE} ausf\"{u}hrt.\\ \\ \textbf{Vorsicht!!!} Die oben angegebene Implementation ist nicht Thread-safe! Die Implementation sollte trotzdem effizient sein. Synchronisation ist n\"{o}tig. \subsection{Aufgabe 7} \subsubsection{Aufgabenstellung} Ein Client nimmt entfernte Prozeduraufrufe auf einem Server vor. Der Client ben\"{o}tigt 5ms, um die Argumente f\"{u}r eine Anforderung zu berechnen, und der Server ben\"{o}tigt 10ms, um eine Anforderung zu bearbeiten. Die lokale Betriebssystemverarbeitungszeit f\"{u}r jede Sende- oder Empfangsoperation betr\"{a}gt 0.5ms. Die Netzwerkzeit f\"{u}r jede Nachricht betr\"{a}gt 3ms. Das Marshalling und das Un-Marshalling ben\"{o}tigen 0.5ms pro Nachricht. Berechnen Sie die Zeit, die der Client ben\"{o}tigt, um zwei Anforderungen zu erzeugen und zur\"{u}ckzukerhen: \begin{enumerate} \item Wenn er single threaded ist \item Wenn er zwei Threads hat, die Anforderungen auf einem einzigen Prozessor nebenl\"{a}ufig ausf\"{u}hren k\"{o}nnen \end{enumerate} Die Zeiten f\"{u}r Kontextumschaltungen k\"{o}nnen Sie ignorieren \subsubsection{L\"{o}sung} Gesamtzeiten der Clientanforderungen: \begin{enumerate} \item Anforderung: Single-Threaded: $(4+6+5+10)$ms $= 25$ms \item Anforderung: 50ms \end{enumerate} \begin{figure}[htbp] \begin{center} \includegraphics[width=100mm]{vsu4a7.png} \end{center} \end{figure} \begin{figure}[htbp] \begin{center} \includegraphics[width=110mm]{vsu4a7b.png} \end{center} \end{figure} Mit 2 Threads 27ms, das ist sp\"{u}rbar besser. \section{\"{U}bung 5} \subsection{Aufgabe 1} \subsubsection{Aufgabenstellung} Warum gibt es keine OPEN- und CLOSE-Operationen in unsere Schnittstelle zum flachen Dateidienst bzw. Verzeichnisdienst. Was sind die Unterschiede zwischen den LOOKUP-Operationen unseres Verzeichnisdienstes und dem OPEN von UNIX? \subsubsection{L\"{o}sung} Die Operationne im flachen Dateidienst sollten so sein, da{\ss} sie einfach mit ``zustandslosen Servern'' zu implementieren sind. Dabei sind beispielsweise idempotente Operationen hilfreich. In diesem Sinne passen die \"{u}blichen ``OPEN'' und ``CLOSE'' Operationen nicht zum flachen Dateidienst. Mit ``OPEN'' werden \"{u}blicherweise Zeiger auf aktuelle Positionen und Puffer f\"{u}r Inhalte angelegt.\\ \\ OPEN im Vergleich zum LOOKUP: \begin{itemize} \item LOOKUP ist eine Operation im Verzeichnisdienst: Name $\rightarrow$ UFID und ist idenpotent \item ``OPEN'' verschmicht Verzeichnisdienst und Dateidienst. Einerseits bekommt man eine Dateireferenz (``handle''), anderseits wird die Verwaltungsstruktur (Zeiger, Puffer, ...) initialisiert (Zustand). \end{itemize} \subsection{Aufgabe 2} \subsubsection{Aufgabenstellung} In einem verteilten System werden mehrere Dateisysteme benutzt. Warum sollten UFIDs eindeutig \"{u}ber all diese Systeme sein. Wie wird die Eindeutigkeit sichergestellt? \subsubsection{L\"{o}sung} In einem einzelnen Dateisystem sind Namen eindeutig! Anderenfalls k\"{o}nnte man Dateien nicht \"{u}ber den Namem referenzieren. Eine einzelne Datei kann durchaus mehrere Namen haben. Will man mehrere Dateisysteme in ein verteiltes Dateisystem integrieren, so m\"{u}ssen die neuen Namen wieder eindeutig sein. Die ``Schreibweise'' von Namen mu{\ss} dabei harmonisiert werden. Oft werden neue Dateisysteme eingebunden indem man eine Baumstruktur verwendet. Dabei bekommen die alten Dateinamen quasi Prefixe die von der Position des Einbaus ins bestehende Dateisystem abh\"{a}ngen. \subsection{Aufgabe 3} \subsubsection{Aufgabenstellung} In welchem Ausma{\ss} weicht SUN-NFS von der Ein-Kopie-Aktualisierungssemantik ab? Konstruieren Sie ein Szenario, in dem zwei Prozesse auf Benutzerebene, die eine Datei gemeinsam nutzen, auf einen einzelnen UNIX-Host korrekt arbeiten, aber Inkonsistenzen aufweisen, wenn sie auf unterschiedlichen Hosts ausgef\"{u}hrt werden. \subsubsection{L\"{o}sung} SUN-NFS garantiert nicht die Ein-Kopie-Aktualisierungssemantik! Notation wie in der Vorlesung: READ liest das einzige Zeichen einer Datei. WRITE schreibt das einzige. 5s Aktualisierungsinterval und G\"{u}ltigkeit von Cache-Eintr\"{a}gen zu pr\"{u}fen. \begin{figure}[htbp] \begin{center} \includegraphics[width=80mm]{vsu5a3.png} \end{center} \end{figure} In diesem Ablauf hat das NFS bereits gegen die Ein-Kopie-Aktualisierungssemantik versto{\ss}en, aber die Applikationen stellen diesen Versto{\ss} noch nicht fest, weil sie relativ harmlose Operationen machen und die zeitlichen Abl\"{a}ufe die Entdeckung erschweren. Versuche zwei Programme so zu schreiben, da{\ss} mit hoher Treffsicherheit der Versto{\ss} gegen die Ein-Kopie-Aktualisierungssemantik bemerkt wird. Idee: Programm A schreibt in die Datei und Programm B soll ``garantiert danach'' lesen, und etwas falsches lesen. Damit das klappt, mu{\ss} B schon auf seinem Client vorher eine Kopie im Cache haben.\\ \\ \textbf{Annahme:} Die Zeitverz\"{o}gerung durch Nachrichtenaustausch und Scheduling sind, im Vergleich zum Aktualisierungsintervall (5s), vernachl\"{a}ssigbar klein (ms Bereich).\\ \\ Damit wirklich was schief geht, synchronisieren sich die Prozesse durch Nachrichten-Austausch. Programmiere wie folgt: \\ \\ \begin{tabular}{l|l} \textbf{Prozess A} & \textbf{Prozess B} \\ \hline Open & Open \\ C = Read & \\ Send(M1) & \\ & Receive(M1) \\ & C = Read \\ & Send(M2) \\ Receive(M2) & \\ Write(A) & \\ Close & \\ Send(M3) & \\ & Receive(M3) \\ & C = Read \\ \end{tabular}\\ \\ Auf einem System, in welchem A und B auf dem gleichen Client laufen, liefert der zweite READ von B auf jeden Fall ``A'', weil es nur eine Client-Cache-Kopie gibt. Ablauf wenn A und B auf verschiedenen Clients laufen: Dateiinhalt am Anfang: ``X''. \begin{figure}[htbp] \begin{center} \includegraphics[width=100mm]{vsu5a3b.png} \end{center} \end{figure} Durch den zus\"{a}tzlichen Nachrichtenversand werden ``Geschehen-Vor''-Beziehungen erzwungen. Dadurch wird das Ergebnis des 2. Reads von B vorhersagbar und ein Versto{\ss} gegen die Ein-Kopie-Aktualisierungssemantik nachweisbar. \subsection{Aufgabe 4} \subsubsection{Aufgabenstellung} Wie geht das ANDREW-FILE-SYSTEM (AFS) damit um, dass CALLBACK-Nachrichten verloren gehen? \subsubsection{L\"{o}sung} Die ``Callbacks'' sind Benachrichtigungen vom (File-) Server zum Client, auf welchem das AFS die Datei cached. Da der Client beim Wiederstart nach einem Absturz seine Callback Promises \"{u}berpr\"{u}ft und erneuert, ist der Verlust von Callbacks kein grosses Problem. \subsection{Aufgabe 5} \subsubsection{Aufgabenstellung} Welche Ziele werden durch Caching auf Client- bzw. Server-Seite in einem verteilten Dateisystem erreicht? \subsubsection{L\"{o}sung} \begin{itemize} \item Client-Caching: Weniger Netzlast, dadurch geringere Antwortzeit f\"{u}r den Client. \item Server-Caching: Weniger Schreib/Lese-Vorg\"{a}nge auf der Festplatte, dadurch schnelleres Dateisystem. Eventuell geringere Antwortzeit des Servers. \end{itemize} \section{\"{U}bung 6} \subsection{Aufgabe 1} \subsubsection{Aufgabenstellung} Ein Server verwaltet die Objekte $a_1, a_2, ..., a_n$. Der Server stellt zwei Operationen f\"{u}r seine Clients bereit: \begin{itemize} \item \textbf{read(i)} gibt den Wert von $a_i$ zur\"{u}ck \item \textbf{write(i,wert)} weist $a_i$ den angegebenen Wert zu \end{itemize} Die Transaktion T und U sind wie folgt definiert: \begin{itemize} \item T: x=read(j); y=read(i), write(j,44); write(i,33); \item U: x=read(k); y=write(i,55), read(j); write(k,66); \end{itemize} Geben Sie eine serielle \"{a}quivalente Verzahnung (``Interleavings'') der Operationen der Transaktionen T und U an. Geben Sie eine nicht seriell \"{a}quivalente Verzahnung der operationen der beiden Transaktionen an! \subsubsection{L\"{o}sung} x und y seien Variablen, die beide Transaktionen gemeinsam benutzen.\\ \\ \begin{tabular}{l|l} \textbf{T} & \textbf{U} \\ \hline x=read(j) & x=read(k) \\ y=read(i) & write(i,55)\\ write(j,44) & y=read(j)\\ write(i,33) & write(k,66)\\ \end{tabular} \\ \\ \\ (Statt $a_j$ schreibe ``$j$''). Ausgangswerte: $i=1, j=2, k=3$.\\ \\ Was ist die Gesamtwirkung f\"{u}r die Reihenfolge $T,U$ und $U,T$?\\ \\ \begin{tabular}{l|l} \textbf{T,U} & Ergebnis \\ \hline x=read(j) & x=2 \\ y=read(i) & y=1\\ write(j,44) & j=44\\ write(i,33) & i=33\\ \hline x=read(k) & x=3\\ write(i,55) & i=55\\ y=read(j) & y=44\\ write(k,66) & k=66\\ \end{tabular}\\ \\ \\ \begin{tabular}{l|l} \textbf{U,T} & Ergebnis \\ \hline x=read(k) & x=3\\ write(i,55) & i=55\\ y=read(j) & y=2\\ write(k,66) & k=66\\ \hline x=read(j) & x=2 \\ y=read(i) & y=55\\ write(j,44) & j=44\\ write(i,33) & i=33\\ \end{tabular}\\ \\ \\ Versuche ein echtes Interleaving, welches seriell \"{a}quivalent ist anzugeben.\\ \\ \begin{tabular}{l|l|l} U1 & x=read(k) & x=3 \\ T1 & x=read(j) & x=2 \\ U2 & & i=55 \\ U3 & & y=2\\ U4 & & k=66\\ T2 & & y=55\\ T3 & & j=44\\ T4 & & i=33\\ \end{tabular} \\ \\ ist seriell \"{a}quivalent zu $U,T$. Vertausche $U1,T1$, dann ergibt sich ein nicht seriell \"{a}quivalentes Interleaving. \subsection{Aufgabe 2} \subsubsection{Aufgabenstellung} Erkl\"{a}ren Sie, weshalb es bei der seriellen \"{A}quivalenz erfoderlich ist, dass eine Transaktion keine weiteren Sperren setzen darf, nachdem sie eine Sperre f\"{u}r ein Objekt freigegeben hat.\\ \\ \textbf{Beispiel:} Ein Server stellt wie in Aufg. 1 read und write zur Verf\"{u}gung. Die Transaktionen T und U wie folgt definiert: \begin{itemize} \item T: x=read(i); write(j,44); \item U: write(i,55); write(j,66); \end{itemize} Beschreiben Sie die Verzahnung der Transaktionen T und U, in denen die Sperren f\"{u}r aufgehoben werden, sodass die Verzahnung nicht seriell \"{a}quivalent ist. \subsubsection{L\"{o}sung} \begin{itemize} \item Keine Sperren, d.h. keine Nebenl\"{a}ufigkeitskontrolle $\Rightarrow$ Geht nicht. \item Sperren f\"{u}r jedes Objekt: Fr\"{u}hzeitiges aufheben von Sperren. D.h. Aufheben wenn die Transaktion das Objekt nicht mehr braucht $\Rightarrow$ das geht immernoch schief. \item Zwei-Phasen-Sperren: Aber gebe Sperren frei, bevor ``COMMIT oder ABORT'' feststeht $\Rightarrow$ Das geht immer noch schief (durch die Wiederherstellung). \item Striktes Zwei-Phasen-Sperren $\Rightarrow$ Funktioniert \end{itemize} Bis hier jedoch noch keine verteilten Transaktionen. Verteilte Transaktionen: Keine globale Nebenl\"{a}ufigkeitskontrolle $\Rightarrow$ Geht evtl. schief. \section{\"{U}bung 7} \subsection{Aufgabe 3} \subsubsection{Aufgabenstellung} Nennen Sie ein Beispiel f\"{u}r die Verzahnung (Interleaving) von zwei Transaktionen, die seriell \"{a}quivalent auf jedem Server, aber nicht global seriell \"{a}quivalent ist. \subsubsection{L\"{o}sung} Vergleiche \"{U}bung 6 Aufgabe 2. Transaktionen: \begin{itemize} \item T: x=read(i); write(j,44); \item U: write(i,55); write(j,66); \end{itemize} T wird zerlegt in: \begin{itemize} \item T$_I$: x=read(i) \item T$_J$: write(j,44) \end{itemize} U wird zerlegt in: \begin{itemize} \item U$_I$: write(i,55) \item U$_J$: write(j,66) \end{itemize} \textit{Folgende Server m\"{u}ssen folgende Operationen ausf\"{u}hren:} \begin{itemize} \item Server I hat T$_I$ und U$_I$ auszuf\"{u}hren. Lokal seriell \"{a}quivalent. \item Server J hat T$_J$ und U$_J$ auszuf\"{u}hren. Lokal seriell \"{a}quivalent. \item Server I macht zuerst I$_I$ (x=read(i)) dann U$_I$ (write(i,55)) \item Server J macht zuerst U$_J$ (write(j,66)) dann T$_I$ (write(i,44)) \end{itemize} \begin{tabular}{ll|ll} \textbf{Server} & \textbf{I} & \textbf{Server} & \textbf{J} \\ \hline & x=1 & & \\ & i=2 & & j=3 \\ T$_I$ & x=2 & U$_J$ & j=66 \\ U$_I$ & i=55 & T$_J$ & j=44 \\ \end{tabular}\\ \\ $\Rightarrow$ x=2, i=55, j=44 $\Rightarrow$ Das Gesamtergebnis ist nicht seriell \"{a}quivalent $\Rightarrow$ Eine globale Nebenl\"{a}ufigkeitskontrolle ist n\"{o}tig. \section{\"{U}bung 8} \subsection{Aufgabe 1} \subsubsection{Aufgabenstellung} Drei Computer stellen einen replizierten Dienst bereit. Die Hersteller behaupten, dass jeder Computer eine mittlere Laufzeit zwischen Fehlern von 5 Tagen hat; ein Ausfall wird normalerweise innerhalb von 4 Stunden repariert. Welche Verf\"{u}gbarkeit hat der replizierte Dienst? Wie \"{a}ndert sich die Verf\"{u}gbarkeit in Abh\"{a}ngigkeit von der Anzahl der Computer? \subsubsection{L\"{o}sung} Verf\"{u}gbarkeit des einzelnen Computers: \begin{itemize} \item Zeit, die er korrekt l\"{a}uft / Gesamte betrachtete Zeit\\ \\ = (5 Tage - 4h) / 5 Tage \\ \\ = $\frac{5 * 24h - 4h}{5 * 24h} = 0,96^-$ \\ \\ = 96,6..\%\\ \\ Die Fehlerwahrscheinlichkeit $p_1$ f\"{u}r einen Einzelrechner betr\"{a}gt also $\frac{4h}{5 * 24h} = 0,03^-$. \end{itemize} Der replizierte Dienst wird als verf\"{u}gbar betrachtet, wenn mindestens in Rechner l\"{a}uft.\\ \\ D.h. er ist nicht verf\"{u}gbar, wenn alle Rechner ausfallen. \begin{itemize} \item Fehlerwahrscheinlichkeit bei 3 Rechnern ist also $p_3 = p_1^3 = 0,000037..$. \item Verf\"{u}gbarkeit: $v_3 = 1 - p_3 = 0,999962...$ \end{itemize} Das entspr\"{a}che einer mittleren Ausfallzeit von $p_3 * 1$ Jahr $\approx 18,9$ Minuten / Jahr.\\ \\ Allgemein: $v_n = 1 - p_1^N$ \newpage \subsection{Aufgabe 2} \subsubsection{Aufgabenstellung} Ein Router, der Prozess p von zwei anderen, q und r, abtrennt, f\"{a}llt aus, unmittelbar nachdem p das Multicasting von Nachricht m initiiert hat. Erkl\"{a}ren Sie, was als N\"{a}chstes passiert, wenn das Gruppenkommunikationssystem ansichtssynchron ist? \subsubsection{L\"{o}sung} Annahme: \\ \\ \begin{figure}[htbp] \begin{center} \includegraphics[width=65mm]{vsu8a2.png} \end{center} \end{figure} \begin{figure}[htbp] \begin{center} \includegraphics[width=90mm]{vsu8a2b.png} \end{center} \end{figure} \begin{figure}[htbp] \begin{center} \includegraphics[width=90mm]{vsu8a2c.png} \end{center} \end{figure} \begin{figure}[htbp] \begin{center} \includegraphics[width=90mm]{vsu8a2d.png} \end{center} \end{figure} 1. Fall: Ein Koordinator realisiert das Kommunikationssystem und er liegt in der N\"{a}he von p. \begin{itemize} \item p teilt dem Koordinator mit, er m\"{o}chte m multicasten. Vorher ist nichts schiefgegangen $\Rightarrow$ p q und r haben also Ansicht (p, q, r) ausgeliefert. \end{itemize} 2. Fall: Koordinator auf gleicher Seite wie q und r und k erlebt das Initiieren des Multicasts noch. \newpage \subsection{Aufgabe 3} \subsubsection{Aufgabenstellung} Zur Reihenfolge der Aktualisierung in replizierten Diensten gibt es die folgenden M\"{o}glichkeiten: \begin{itemize} \item FIFO-Reihenfolge: Wenn ein Frontend die Anforderung r und danach die Anforderung s absetzt, wird jeder korrekte Repliken-Manager, der s verarbeitet, zuvor r verarbeiten. \item Kausale Reihenfolge: Wenn die Anforderung r vor der Anforderung s abgesetzt wurde, wird jeder korrekte Repliken-Manager, der s verarbeitet, zuvor r verarbeiten. \item Vollst\"{a}ndige Reihenfolge: Wenn ein korrekter Repliken-Manager r von der Anforderung von s verarbeitet, wird jeder korrete Repliken-Manager, der s verarbeitet, zuvor r verarbeiten. \end{itemize} Machen Sie sich klar, dass es sich tats\"{a}chlich um verschiedene Reihenfolgen handeln kann. \subsubsection{L\"{o}sung} Bei FIFO sind nur die ``geschehen vor'' Relationen der einzelnen FE $\leftrightarrow$ RM Paare zu erf\"{u}llen, bei ``kausal'' alle, deswegen erf\"{u}llt ein System, welches die kausale Reihenfolge erf\"{u}llt, auch die FIFO Reihenfolge.\\ \\ Aus ``kausal'' folgt nicht ``vollst\"{a}ndig''. Beispiel: \begin{figure}[htbp] \begin{center} \includegraphics[width=90mm]{vsu8a3.png} \end{center} \end{figure} Weil A und B nebenl\"{a}ufig sind, d\"{u}rfen RM1 und RM2 verschiedene Reihenfolgen w\"{a}hlen ohne gegen Kausalit\"{a}t zu versto{\ss}en. Folgt aus ``volst\"{a}ndig'' kausal? \begin{figure}[htbp] \begin{center} \includegraphics[width=90mm]{vsu8a3c.png} \end{center} \end{figure} RM1: C D A B, RM2: A B C D, erf\"{u}llt FIFO, ist aber nicht vollst\"{a}ndig sortiert, ist nicht kausal weil RM1 mit D A dagegen verst\"{o}{\ss}t. \end{document}