Folien hier

Werbung
Effizientere Serialisierung
und RMI für Java
Seminar Verteilte Systeme WS 05/06
Prof. Dr.-Ing. Klaus-Peter Löhr
Referent: Magnus Konze
RMI - Wiederholung
Aufrufer
Aufgerufener
Vertreter
Treiber
Referenzschicht
Transportschicht
Übersicht
•
•
•
•
•
Motivation
Optimierung der Serialisierung
KaRMI
Benchmarks und Ergebnisse
verwandte Arbeiten
Motivation
• wachsender Einsatz von Java bei
Hochleistungsanwendungen
• Java bietet brauchbare Mechanismen für
internetweite Kommunikation
• Javas RMI-Implementierung sehr langsam
Vergleich
Wo lässt sich RMI optimieren?
Anforderungen
schnelle Serialisierung
Prozess-/Threadpool
schneller Prozesswechsel
aktives Warten
verbindungsloses Protokoll
spezielle Kommunikationshardware
direkter Speicherzugriff
angepasste Speicherbereinigung
RMI
nein
nein(?)
?
nein
an TCP/IP gebunden
umständlich
nicht möglich
nicht austauschbar
Kostenanalyse
Optimierung der Serialisierung
Grundlagen
• Serialisierung mittels dynamischer
Typintrospektion (Reflektion)
• Programmierer kann Methoden schreiben,
die spezifischer arbeiten
Bewertung
• JDK-Serialisierung ist ein „nettes“ Feature
• schneller geht es mit eigenen Methoden und
der UKA-Serialisierung
Kodierung von Typinformationen
• JDK-Serialisierung fügt dem Bytefeld eine
komplette Typbeschreibung hinzu
• nicht notwenig in Rechnerverbund, da
angenommen werden darf, dass alle auf den
gleichen Bytecode Zugriff haben
• UKA-Serialisierung sendet nur Klassenund Paketnamen
Ersparnis
Zwei Reset Arten
• Zyklen im Objektgraphen werden mit Hilfe
einer Hashtabelle gesucht
• diese wird bei jedem Fernaufruf neu
angelegt oder alternativ zurückgesetzt
• UKA-Serialisierung bietet neue
Resetmethode, die die Hashtabelle löscht,
aber sich die Typinformationen merkt
Ersparnis
Bessere Pufferung I
• JDK-Serialisierung enthält auf Empfängerseite keine eigene Puffer-Strategie
• Wissen über Puffergröße kann nicht genutzt
werden
• UKA-Serialisierung hat eigenen Puffer, im
Optimalfall kann er in einem Schritt gelesen
Ersparnis
Bessere Pufferung II
• Programmierer kann bei JDK-Serialisierung
nicht direkt auf den Puffer zugreifen
• in UKA-Serialisierung möglich, da Puffer
Teil der Serialisierung
Ersparnis
Reflektion erweitern
• JNI sollte Methoden bereitstellen, mit denen
primitive Instanzvariablen direkt in einen
Puffer geschrieben oder aus einem Puffer
gelesen werden können
• diese könnten zum Beispiel über die Klasse
Class zugänglich sein
Floats und Doubles
• Floats und Doubles treten häufig in
wissenschaftlichen Anwendungen auf und
sollten daher effizient serialisiert werden
können
• native Methoden wandeln diese vorher in
maschinenunabhängige Byterepräsentationen um
Floats und Doubles
• weiterhin wird dieser Schritt bei Feldern für
jedes Element einzeln gemacht
• sollte mit JIT-Compiler inline gemacht
werden
Testergebnisse
Testergebnisse
Design
• UKA-Serialisierung setzt selbstgeschriebene Serialisierungsmethoden
voraus
• für „herkömmliche“ Objekte muss die JDKSerialisierung verfügbar bleiben
Ansatz 1
• JDK-Serialisierung kopieren
• Kopie bearbeiten
• per CLASSPATH Variable gewünschte
Implementierung auswählen
• Nachteil: aufwendige Änderungen bei
jedem JDK Update
Ansatz 2
• UKA-Serialisierung Unterklasse der JDKSerialisierung
• Nachteil: bestehender Code muss geändert
werden (speziell Unterklassen der JDK-S.)
• Security Manager muss konfiguriert werden
• Bemerkung: sogar Klassen, deren
Quellcode nicht vorliegt, können angepasst
werden
Problem bei Ansatz 2
• JDK-Serialisierung kann nicht gleichzeitig mit
neuer Serialisierung benutzt werden
protected ObjectOutputStream() {
[...]
// Abfrage des Security Managers
enableOverride=true;
}
public final void writeObject(Object obj) {
if (enableOverride)
writeObjectOverride(obj)
[...]
}
protected void writeObjectOverride() {...}
Ansatz 3
• Problem von Ansatz 2 mit Delegation lösen
neue Probleme:
• aufwändig
• funktioniert nicht in allen Fällen
Ansatz 4
Änderungen an der JDK-Implementierung:
• ObjectOutputStream bekommt
Initialisierungsmethode
• Flag enableSubclassImplementation wird
protected (vorher private)
• writeObject nicht mehr final
Ergebnisse
KaRMI
KaRMI
• KaRMI ist eine neu entworfene
Implementierung von RMI
• Ziel war ein schlankeres und schnelleres
Framework
Saubere Schnittstellen
• wie bei RMI drei Schichten
(Vertreter/Treiber, Referenz, Transport)
• Fernaufruf in KaRMI benötigt nur zwei
Methodenaufrufe zwischen Schichten (>30
in RMI)
• andere Referenz- und
Transportimplementierungen können leicht
genutzt werden
Saubere Schnittstellen
• Sockets in RMI auf Anwendungsebene
• daher muss Socketsemantik auch auf
Transportebene genutzt werden (also auch
z.B. für nicht-TCP/IP Netzwerke)
=> in KaRMI Sockets vom RMI-Design
getrennt
KaRMI Entwurf
Performanz Verbesserung
• RMI nutzt Hashtabellen, obwohl Felder
effizienter wären
• viele temporäre Objekte in RMI
• KaRMIs Referenzschicht erkennt, wenn ein
Objekt lokal ist
• RMI Code enthält Debugcode (kann
umgangen werden => Flags müssen geprüft
werden)
Technologie Objekte
• KaRMI kann über nicht-TCP/IP Netzwerke
kommunizieren
• dafür wurde ein Technologie-Objekt
eingeführt
• für jede verfügbare Technologie ein Objekt,
das Beste wird genutzt
austauschbare
Speicherbereinigung
• Verteilte Speicherbereinigung ist
kompliziert (verlorene, doppelte, verspätete
Nachrichten, Knotenabstürze...)
• kein perfekter Algorithmus bekannt
• in KaRMI kann eine der Umgebung
angepasste Speicherbereinigung eingesetzt
werden
Einschränkungen
um alten Code zu nutzen, muss man:
• BOOTCLASSPATH-Variable anpassen
• Vertreter neu erstellen
• Treiber neu erstellen
Einschränkungen
•
•
•
•
KaRMI kann nicht genutzt werden, wenn:
alter Code die Socketfactory benutzt
alter Code undokumentierte RMI Klassen
nutzt
Inkompatibilitäten:
Vertreter und Referenzobjekte erben nicht
mehr von Remoteobject
nur eine RMI-Registrierung pro JVM
Benchmarks und Ergebnisse
Parastation
• Technologie, die mehrere Standardrechner
zu einem Rechner verbindet
• Performanzgewinn durch Umgehung des
Betriebssystems
Benchmarks
• ping (2 Rechner)
• konkurrierende Aufrufe (1 Server, mehrere
Clients)
• Anwendungen (Hamming Problem,
Erzeugung von Paraffin-Strukturformeln,
Lösen von Laplace Differentialgleichungen
auf einem 2D-Gitter)
Konfigurationen
•
•
•
•
4 Software Konfigurationen:
normales RMI
RMI mit UKA-Serialisierung
KaRMI mit normaler Serialisierung
KaRMI mit UKA-Serialisierung
Konfigurationen
3 Hardware Konfigurationen
• zwei 350 MHz Pentium 2, Windows NT 4.0,
Ethernet, Java 1.2
• 8er Bündel von 500 MHz Alphas,
FastEthernet
• 8er Bündel von 500 MHz Alphas,
Parastation
Bandbreite
Zeitersparnis
Zeitersparnis bei Feldern
Verwandte Arbeiten
Verwandte Arbeiten
• explizite Versendemethoden
• Compilerprojekt „Manta“: kompiliert Teil
des Javacode in nativen Code
• Java/DSM nutzt verteilten Speicher statt
Fernaufrufe
• direkter Zugriff auf Hardware
Verwandte Arbeiten
• Cache für fernaufrufbare Objekte
• alternative Technologie (Horb, Voyager)
Quellen
•
•
•
•
•
•
Philippsen, Haumacher, Nester: More Efficient Serialization and RMI
for Java
Christian Nester: Eine flexibles RMI Design für eine effiziente Cluster
Computer Implementierung
Java Object Serialization Specification
Friedrich Esser: Java 2
www.jacorb.org
www.wikipedia.de
Herunterladen