3. 3.1 Kommunikation Eigenschaften • Netzbandbreite und –latenz : System Area Network Lokales Netz Internet GSM Datenrate 1 .. 10 GBit/sec 10 .. 1000 MBit/sec 0.01 .. 1.0 Mbit/sec 0.01 .. 0.3 MBit/sec Latenzzeit 0.000002 sec 0.00005 sec 0.005 sec 0,5 sec • Art und Weise der Interaktion der Knoten: - stromorientiert (TCP), nachrichtenbasiert (UDP), verteilter gemeinsamer Speicher (DSM), aufrufbasiert: über Prozeduren (RPC) oder über Objekte (RMI). • Eigenschaften: - 30 Pufferung: gepuffert und ungepuffert, Zuverlässigkeit: Datenverlust möglich?, Adressierung: Uni-, Multi- und Broadcast, Dienstqualität: z.B. garantierte Bandbreite, Übertragungsrichtung: simplex, halb-duplex und voll-duplex, … Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner 3.2 Java Sockets 3.2.1 Allgemeines: • Java Sockets in Package java.net enthalten. • Socketobjekte mit Zustandsvariablen: - eigene & entfernte Portnummer, entfernte Internetadresse (IP), Puffer-Reservierung, Sequenznummern, Protokolltyp ... • Sockets sind Kommunikationsendpunkte: - für Java nur Internet-Protokollarchitektur, - allgemein für irgendeinen Protokollstack, • TCP: - Socket() & ServerSocket() zur verbindungsorientierten Kommunikation, - zuverlässige full-duplex Stromverbindung. • UDP: - DatagramSocket() zur verbindungslosen Kommunikation (UDP), - unzuverlässiger Nachrichtenversand (Sequenz auch nicht garantiert). 31 Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner 3.2.2 Kommunikation über TCP-Sockets in Java: • Beim Erzeugen der Socket-Instanz beim Klienten wird gleichzeitig die Verbindung aufgebaut. • ServerSocket(): - Impliziert keinen Verbindungsaufbau, Ist aber an einen Port gebunden, optionale Warteschlangenlänge, accept() erwartet Verbindung liefert neuen Socket für die eigentl. Kommunikation. • Lesen und Schreiben: - Garantierte End-zu-End Übertragung, - als unstrukturierter Bytestrom, - Full-Duplex ... • Viele Verbindungen an einen Port. • Close() gibt Puffer & Ports frei. 32 write() read() close() Server accept() Klient Socket() ServerSocket() Verbindung aufbauen Anfrage Antwort Warten auf Verbindung read() write() close() Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner 3.2.3 Programmbeispiel für ServerSocket mit TCP import java.io.*; import java.net.*; public class EchoServer { public static void main(String[] s){ ServerSocket sock; Socket conn; DataInputStream in; PrintStream out; String inputMsg; try{ sock = new ServerSocket( 4711 ); conn = sock.accept(); out = new PrintStream( conn.getOutputStream( ) ); in = new DataInputStream( conn.getInputStream( ) ); out.println( "Echo Server active, enter bye to exit.\r"); do{ inputMsg = in.readLine(); out.println("echo: "+ inputMsg +"\r"); if (inputMsg ==null ) break; if (inputMsg.trim( ).equals( "bye") ) break; // trim: Leerz. von beiden Seiten löschen } while( true ); conn.close( ); } catch ( IOException ioX ){ System.out.println( ioX ); } } } 33 Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner 3.2.4 Kommunikation über UDP Datagram-Sockets: • Weniger Protokolloverhead als TCP. Peer • Verbindungsaufbau entfällt. Datagram • Lesen und Schreiben: - als einzelne Pakete/Datagramme, - Keine Ablieferungsgarantie, - Full-Duplex ... • Pufferung im Betriebssystem: - Nachträgliches receive() möglich, - Oder vorsorgliches receive() • Close() gibt Puffer & Ports frei. • IP-Paketfragmente unsichtbar. Socket() send() Datagram Socket() Nachricht receive() receive() Warten auf Paket close() 34 Peer Nachricht send() close() Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner 3.2.5 Programmbeispiel mit Datagram-Sockets: import java.net.* ; import java.io.*; public class UDPClient{ static String url = "voyager.informatik.uni-ulm.de"; static int port = 10001; public static void main (String[] args){ byte[] b = new byte[128]; byte[] name = "Fritz Witz".getBytes(); try{ DatagramSocket socket = new DatagramSocket( ); DatagramPacket packet = new DatagramPacket( name, name.length, InetAddress.getByName( url ), port); socket.send( packet); // String "Fritz Witz" ist gesendet packet.setData( b); packet.setLength( 128); socket.receive( packet); // Puffer für das Antwortpaket vorbereiten // mühselige Stringverarbeitung // Auf Antwort warten, evtl. blockieren String message = new String( packet.getData( ), 0, packet.getLength( )); System.out.printin( "Nachricht empfangen: " + message) ; socket.close(); } catch (Exception e) { e.printStackTrace( ); } }} 35 Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner 3.3 Gruppenkommunikation • Multicast (Gruppenkommunikation): - Versand der Nachricht an viele Teilnehmer, aber nicht an alle, - teilweise von niedrigen Schichten unterstützt (z.B. Ethernet), - besser als (n-1) 1-zu-1 Verbindungen. • Kommunikationstopologien: - 1:n - ein ausgezeichneter Sender, viele Empfänger, - n:n - viele Sender, viele Empfänger, - evtl. kollektive Antwort an Sender. • Benötigt für: - Videokonferenzen, - Distributed Shared Memory, - gemeinsamem Editieren von Dokumenten. • Zuverlässigkeit meist nicht garantiert Æ Paketverlust im Internet. • Ordnung der Nachrichten zufällig Æ Sequenznummern. 36 Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner 3.3.1 Multicast MAC-Adressen: • IEEE 802.3 MAC-Adresse: 7 0 7 0 7 0 7 0 7 0 7 0 xxxxxxLM xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx - 23 Bit für verschied. Multicast-Gruppen, Rest für Header reserviert (siehe IEEE), Universal/Local Bit: 0=weltweit eindeutig, 1=explizit gesetzt (für Multicast), Broadcast/Multicast Bit adressiert eine Gruppe von Stationen oder alle, $FFFF FFFF FFFF ist die Broadcastadresse. Erkennung der Pakete in Hardware. • Abbildung von IP Multicast-Adressen (28-Bit) - erste 5 Bit werden in Praxis ignoriert, - da für Multicast MAC-Adressen nur 23-Bit verfügbar. • MAC-Layer switching Hubs müssen Multicast-Nachrichten im Prinzip auf allen Ports replizieren. Optimierungsmöglichkeiten: - Abgestützt auf das Internet Group Management Protokoll (IGMP), - Interpretation von IGMP Nachrichten im Switch (IGMP snooping), - Proprietäres Protokoll zum Switch (CISCOs CGMP ...) 37 Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner 3.3.2 Multicast IP-Adressen • IP Multicast: - UDP/IP Pakete, Interpretiert durch die Router Software, Adressbereich von 224.0.0.0 bis 239.255.255.255, Keine automatische Erkennung durch die Adapterhardware. • Unterbereiche von IP Multicast Adressen: 224.0.0.x: Multicast auf lokalem Segment, keine Weiterleitung durch Router, 239.x.x.x: Limited Scope Multicast Adressen, Unterstützung durch Router, 224.0.1.0-238.x.x.x: Globally Scoped Multicast Adressen, z.B. Netzdienste. • Reservierte IP-Adressen im lokalen Segment: 224.0.0.1: 224.0.0.2: 224.0.0.12: … Alle Stationen am lokalen Segment, Alle Router am lokalen Segment, DHCP-Server oder DHCP-Proxy am lokalen Segment. • Info: www.cisco.com/univercd/cc/td/doc/cisintwk/ito_doc/ipmulti.htm. 38 Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner 3.3.3 Beispiel: IP Multicast mit Java • Java stellt ein API für IP multicast zur Verfügung. - Beitreten (join) und Verlassen (leave) der Gruppe, - Senden & Empfang von Paketen an die Gruppe. import java.net.*; import java.io.*; public class MulticastPeer{ public static void main(String args[]) { // args: message contents & multicast group (e.g. "224.5.6.7") try { InetAddress group = InetAddress.getByName(args[1]); MulticastSocket s = new MulticastSocket(6789); // with port number s.joinGroup(group); byte [] m = args[0].getBytes(); DatagramPacket messageOut =new DatagramPacket(m, m.length, group, 6789); s.send(messageOut); // get messages from others in group byte[] buffer = new byte[1000]; for(int i=0; i< 3; i++) { DatagramPacket messageIn = new DatagramPacket(buffer, buffer.length); s.receive(messageIn); System.out.println("Received:" + new String(messageIn.getData())); } s.leaveGroup(group); }catch (IOException e){System.out.println("IO: " + e.getMessage());} }} 39 Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner 3.4 RPC - Remote Procedure Call • Grundidee: entfernter Prozeduraufruf von lokalem nicht unterscheidbar: - über Rechnergrenzen und Adressräume hinweg, - synchrone Aufrufssemantik, - f. Klient-Server Szenerien. Klient Server • Client-Stub: - stellt Stub-Prozedur für Aufrufe bereit, Einpacken der Param. (Marshalling), Kommunikation mit Server-Stub, Ergebnisse auspacken (Unmarshalling) Rückgabe an Aufrufer. • Server-Stub: - Annahme von Anfragen vom Netzwerk, Parameter auspacken (Unmarshalling), Aufruf der gewünschten Prozedur, Ergebnisse einpacken (Marshalling), Kommunikation mit Client-Stub. Client-Stub Server-Stub (Server proxy) marshall unmarshall unmarshall marshall • Berücksichtigt heterogene Umgebungen bezüglich: Betriebssystem, Byteanordnungen, Containergrößen, … 40 Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner 3.4.1 RPC-Programmherstellung (Microsoft Windows) • *.c, *.acf, *.idl-Dateien, • MIDL, Server.c Client.c Interf.acf Interf.idl • Stubs, MIDL Compiler • C, • Linker, Interf_C.C (stub) Interf.h Interf_S.C (stub) • Run time … C Compiler Client.obj. Server.obj C Compiler Interf_C.obj Interf_S.obj Client run time Linker Client.exe 41 Linker Server run time Server.exe Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner 3.4.2 Attribute Configuration File interf.acf : • Regelt die Verwendung von Interface-Handles: - dienen der Identifikation eines Interfaces der IDL-Datei und des zugehörigen Servers. - realisiert als globale Variable (deklariert in Stub-Code). • Beispiel: [ implicit_handle(handle_t string_IfHandle) ] interface Interf { } - Mit implicit_handle benutzt das RPC Laufzeitsystem immer die spezifizierte globale Variable: RPC Library Implicit handle - explicit_handle erlaubt verschiedene Remote-Interfaces per RPC anzusprechen: void ExplicitRemoteProcX( handle_t whichServer, [string] char * printMsg); 42 Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner 3.4.3 Interface Definition File interf.idl : • Spezifiziert die Schnittstelle von Remote-Prozeduren auf dem Server, • Universally Unique Identifier mit Programm uuidgen erzeugen, • Schnittstelle hat nur Prozeduren, also keine Instanzen, • IDL als erweiterte Datendeklaration in der Sprache C, • Notwendig, da kein strenges Typenkonzept in C. [ uuid(5AFEB070-D4D5-11d0-9451-002018304F6C), version (1.0), ] interface Interf { void Print( [in, string] unsigned char *pszString); } Klient 43 IDL Server Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner 3.4.4 Parameterübergabe und IDL-Attribute • Marshalling: Konvertierung zwischen Hostformat & Netzwerkformat. • Verschied. Datentypen als maschinenunabhängiges Format (IDL): - 44 boolean, byte, char, double, float, hyper, long, short, small, wchar_t … Containergrössen (z.B. long = 64-Bit), Stringformat berücksichtigen, Byte-Order: Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner • Übergabe von Zeigern in den fremden Adressraum: - Übergabe dynamischer Strukturen nur mit sogenannter "Pointer Emulation", Parameter-Übergabe nötigenfalls nach dem Prinzip von Copy-Restore, Referenz-Zeiger sind konstant und enthalten nie den Wert NULL, Unique-Zeiger dürfen im Zeitpunkt des Aufrufs Null sein, lassen aber eine Allozierung des zurückgelieferten Parameterobjektes zu, - Full-Pointer zeigen auf ein Objekt, auf welches es auch Alias-Zeiger geben darf (teuer wegen Aliasanalyse), - automatische Hüllenbildung, sofern Speicher mit "Hallo Server !" spezieller RPC-Funktion alloziert wurde. • Übergabemodell für Werte und Zeiger: - 45 Kopie des Wertes, Adresse des Wertes, Adresse der Zeigervariablen, Menge aller Zeiger auf das Objekt. Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner • Parametertransport mit speziellen Attributen: - [string, …] mit Nullcharacter abgeschlossener String, - [out, …] nur auf dem Rückweg übertragen, - [in, ...] nur auf dem Hinweg übertragen. • Weitere Attributfunktionen: [in] [out] Server - size_is(..), max_is, min_is, first_is, last_is, length_is … - zum Beispiel für einen Array variabler Größe: // weiteres IDL-Dateibeispiel interface RPC_Array { void myArrayProc( [in, size_is(size)] int *data, int size) } 46 // Array variabler Größe Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner 3.4.5 Quellprogramm client.c: • Argument auf der Befehlszeile enthält einen auszugebenden String. • Durch MIDL erzeugte Interface-Headerdatei mitcompilieren. • Interface Handle ist in der Headerdatei versteckt. • Bind( )-Funktion für Windows-RPC: - Zeichenkette zusammenstellen mit den nötigen Binde-Parametern, Je nach gewähltem Protokoll Verbindung implizit aufbauen, Viele Protokollvarianten wählbar über eine Kennung; Z.B. "ncagn_np" für Microsoft Named Pipes • Hilfsfunktionen: // allocate and free memory for an RPC client object (here string) void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len) { return (malloc(len)); } void __RPC_USER midl_user_free(void __RPC_FAR *ptr) { free(ptr); } 47 Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner • Hauptprogramm: #include <stdlib.h> #include <stdio.h> #include <windows.h> #include "..\interf.h" void main(int argc, char **argv){ // Cmndline Argument implied ! RPC_STATUS status; // status of RPC unsigned char *pszStringBinding=NULL; // binding handle as string unsigned char *pszString = &argv[1]; // string to print // make a concatenated string to feed the binding function - ignore errors here status = RpcStringBindingCompose( NULL, "ncacn_np", // proto.seq.=named-pipe NULL, // network-address "\\pipe\\hello", NULL, // end-point (pipe name) &pszStringBinding ); // the combined string status = RpcBindingFromStringBinding( pszStringBinding, &string_IfHandle); // now do the RPC RpcTryExcept { Print(pszString); } // try our remote print function, use RPC-Macro RpcExcept(1) // every exception is handled here { printf("Runtime reported exception 0x%lx\n", RpcExceptionCode() ); } RpcEndExcept // end the try block, use RPC-Macro // might need to free the strings allocated by the RPC run-time library status = RpcStringFree(&pszStringBinding); // should check for error status = RpcBindingFree(&string_IfHandle); // should check for error } 48 Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner 3.4.6 Quellprogramm server.c: • Protokollsequenz auswählen. • Server-Interface registrieren. Handle wird durch Midl deklariert. • Server einschalten zur Entgegennahme von RPCs - concurrently. • Server stoppen, keine weiteren RPCs. • Registrierung wieder entfernen. • Wie beim Klienten Allozierungsroutinen bereitstellen. • Header und exportierte RPC-Funktion: #include <stdlib.h> #include <stdio.h> #include <windows.h> #include "..\interf.h" void Print(char *pszString) { printf("RPC: %s\n", pszString); } 49 Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner • Hauptfunktion: void main(int argc, char **argv) { RPC_STATUS status; // result status of RPC // tells the RPC library to use the specified protocol sequence combined // with the specified endpoint for receiving remote procedure calls. status = RpcServerUseProtseqEp("ncacn_np", 20, // named-pipe, # of concurrent calls "\\pipe\\hello", NULL ); // end-point name, security descr. // register interface with the RPC library status = RpcServerRegisterIf(string_ServerIfHandle, NULL, NULL ); // start the RPC server, ignore errors ! status = RpcServerListen( 1, 20, 1); getchar(); status = RpcMgmtStopServerListening(NULL); // interface to register (created by midl) // nil UUID, default entry-point-vector // concurrent calls in [1..20], don't wait // wait for any key to shutdown server // shutdown and stop listening status = RpcServerUnregisterIf( NULL,NULL,FALSE ); // unregister any interface // interface to unregister, unregister interface for all UUIDs, shutdown without wait 50 Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner 3.5 RMI - Remote Method Invocation 3.5.1 Beteiligte Instanzen • Klientenklasse als Aufrufer: - Naming.Lookup() Æ Dienst finden, - MyCall.Invoke(). Codebase Interface • Interface Spezifikation für: - Server Stub im Klienten, - Server-Skeleton*), - Serverklasse. RMI-Registry • RMI Namensdienst: - Naming.bind(..) durch Server, - Klient fragt nach Server. • Codebasis für Klienten: - Liefert den Server-Stub, - Evtl. dynamisch laden. • Bemerkungen: Klient Skelett *) Server-Stub - nur Methoden über Interface ansprechbar, - keine andere Methoden und keine Instanzvariablen. 51 Server *) entfällt ab jdk 1.2 generische Skeletons vorhanden Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner 3.5.2 Compilationsprozess • Interface Spezifikation für Klienten & Server. • Übersetzungsreihenfolge: Interface.java - Interface "Klasse" zuerst, - dann Server & Klienten, • "rmic" für RMI-Compiler. • RMI-Compiler erzeugt: Javac Klient.java - Stub für Klienten, - Skeleton für Server, - Parameter "-v1.2" Æ kein Skelett erzeugen. Interface.class Javac Server.java Javac Klient.class Server.class rmic Server_Stub.class Server_Skel.class (nur jdk <1.2) Java 52 Java Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner 3.5.3 Ausführung • Namensdienst starten - start rmiregistry.exe: - hört normalerweise auf Port 1099. • Server starten (evtl. weitere Maschine). - Property "policy" setzen, sonst keine Verbindung, - Optional "Codebase", falls Stubklassen über das Netz geladen werden sollen java -Djava.security.policy= - -Djava.rmi.server.codebase=http://cb/stublib Instanz der Serverklasse wird erzeugt, Security-Manager im Server installieren, Serverinstanz registriert sich namentlich, Anschließend wird auf Klientenaufrufe gewartet. c:\rmi.policy grant { permission java.net.SocketPermission "134.60.77.91:1024-65535", "connect,accept"; permission java.net.SocketPermission "*:80", "connect"; }; • Klienten starten (evtl. dritte Maschine). - Stub für das Remote Interface wird erzeugt, - Interface-Methoden werden lokal im Stub gerufen, - Stub serialisiert die lokalen Aufrufe fürs Netz. 53 Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner 3.5.4 Beispiel • Interface-Spezifikation: import java.rmi.*; public interface Intface extends Remote { public String TellTime() throws RemoteException; } • Klienten-Klasse: import Intface; import java.rmi.*; import java.util.*; public class Client { public static void main(String[] s) { String serverTime; String url = new String( "//192.168.1.104/TimeServer"); System.out.println( "Client starting" ); try { Intface iface = (Intface ) Naming.lookup( url ); serverTime = iface.TellTime() ; System.out.println( "Received: "+serverTime ); } catch (Exception e) { System.out.println( "Client exception: " + e.getMessage() ); } } } 54 Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner • Server-Klasse: import Intface; import java.rmi.*; import java.rmi. server.*; public class Server extends UnicastRemoteObject implements Intface { public Server () throws RemoteException { } } 55 } public String TellTime( ) throws RemoteException { String now =( new Date() ).toString(); System.out.println( "request served at: "+now ); return now ; } public static void main(String args[]) { System.setSecurityManager( new RMISecurityManager() ); System.out.println( "Server starting"); try { Server srvr = new Server(); Naming.rebind("//192.168.1.104/TimeServer", srvr ); System.out.println( "Server bound in registry"); } catch (Exception re) { System.out.println("TimeServer err: " + re.getMessage() ); } Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner Ausgabe: • Maschine #0: DOS-Box für Compilierung und Registry: Microsoft(R) Windows NT(TM) (C) Copyright 1985-1996 Microsoft Corp. D:\>path PATH=D:\WINNT\...;d:\jdk\bin\;d:\jdk\ D:\>cd jdk D:\jdk>javac Intface.java D:\jdk>javac Server.java D:\jdk>javac Client.java D:\jdk>rmic Server D:\jdk>rmiregistry no security properties. using defaults. • Server-Fenster (DOS-Box, evtl. Maschine 1): D:\jdk> java –djava.sec...policy=... -Djava.rmi.server.codebase=file:/d:\jdk/ Server Server starting Server bound in registry request served at: Thu Nov 25 21:38:54 2004 • Klienten-Fenster (DOS-Box, Maschine 2): D:\jdk>java Client Client starting Received: Thu Nov 25 21:38:54 CEST 2004 56 Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner 3.5.5 RMI-Kommunikationsströme • Übertragung von Parametern und Funktionsresultat: - stützt sich auf die Streams-Klassen, - in serialisierter Form • Separater ObjectStream für jede Richtung. • Klient ruft Methode im Stub. • Die Methode erstellt ein Call-Objekt mit: - Referenz auf den Server, - Signatur der Methode, - Schlüsselwert/Hash ... • Dispatcher ruft die Methode im Server. 57 Klient Server method1 Server-Stub Skelett * method1 Dispatch write read read write Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner Parameter der Methoden • Keine Änderung der Byte-Ordnung, da RMI nur zwischen JavaVM. • Lokale serialisierbare Objekte werden "flachgeklopft" und übertragen. • Parameter und Return-Werte müssen das Interface "serializable" implementieren, damit sie transportiert werden können. • Remote Objekte werden als Remote-Referenz (Ifc.-Ptr.) übertragen: - Im Server werden dann Stub-Referenzen in echte Referenzen übersetzt. - Klienten besitzen nur Referenzen auf Stubs und auf Server, - zu jedem benützten Remote Object gibt es einen Stub, • Serialisieren, Kopieren und Übertragen umfangreicher Datenstrukturen kann teuer werden (Hüllenbildung): 58 Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner Serialisierung von Parametern • Serialisierung / Deserialisierung: - in einem Bytestrom (Netz oder Disk), - sinnvoll für RMI Parameterübergabe, - allgemein zum Abspeichern von Objekten, • Interface Serializable markiert Klassen, welche in ein "streamfähiges" Format überführt werden können: - Integer, Boolean, Real, Strings ... - Ein- und mehrdimensionale Arrays, - Weitere explizit serialisierbare Objekte. • Für nicht serialisierbare Objekte sind eventuell explizite Methoden zu schreiben, die unserialisierbare Felder besonders berücksichtigen: import java.io.*; … private void writeObject(ObjectOutputStream stream) throws IOException … private Object readObject(ObjectInputStream s) throws IOException, ClassNotFoundExcep .. 59 Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner Beispiel PrintObj - zum Serialisieren in den Printstream • Das zu serialisierende Objekt sei ein Objekt der Klasse CnvrtMe: import java.io.*; public class CnvrtMe implements Serializable { int num4711 = 4711; String gr = "Hallo!"; } • "writeObject" schreibt Klassenobjekt in einen ObjectOutputStream: import java.io.*; public class PrintObj { static public void main( String[ ] args ) { CnvrtMe cvObj=new CnvrtMe(); ObjectOutputStream oos; try{ oos= new ObjectOutputStream( System.out ); oos.writeObject( cvObj ); } catch (Exception e) { }; } 60 Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner • Erzeugter Output Text entspricht dem serialisierten Objekt cvObj: - Eigentlich als binäres Format geschrieben, Teilweise als ASCII-Zeichen erkennbar, Klassenname CnvrtMe, Integer num4711, Aktueller Wert, Referenztyp, Zeichenkette. ¼Ý sr CnvrtMeB ·+liqY Ljava/lang/String;xp I num4711L gt Hallo! grt • Lesen eines Objektes von einem ObjectInputStream: ObjectInputStream ois = new ObjectInputStream (yStream); Object obj = ois.readObject(); 61 Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner 3.6 DSM • Multiprozessor: mehrere CPUs teilen sich gemeinsamen Speicher. • Multicomputer: mehrere Rechner mit privatem Speicher vernetzt. • Verteilter Gemeinsamer Speicher (Distributed Shared Memory): Æ Illusion eines gemeinsamen cpu cpu Speichers für Multicomputer #1 #2 • Datenzugriff ohne Replikation => - schneller Zugriff im lokalen Speicher, - langsamer Zugriff im fremden Speicher, - ohne Synchronisierung nicht deterministisch. Speicher #1 Speicher #2 • Datenzugriff mit Replikation: - z.B. auf alle Kopien schreiben & v. lokaler Kopie lesen, vermeidet häufige Lesezugriffe über das Netz, Lesequorum und Schreibquorum verwenden, evtl. Update- oder Invalidate Protokoll => Abwägen zw. Latenz & Konsistenz • Unterschiedliche Konsistenzmodelle (siehe später in Vorlesung). 62 cpu #1 Speicher #1 cpu #2 update/ invalidate Speicher #2 Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner 3.6.1 Verteilte Speicherseiten • Speicher als „amorphe“ und lineare Folge von 4, 8, 16 KByte Seiten. • Implementierung des verteilten Zugriffs: - expliziter Aufruf von R/W-Laufzeitroutinen, explizite Anforderung von Speicherseiten, Compiler fügt die Laufzeitroutinen ein, Abfangen ungültiger Zeigerzugriffe, Paging mit MMU Unterstützung, mit oder ohne Replikation. • Alternative Ausführungsmodelle: * + < - Speicher wandert zum Operationsort, - Operation wandert zum Speicherort. • Auffinden der Seiten: - feste Zuordnung zu einer bestimmten Station, - Anfordern bei einem Verzeichnisdienst, - Anfordern per Rundspruch im LAN. 63 Node i Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner Ablauf entfernte Seitenanfrage: • Zugriff auf Seite 5 Æ nicht präsent Æ Page Fault Knoten-1 VA Seitentab. 0 2 1 1 1 1 2 0 3 5 0 5 0 6 0 7 0 3 log. Adr. 64 1 4 8 Knoten-2 1 phys. P-Bit Adr. Seitentab. 0 RAM 0 0 1 1 2 0 3 8 4 5 3 3 1 5 0 0 1 2 1 5 1 4 1 RAM 0 4 1 2 5 3 2 4 7 5 6 0 phys. P-Bit Adr. Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner • Knoten 1 frägt Seite 5 im Netz an (z.B. per Broadcast). • Knoten 2 trägt Seite aus und schickt sie an Knoten 1. Knoten-1 VA Seitentab. 0 2 1 1 1 1 2 0 3 5 0 5 0 6 0 7 0 3 log. Adr. 65 1 4 8 Knoten-2 1 phys. P-Bit Adr. Seitentab. 0 RAM 0 0 1 1 2 0 3 8 4 5 3 3 1 5 0 0 1 0 5 1 4 1 RAM 0 4 1 2 5 3 2 4 7 5 6 0 phys. P-Bit Adr. Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner • Seiten wird auf Knoten 1 eingetragen (in Kachel 4). • Knoten 2 gibt die entsprechende Kachel frei. Knoten-1 VA Seitentab. 0 2 1 1 1 1 2 0 3 5 4 4 1 6 0 7 0 8 3 log. Adr. 66 1 0 5 Knoten-2 1 phys. P-Bit Adr. Seitentab. 0 RAM 0 0 1 1 2 0 3 8 4 5 5 3 3 1 0 0 1 0 5 1 4 1 RAM 0 4 1 2 3 2 4 7 5 6 0 phys. P-Bit Adr. Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner False Sharing: • Grundphänomen in seitenbasierten DSM-Systemen: - Zwei Objekte liegen auf derselben Speicherseite, Zugriffe erfolgen von verschiedenen Knoten, mind. ein Knoten schreibt auf die Seite, Seite wird unnötig oft transportiert, zeitlich abhängiges Phänomen. • Lösungen: - Objekte geschickt allozieren (User oder Compiler), Instanzen dynamisch relozieren (Plurix) Æ abgeschwächte Konsistenzmodelle, andere Sharing Granularität. • True Sharing: - zwei oder mehr Objekte liegen auf einer Seite, - Objekte werden von einem Knoten nacheinander verwendet, - Caching-Effekt: erster Zugriff auf Seite evt. entfernt, aber nach- folgende Zugriffe auf die gleiche Seite laufen mit voller Geschwindigkeit ab. 67 Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner 3.6.2 Verteilte Variablen • Sind zum Beispiel in einem verteilten Speicher untergebracht. • Programmierung: - ähnlich wie bei lokaler Nebenläufigkeit, - kritische Regionen, Semaphore und dgl., - Update zum Synchronisierungzeitpunkt. Node 1 • Attribute für die einzelnen Variablen: - Release local, read-only, shared, synchronized, migrierend, gemeinsam schreibbar, Compiler berücksichtigt Attribute, Evtl. pro Variable unterschiedlich. Release • Kleinere Speichergranularität: - t Acquire als bei Verteilung ganzer Objekte, als bei seitenweiser Verteilung, vermeidet false sharing, aber kein true sharing. Node 2 • Beispielsweise Release-Konsistenz in Munin: - J.B. Carter, J.K. Bennett, and W. Zwaenepoel: "Implementation and performance of Munin", In Proc. of the 13th ACM Symposium on Operating Systems Principles, p.152-164, Oct. 1991. 68 Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner 3.6.3 Verteilte Objekte • Objekt: + + + Instanz als Abbild eines Gegenstandes => mit einer Anzahl Eigenschaften, mit einer Anzahl Methoden, Vererbung, Polymorphie. • Verteilungsstrategien: - einzelne Objekte unterschiedlichen Maschinen zuordnen, einzelne Fragmente der Objekte im Netz verteilen, Objekte auf virtuellen Speicher abbilden, statische und dynamische Verteilung. • Zugriffsstrategien: - Objekte im Netz migrieren lassen, Objektmethoden aufrufen, Aufrufe auch übers Netz, serialisierte Parameter ... • Beispielsweise Orca: Nachrichten, bzw. Methodenaufrufe - Bal, H.E., Bhoedjang, R., Hofman, R., Jacobs, C., Langendoen, K., Ruhl, T., and Kaashoek, M.F, “Performance Evaluation of the Orca Shared Object System”, ACM Transactions on Computer Systems, Vol. 16, No. 1, Febr. 1998. 69 Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner 3.6.4 Tupel Spaces • Tuple Space gemeinsam nutzen, anstatt eines Adressraumes. - Gelernter, D., „Generative Communication in Linda“, ACM Computing Surveys, 7(1), 1985. • Operationen auf die Linda-Tupel: - Write( w1, w2, ... ) fügt Tupel ein, Read( m1, m2 … ) assoziatives Matching, Take( m1, m2 … ) Tupel herausnehmen. Bem.: Tupel nicht änderbar. • Assoziative Adressierung: - nur ganze Tupel (keine Einzelelemente), Tupel mit der richtigen Anzahl Elemente, passender Typ an der richtigen Position, passender Wert oder * . Bem.: passen mehrere Tupel, wird eines zufällig gewählt. • Weitere Anwendungsbereiche: - JavaSpaces (Teil von Jini): http://java.sun.com/products/javaspaces. - Tuple Spaces auch in Sensornetzwerken. 70 Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner 3.7 Message Passing vs. Shared Memory • Nachrichtenbasierte Kommunikation: - Serialisierung und Deserialisierung von Objekten, gekapselt in komfortable Middleware, z.B. Corba, .NET, mit umfangreichen sprachunabhängigen Laufzeitumgebungen, aber Konsistenz & Fehlertoleranz von Objektmengen ist Bürde des Programmierers, bei korrekter und optimaler Programmierung ist die maximale Nebenläufigkeit erzielbar. • Verteilter Virtueller Speicher: - vereinfachte implizite Kommunikation, Serialisierung von Objekten entfällt meist, keine Hüllenbildung für Referenzen notwendig, Objekte werden beim Zugriff auto. angefordert, Konsistenz wird für alle Objekte im DSM garantiert, inhärente Replikation ist gute Basis für Fehlertoleranz, i.d.R. etwas langsamer als Message Passing, aber komfortabler, allgemein nützlich z.B. für Multiplayer Spiele, nicht nur für Number Crunching. • Verbreitung im Bereich der parallelen Anwendungen: - MPI (Message Passing Interface) – Standard für message passing; am weitesten verbreitet, - PVM (Parallel Virtual Machine) – ähnlich JVM, aber verteilt mit message passing, - OpenMP (Open Multi Processing) – Standard für shared memory Anwendungen. 71 Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner 3.8 Zusammenfassung • Sockets: - TCP: verbindungsorientiert, garantierte Nachrichtenauslieferung und Paketsequenz, - UDP: verbindungslos, keine Garantien für Sequenz und Zustellung. • Multicast: effizient, falls durch HW unterstützt (z.B. Ethernet) • RPC: - entfernter Prozeduraufruf für heterogene Umgebungen, - Schnittstelle per IDL definieren (verschiedene Attribute), - Hüllenbildung für Zeigerparameter (unterschiedliche Typen). • RMI: - entfernter Java Methodenaufruf für exportierte entfernte Instanzen, Zugriff nur über Interfacepointer („Interface extends Remote“), nur serialisierbare Parameter erlaubt, Hüllenbildung für Zeigerparam. • DSM: - 72 auf Basis von Seiten (False Sharing), Variablen, Objekten und Tupeln, einfacher Datenaustausch auch komplexer Objektstrukturen, keine Hüllenbildung für Zeiger notwendig, zusätzliche Signalisierung für Interaktion. Verteilte Betriebssysteme, Winter 2005 © Verteilet Systeme, Universität Ulm, M. Schöttner