codecentric

Wer anderen eine Nachricht schickt …

Herausgeber: Java Magazin

Ausgabe: April 2009

Autor: Mirko Novakovic

Sehr häufig bleiben Details, wie Daten erzeugt und übertragen werden, im Verborgenen. Ein wesenticher Grund ist hier, dass sich der Anwendungsentwickler um diese Teile keine Gedanken machen muss, da ihm diese Aufgabe von Remoting-Frameworks abgenommen wird. Da Serialisierung aber einer der Hauptbestandteile einer verteilten Anwendung ist, sollen die Serialisierungskonzepte in diesem Artikel detailliert betrachtet werden.

Lesen Sie nun den kompletten Artikel oder laden Sie sich die kostenlose Ausgabe als Download herunter.

Im letzten Artikel haben wir uns mit architekturellen Anti- Patterns in verteilten Systemen auseinandergesetzt. Der Fokus lag dabei auf Problemen wie dem Senden von großen Datenmengen oder ineffizienter Kommunikationsmuster. Serialisierung im Zuge von Remote-Aufrufen wurde dabei bereits als Problemquelle gestreift. Neben dem Schnittstellendesign und der Kommunikationslogik ist die Serialisierung der dritte wesentliche Bestandteil einer verteilten Anwendung, der zu Performance- und Skalierbarkeitsproblemen führen kann. Sehr oft bleibt dem Entwickler allerdings verborgen, was auf der Serialisierungsebene passiert. Serialisierung im Detail Als Erstes gilt es zu verstehen, wie sich Serialisierung auf die Performance einer Anwendung auswirkt. Dazu ist es hilfreich zu verstehen, was bei verteilter Kommunikation im Detail passiert.

Serialisierung im Detail

Als Erstes gilt es zu verstehen, wie sich Serialisierung auf die Performance einer Anwendung auswirkt. Dazu ist es hilfreich zu verstehen, was bei verteilter Kommunikation im Detail passiert.
In der nachfolgenden Grafik sehen wir den abstrahierten Ablauf eines Client-Server-Aufrufs eines Remoting-Frameworks.

Abb. 1: Logischer Ablauf der Serialisierung in verteilten Anwendungen

Neben der eigentlichen Datenübertragung nimmt die Umwandlung der Objekte in das Transportformat einen wesentlichen Teil der Laufzeit in Anspruch. Aus diesem Verhalten können wir die wesentlichen Performancemetriken ableiten (Abb. 1).

Die Serialisierung selbst wirkt sich im Wesentlichen auf den CPU- und Speicherverbrauch der Anwendung aus. Je größer die Datenmenge und je komplexer die zu serialiserenden Datenstrukturen, desto höher die CPUAuslastung und je nach verwendeter Serialisierungstechnologie auch die Speicherbelastung. Durch die oft auch mehrfache Umwandlung der Daten wird eine sehr hohe Anzahl von (temporären) Objekten erzeugt, die sehr kurzfristig benötigt werden. Dieses Verhalten wird auch als „Object Churning“ bezeichnet und führt mitunter zu hoher Aktivität des Garbage Collectors, vor allem wenn bei Generationen-Heaps die Young Generation zu klein ist, um die temporären Daten der Serialisierung zu verarbeiten. Neben den temporären Objekten ist es aber auch entscheidend, ob die serialisierten Objekte direkt auf die Leitung, also z. B. direkt auf einen OutputStream geschrieben werden oder die Serialisierung im Speicher vorgehalten wird. Letzteres kann bei sehr großen Objekten oder hoher Last schnell zu Schwierigkeiten bis hin zu einem OutOfMemoryError führen. Es ist daher unbedingt notwendig, die Funktionsweise der Serialisierung bei einer verwendeten Remote-Technologie zu verstehen. Neben CPU und Speicher legt die Serialisierungstechnologie aber auch die übertragene Datenmenge fest, die ausschlaggebend für die Netzwerkbelastung ist. Je nach Bandbreite, Datenmenge und Last kann es auch hier schnell zu Engpässen kommen, die Performance und Skalierbarkeit einer Anwendung einschränken.

Formate, Formate, Formate

Alleine die Wahl einer Technologie legt aber noch nicht automatisch fest, welches Übertragungsformat gewählt wird und wie die Serialisierung erfolgt. Bei Übertragungsformaten kommt es darauf an, wie viel Overhead ein Protokoll generiert und wie die tatsächlich übertragenen Daten repräsentiert werden. Anhand eines kleinen Beispiels wollen wir uns ansehen, welche Auswirkungen die Wahl des Übertragungsformats auf die Datenmenge hat. Wir übertragen dazu einen Personendatensatz einmal mittels RMI und einmal über einen SOAP Web Service. Da SOAP XML als Übertragungsformat verwendet, werden die Daten und die Struktur der Nachricht in textueller Form übertragen. Im Vergleich dazu überträgt RMI die Daten rein binär und nimmt wesentliche Optimierungen vor, die speziell bei größeren Datenmengen ausschlaggebend für eine bessere Performance sein können.

Abb. 2: Vergliech Transportdaten zwischen einem RMI und einem SOAP Web Service

In Abbildung 2 sind die via RMI und SOAP übertragenen Daten gegenübergestellt. Keine Angst, sollten Sie die RMI-Nutzdaten nicht lesen können – das brauchen Sie auch nicht. Es geht bei dem Beispiel nur um den Vergleich der Datenmengen.

RMI wurde hier nur als Beispiel für ein binäres Protokoll genommen. Im Java- Umfeld gibt es weitere Alternativen, z. B. Hessian [2]. Aber selbst wenn man sich für eine Remoting-Technologie entschieden hat, steht man oft noch vor der Wahl bezüglich des Datenformats. So erlaubt RMI z. B. das Verwenden von zwei Übertragungsprotokollen. JRMP basiert auf Java-Serialisierung, GIOP – das Protokoll von CORBA – wird für RMI over IIOP verwendet. Viele Application- Server-Hersteller bieten zudem eigene optimierte Protokolle an.

XML oder binär

Eine wesentliche Entscheidung in der Entwicklung verteilter Anwendung ist die Wahl des Übertragungsformats. Als Entwickler steht man heute meistens vor der Entscheidung, ob man XML oder ein binäres Format verwenden soll. Diese Entscheidung wird sehr stark vom Einsatzszenrio beeinflusst. Wird in heterogenen Systemen kommuniziert, so muss man zwansgweise ein technologieneutrales Format wählen. Hier kommt dann meist XML zum Einsatz, wobei auch GIOP oder Hessian von unterschiedlichsten Programmiersprachen unterstützt wird – oftmals aber zu Lasten der eingesetzten Datentypen. Handelt es sich allerdings um Kommunikation zwischen zwei Java-Anwendungen, sind binäre Übertragungsprotokolle zu bevorzugen, die dem Java-Serialisierungsmechanismus folgen. Nutzt man SOAP oder natives XML als Austauschformat, so ist in der Regel die Datenmenge größer und der Serialsierungsmechanismus aufwändiger. Dafür sind die Daten aber gerade bei WS-I-konformer SOAP-Kommunikation sehr interoperabel.

Serialisierung als Performancekiller

Bei jeder eingesetzten Technologie müssen die Daten der zu übertragenden Java-Objekte auf der Senderseite in das entsprechende Protokoll der Remoting- Technologie serialisiert und durch den Empfänger deserialisiert werden. Gerade hier werden oft wertvolle Zeit und Ressourcen verbraucht. Die gängigste Form der Serialisierung von Java- Objekten ist der integrierte Serialisierungsmechanismus [3] von Java auf Basis des java.io-Pakets. Klassen, die das Interface java.io.Serializable implementieren, werden mithilfe des java. io.ObjectOutputStream serialisiert und direkt in einen OutputStream umgeleitet, der die Daten beispielsweise direkt auf das Netzwerk schreiben kann. Der ObjectOutputStream gilt trotz einiger Performanceverbesserungen in den letzten Java-Releases nicht als besonders performant. JBoss hat beispielsweise mit dem Projekt JBoss Serialization [4] eine optimierte Variante des ObjectOutputStreams entwickelt, den org.jboss.serial.io. JBossObjectOutput- Stream, der nach Angaben von JBoss mindestens zwei mal schneller ist als die Java-eigene Implementierung. Bei Klassen, die java.io.Serialization nutzen, kann zudem der Mechanismus, die Daten der Klasse zu serialisieren, nur generisch implementiert werden, was immer gewisse Performancenachteile mit sich bringt. Java bietet dafür die Möglichkeit an, die Serialisierung einer Klasse selbst zu implementieren – hierfür muss die Klasse das Interface java. io. Externalizable implementieren. Das Interface enthält zwei Methoden zum Schreiben und Lesen des Objekts – so erhält man die Möglichkeit, den Mechanismus selbst zu steuern und gegebenenfalls nur die benötigten Daten effizient zu schreiben.

Beim Serialisieren von XML-Daten wird es deutlich komplizierter und es gibt Unmengen von Möglichkeiten und Implementierungen, Java-Objekte in XML zu serialisieren. JAXB (Java Architecture for XML Binding) ist ein offizieller Standard (JSR-222) der Java- Plattform für die Serialisierung von Java-Objekten in XML, mit einer Referenzimplementierung [5] von Sun. XStream [6] und Castor [7] sind zwei weitere Open-Source-Alternativen, mit einer sehr einfachen API. XStream bietet zudem die Möglichkeit, die Daten auch als JSON [8] zu serialisieren, was die Datenmenge erheblich reduziert. Die Performance hängt dabei vor allem von der Implementierung des XML-Serialisierungsmechanismus und dem eingesetzten XML-Parsers ab. Je nach SOAP-Implementierung kann man den Mechanismus wählen oder konfigurieren, bei dokumentbasierten SOAP-Aufrufen [1] liegt die Serialisierung der Daten sowieso in der Hand des Entwicklers. Gerade bei hoher Last und großen Datenmengen bietet sich aber auch hier eine eigene Implementierung des Serialisierungsmechanismus nach XML an – dafür müssen die Objekte entsprechende Methoden zum Schreiben und Lesen des Objekts nach und von XML anbieten und implementieren. Um den Aufwand der Implementierung solcher Methoden für alle relevanten Objekte zu reduzieren (das gilt für binäre und XML-basierte Implementierungen), empfiehlt es sich, die Methoden mit einem Generator zu erzeugen – dadurch werden auch Probleme vermieden, die durch händische Implementierung der Serialisierung durch unterschiedliche Entwicker entstehen können.

Abb. 3: Vergleich eines optimierten und nicht optimierten RMI-Aufrufs

 Ich schreibe dir einen langen Brief …

… denn für einen kurzen hatte ich keine Zeit. Dieser Spruch von Goethe lässt sich auch auf die Implentierung von Custom-Serialisierung anwenden. Der Vorteil moderner Remoting-Frameworks ist, dass man sich um die Datenserialisierung nicht kümmern muss, da dies schon von den diversen Implementierungen abgenommen wird. Dies ist sehr wartungsarm und – sofern ein entsprechendes Framework gewählt wurde – auch wenig fehleranfällig. Will man allerdings optimale Performance erreichen, stellt sich die Frage, ob man nicht doch zur eigenen Implementierung greift – Beispiele hierfür wurden ja bereits im vorangegangenen Kapitel gegeben. Bei einer Eigenimplementierung hat man volle Kontrolle über den gesamten Serialisierungsprozess und kann hier teilweise signifikante Performanceoptimierungen vornehmen. In Abbildung 3 wird die Datenmenge einer Standard-RMI-Serialisierung mit einer Custom-Serialisierung verglichen.

Diesen Performancegewinn erhält man allerdings nicht umsonst. Man erkauft ihn sich mit wesentlich höherem Implementierungs- und – was vielleicht noch entscheidender ist – Testaufwand. Es ist hierbei also wirklich im Einzelfall zu prüfen, wo sich dieser Aufwand tatsächlich lohnt.

Alternative: Hardwareserialisierung

Neben den beschriebenen Technologien und der Möglichkeit, die Serialisierung angepasst an die Bedürfnisse der Anwendung zu optimieren, gibt es heute aber noch eine andere, sehr interessante Möglichkeit der Optimierung von Serialisierung: Man verlagert diesen Prozess an eine speziell dafür optimierte Hardware. Mit Layer7 [8] und IBM WebSphere DataPower [9] sind den Autoren zwei Appliances bekannt, die die Serialisierung von XML-Daten mit extremer Performance und Skalierbarkeit unterstützen. Diese Lösungen sind vor allem dann sehr leistungsfähig, wenn die XML-Daten transformiert werden müssen und die Daten sehr groß sind. In einigen Beispielen aus der Praxis konnten mit dieser Lösung Hardwarekosten gespart und die Performance und Skalierbarkeit der Anwendung signifikant verbessert werden.

Wann muss man optimieren?

Eine wesentliche Frage, die sich einem Entwickler oder Architekten zwangsweise stellt ist, wann die Serialisierung einer Anwendung optimiert werden soll oder muss. Da dies mit einem erheblichen Mehraufwand verbunden ist, sollte es nicht proaktiv gemacht werden, „um auf Nummer sicher zu gehen“. In den meisten Fällen wird man mit dem, was die Infrastruktur zu bieten hat, eine ausreichende Performance und Skalierbarkeit erreichen. Dennoch gilt es, rechtzeitig den Handlungsbedarf zu erkennen, um Performance- und Skalierungsprobleme rechtzeitig zu vermeiden. Daneben können aber auch die Kosten eine entscheidende Rolle bei der Optimierung der Serialsierung spielen. Auf Plattformen, bei denen Rechenleistung aufgrund der hohen Verfügbarkeit und Zuverlässigkeit teurer sind als bei Mainstream- Hardware, kann die Optimierung der Serialisierung zu erheblichen Kosteneinsparungen führen. Beispielsweise konnte bei einer Java-basierten Anwendung, die auf dem IBM-Mainframe-System z abläuft, nur durch die Optimierung der Remote Pattern und der Serialisierung, eine Einsparung der Hälfte der CPUs erreicht werden, was jährlich enorme Kosten erspart, sodass ein Return on Investment der Tuningmaßnahmen innerhalb eines Jahres möglich war.

Um bereits in der Entwicklung erste Abschätzungen geben zu können, ob die Datenübertragung ein potenzielles Problem darstellt, ist es notwendig, einige Metriken zu sammeln. Abbildung 4 zeigt die Analyse einzelner Transaktionen einer Anwendung in Hinsicht auf CPU-Verbrauch, Antwortzeit und übertragener Datenmenge. Wesentlich hierbei ist, bereits mit realistischen Datenmengen und -größen zu arbeiten. Zusätzlich sollte man bereits über erste – wenn auch grobe – Abschätzungen der Transaktionsvolumen verfügen. Damit lassen sich zwar nur grobe aber immerhin erste Schätzungen über das Remoting-Verhalten der Anwendung abgeben.

Diese Metriken sollten dann auch während der Lasttests gesammelt und ausgewertet werden. Moderne Performance- Management-Lösungen erlauben, diese Daten ohne Einfluss auf den Test auch in Hochlastszenarios zu sammeln.

Abb. 4:  Darstellung der wesentlichen Remoting-Metriken eines Performance-Integrationstests

Fazit

Die Serialisierung von Daten in verteilten Anwendungen kann ein entscheidender Faktor für Performance und Skalierbarkeit sein. Die Auswahl an Technologien für binäre und XMLbasierte Serialisierung in Java ist groß, sodass die Architekten und Entwickler vor der Qual der Wahl stehen. Es ist daher empfehlenswert, schon zu Beginn die Anforderungen an Interoperabilität und Performance abzuwägen und gegebenenfalls eigene Serialisierungsmechanismen zu implementieren, wenn die Anforderungen nicht durch generische Ansätze erfüllt werden können.

Links & Literatur

[1] Hessian: hessian.caucho.com

[2] Java-Serialisierung: java.sun.com/javase/6/docs/technotes/guides/serialization/ index.html

[3] JBoss-Serialisierung: www.jboss.org/serialization/

[4] JAXB-Referenzimplementierung: https://jaxb.dev.java.net

[5] XStream: xstream.codehaus.org

[6] Castor: www.castor.org

[7] JSON: json.org

[8] Layer7: www.layer7tech.com

[9] IBM WebSphere DataPower: www-01.ibm.com/software/integration/datapower/

[10] Blog-Eintrag zum Thema Serialisierung: blog.dynatrace.com/2008/07/01/ optimizing-remoting-by-optimizing-serialization/

codecentric-Performance-Studie 2008

Die Solinger codecentric GmbH, Spezialist für Performanceanalyse und -tuning, hat im April 2008 auf der JAX in Wiesbaden eine Umfrage durchgeführt, um ein aussagekräftiges Meinungsbild über das Thema „Performance im Java-Umfeld“ zu gewinnen.

Ziele der Umfrage

Im Einzelnen ging es um drei Fragenkomplexe:

 

  • Einschätzung der Bedeutung der Thematik Performance
  • Ursachen für Performance- und Stabilitätsprobleme; performancekritische Technologien, Komponenten und Prozesse
  • Einsatz von Performancewerkzeugen in der (Java-)Praxis Teilnehmer

 

Insgesamt gingen 223 Umfragebögen in die Auswertung ein. Wie auf der Java-Konferenz JAX nicht anders zu erwarten, kam die Mehrheit der Teilnehmer der Umfrage – gut 50 % – aus IT-Unternehmen oder zumindest aus Branchen mit hohem IT-Bezug. Einen weiteren Schwerpunkt bildete die Finanzbranche. Über 43 % der Teilnehmer sind als reine Entwickler tätig, weitere 25 % als Architekten.

Bedeutung des Themas

Zwei Dinge machten die Teilnehmer der Umfrage in ihren Antworten sehr klar: Performance ist ein besonders wichtiges Thema, wird aber immer noch unterschätzt. 55 % meinten, dass Performance ein überdurchschnittlich wichtiges oder sogar kritisches Thema ist. Lediglich 2 % sehen es im Vergleich zu anderen Anforderungen als weniger wichtig an. Gleichzeitig denken auch 28 %, dass in ihren Unternehmen Performance noch nicht entsprechend wahrgenommen wird und stärker beachtet werden müsste, während nur 4 % der Ansicht sind, ihr Unternehmen nehme das Thema zu wichtig. Performancekritische Technologien, Komponenten und Problemfelder Im zweiten Teil der Umfrage wurde gefragt, was in der Praxis für Probleme im Performance- und Stabilitätsbereich verantwortlich ist. Die Umfrageteilnehmer identifizierten viele Ursachen von unzureichendem Problembewusstsein und mangelhaften Prozessen zur Performanceoptimierung über fehlende Tools und Fertigkeiten bis hin zur Komplexität von Java und der IT-Infrastruktur. Insgesamt sehen die Befragten aber weniger ungünstige Strukturen, sondern eher die Umsetzung als den Kern von Performance- und Stabilitätsproblemen. Jeweils mehr als die Hälfte nannten ineffizienten Code und falsche Architektur als wesentliche Ursachen. Auch bei der Frage nach konkreten Problemfeldern in den Bereichen Performance und Stabilität von Java-Anwendungen wurden alle zur Verfügung stehenden Antwortmöglichkeiten von mehr als jedem fünften Teilnehmer gewählt: Typische Java-Themen wie Memory Leaks, Garbage Collection und Threading, aber auch die Einbindung von Datenbanken und Legacy-Anwendungen bzw. das Remoting. Etwas herausgehoben waren lediglich die Problemfelder Datenbankzugriff und Memory Leaks, die jeweils knapp die Hälfte der Befragten nannten. Stärker differenziert waren die Antworten, wenn man nach den konkreten Technologien fragte, die als performancekritisch eingeschätzt wurden. Nicht unerwartet waren es die Technologien rund um Kommunikation und Persistenz, die bevorzugt genannt wurden; allen voran die Kommunikation mit SOAP und XML, knapp dahinter Persistenztechnologien wie Hibernate, TopLink, Kodo und EJB. Seltener werden dagegen die typischen Java Web- und Application-Frameworks wie Struts, Seam, Spring u. a. als Problem wahrgenommen. Auch bei der Frage nach den für Performance kritischen Softwarekomponenten gaben die Befragten eine klare Antwort. Als Hauptproblem wurden die Kerntechnologien einer jeden Java- Anwendung gesehen, insbesondere der Applikationsserver, er wurde von über 55 % genannt, klar vor der JVM mit gut 35 %. Die eher auf höherer Ebene – Kommunikation und Orchestrierung – angesiedelten Softwarekomponenten wie ESB, Portale oder Process Engines wurden als wesentlich weniger kritisch betrachtet.

Performancewerkzeuge

Zu der von den Unternehmen unterschätzten Bedeutung von Performance passt, dass vielfach gar keine Werkzeuge zur Performanceanalyse und zum Performancetuning im Einsatz sind. Vor allem, sobald es um das Thema Performance im Java-Code geht, stößt man auf viele weiße Flecken. Fast zwei Drittel der Befragten gaben an, keinerlei Tools zum Java Monitoring im Einsatz zu haben, kein einziges Tool erreicht eine Nennung von mehr als 6 %. Immer noch 41 % nutzen auch keine Werkzeuge zum Java Profiling. Immerhin gibt es mit Eclipse TPTP (27 %) einen klaren Favoriten unter den Tools. Quests JProbe folgt mit 12 % mit weitem Abstand. Ein ähnliches Bild ergibt sich bei Performancetestwerkzeugen, die nicht direkt am Java-Code selbst ansetzen. Ca. 37 % gaben an, keine solchen Tools zu nutzen. Allerdings zeigt Apaches JMeter, mit 35 % das meistgenannte Tool vor HPs Loadrunner mit 16 %, dass es eine gewisse Marktrelevanz besitzt. Diese Ergebnisse zeigen auch, dass am liebsten zu günstigen Open-Source-Alternativen gegriffen wird, als teure proprietäre Lösungen anzuschaffen, wenn dann ein Tool eingesetzt werden soll.

Fazit

Die Studie hat mit den Ergebnissen der Umfrage und den daraus gewonnenen Erkenntnissen die Erwartungen voll erfüllt. Performance im Java-Bereich, so hat sich erwiesen, ist ein Thema mit viel Potenzial, das für die codecentric GmbH auch in Zukunft eine zentrale Rolle spielen wird. Die Studie soll 2009 wiederholt und in den folgenden Jahren weitergeführt werden. Damit wird die Entwicklung des Meinungsbildes zu Performance und damit zusammenhängenden Technologien, Problemen und deren Ursachen sowie des Einsatzes von Performancewerkzeugen genau weiterverfolgt.

Dr. Raymond Georg Snatzke

Senior IT Consultant codecentric GmbH

 

Zurück zu den Publikationen