Follow my new blog

Donnerstag, 21. Februar 2013

Vorzeitige Optimierung durch Monolithen

Softwareentwicklung ist historisch ein Geschäft der knappen Ressourcen. Speicher war knapp, Speicher war langsam, die Prozessorgeschwindigkeit war gering, die Prozessorverfügbarkeit war niedrig und die Kommunikation zwischen Prozessoren/Maschinen war unmöglich bis schwierig.

Ich glaube, diese jahrzehntelange Not ist zum Bestandteil der Kultur der Softwareentwicklung geworden. So wie die Not der (Vor)Kriegszeit zur Kultur unserer Eltern und Großeltern gehört.

Der Teller wird leer gegessen. Man schmeißt keine Lebensmittel weg. Mit dem Essen spielt man nicht. Kerzenstummel und andere Reste werden gehortet. Socken müssen gestopft werden. Wer kennt solche Ermahnungen und Verhaltensweisen nicht von Eltern und Großeltern? Sie entstammen einer tief liegende Angst, dass das, was heute verfügbar ist, morgen wieder weg sein könnte. In der heutigen Zeit des Überflusses sind es allerdings Anachronismen [1].

Ähnlich kommen mir nun viele Reflexe von Entwicklern vor. Sie mahnen, nicht verschwenderisch mit Speicher umzugehen; sie bedenken zu allererst die Performance; sie misstrauen jeder Ressource und jeder Interaktion [2].

Dabei leben auch wir inzwischen in Zeiten des Überflusses. 48 KB oder 640 KB Hauptspeicher oder 5 MB Festplatten sind heute nicht mehr Stand der Dinge. Für viele (oder gar die meisten?) Anwendungsszenarien ist Hardware heute so groß, schnell und billig, dass sie keine Begrenzung mehr darstellt.

Komplette Unternehmensdatenbanken können wir heute im Hauptspeicher halten. Prozessoren haben mehrere Kerne. Festplatten sind schnell und groß. Rechner sind in Gigabit-Netzwerke eingebunden. Und quasi unendlich viele Rechen- und Speicherressourcen stehen auf Abruf weltweit zur Verfügung.

Doch die Mentalität ist immer noch eine der Knappheit. Das kann ich irgendwie verstehen; ich bin ja selbst in Zeiten der Hardwaremängel mit der Programmierung groß geworden. Jetzt sollten wir aber mal diese Haltung langsam ändern. Solange wir uns ihrer nämlich nicht bewusst sind und sie versuchen zu überwinden, verschwenden wir unsere Zeit und geistige Kapazität. Die sind nämlich tatsächlich noch genauso begrenzt wie früher.

In vielen Bereichen ist die Mangelkultur ein Anachronismus. Wir verhärten uns mit ihr gegen nützliche Veränderungen. Denn dass sich einiges verändern muss, ist unzweifelhaft. Beispiel: Softwareentwurf. Wir müssen Software anders entwerfen, damit die Strukturen evolvierbarer werden. Das heutige Legacy Code Problem darf sich nicht ungebremst so fortsetzen.

Für mich ist es ein Problem des Mangeldenkens, weil die uns so drückenden Softwaremonolithen aus meiner Sicht Kinder des Mangeldenkens sind. Denn warum sollte man Code zu einem Monolithen zusammenschweißen, wenn nicht aus Angst vor Performance- und Speicherproblemen?

Unter Monolith verstehe ich hier Software, die all ihre Aufgaben in möglichst wenigen Prozessen erledigt. Am besten ist das nur einer, eine Desktopanwendung (bzw. ein Batch) oder eine Web-Anwendung. Ein Betriebssystemprozess hostet dabei die gesamte Funktionalität. Das ist das Ideal.

Das ist einfach zu deployen. Das ist vermeintlich einfach zu entwickeln, da man alles in ein Visual Studio Projekt stecken kann. Das ist schnell, weil die gesamte Kommunikation innerhalb des Adressraums eines Prozesses stattfindet. Das ist technisch simpel, weil man sich nicht mit Infrastruktur herumschlagen muss.

Natürlich verstehe ich all diese Beweggründe. Ich habe auch so gedacht. Doch inzwischen glaube ich, dass wir uns damit keinen Gefallen tun, wenn wir so auf diese Mängel stieren. Das Deploymentproblem ist heute nicht mehr so groß wie noch vor 10 Jahren; die Kommunikationsgeschwindigkeit ist mit heutigen Prozessoren, Hauptspeichern und Netzwerkverbindungen auch zwischen Prozessen oft ausreichend. Und die Infrastruktur müssen wir nicht mehr in dem Maße selbst programmieren wie noch vor 10-20 Jahren [3]. Wer heute einen Monolithen entwickelt, der betreibt also vorzeitige Optimierung. Er optimiert für Mängel, deren Existenz nicht gesichert ist im Hinblick auf eine konkrete Domäne.

Unsere Kultur verhindert jedoch, dass wir dieses Potenzial voll ausschöpfen. Wo es nicht anders geht, da wird es getan. amazon, Twitter, Facebook, eBay usw. können nicht anders, als an die heutigen Grenzen zu gehen.

Wer allerdings heute ein CRM oder sonstige Intranet/Desktop-Software programmiert, der verschenkt Potenzial. Der schnürt sich ein in ein Korsett, dass man geradezu masochistische Neigungen vermuten könnte.

Wenn es denn sonst keine Probleme gäbe, wäre das ja nicht schlimm. Jedem seine Neigung ;-) Das Evolvierbarkeitsproblem halte ich jedoch für so groß, dass wir uns “Neigungsprogrammierung” in dieser Hinsicht nicht mehr erlauben können. Die mittel- bis langfristige Gesundheit unserer Software leidet darunter. Und auch die unserer Teams.

Wir müssen bessere Wege finden, um Software über die Jahre nicht nur zu retten, sondern entspannt weiterentwickeln zu können. Dazu gehört für mich immer mehr auch die Neuentwicklung. Ja, genau, Code wegschmeißen und neu machen.

Dass das nicht für komplette Anwendungen funktioniert, ist mir klar. Deshalb müssen wir aufhören, Monolithen zu bauen. Die können wir nämlich nur komplett ersetzen – was unökonomisch ist. Oder wir müssen sie zu Tode refaktorisieren.

Mit geht es um einen Mittelweg. In “Form Follows Feasibility” hatte ich schon darüber nachgedacht. Seitdem bin ich nur sicherer geworden, dass solch ein Mittelweg nötig und gangbar ist – wenn wir uns aus dem Mangeldenken befreien.

Die bewusste Strukturierung auch von Deskptop- oder Web-Anwendungen in mehrere Services, d.h. Komponenten mit plattformunabhängigem Kontrakt, ist mir sogar noch wichtiger geworden.

Erstens kann man sich mit plattformunabhängigen Kontrakten weniger in die Tasche lügen, was die Entkopplung von Code angeht. Zweitens bieten nur solche Kontrakte die Chance, sich vor der drohenden Systemrelevanz der Programmierplattform mit einhergehender Verkalkung des Teams zu schützen.

Jede Software als “web of services” zu denken, sollte der Default werden, glaube ich. Und erst wenn sich das handfest als suboptimal herausstellt, sollte mit einer Optimierung begonnen werden.

Endnoten

[1] Die Motive Respekt und Dankbarkeit hinter solcher Haltung will ich nicht ausschließen. Schön, wenn sie denn mitschwingt. Auch im Überfluss tun wir sicherlich gut daran, Bescheidenheit und Respekt unserer Umwelt entgegen zu bringen.

[2] Schizophren ist, dass diese Haltung komplett umkippen kann. Denn der Umgang mit Objekten in verteilten Anwendungen war (und ist?) von großer Naivität, gar Sorglosigkeit geprägt. Da spielten Skalierbarkeit, Robustheit und Performance lange so gar keine Rolle. Anders sind CORBA, EJB und DCOM und auch noch Teile von .NET Remoting nicht zu erklären.

[3] Eine Kommunikation zwischen Prozessen, die über die Welt verteilt sind, ist via Internet und Cloud API wie Pubnub oder iron.io heute eine Sache weniger Zeilen Code.

Kommentare:

Unknown hat gesagt…

Architektur ist nie Selbstzweck, letztlich geht es um das Umsetzen von Anforderungen.

Dabei sind fachl. Anforderungen selten der Art "Zukunftsicherheit sicherstellen - für 10 Jahre". Durchaus zu Recht, niemand kann sicher soweit schauen (im Zweifel ist der von Ihnen genannte Ansatz da auch schon wieder überholt). Und der Anforderer ist auch eher selten so "strategisch" aufgesetzt.

Das zugrundeliegende Problem hierbei bzw. die Quelle der Unsicherheit, es fehlt an der "Strategie". Also was will das Unternehmen erreichen? Und wie will es das tun? Mit welchem zeitlichen Horizont? Wie kann die IT diese Ziele unterstützen (operationalisieren)? Wie kann die Architektur... Sie wissen schon :-)

Der oben genannte Ansatz könnte einem "time to market, wir akzeptieren ständige Neubauten" eher entgegenstehen.

Langer Rede kurzer Sinn, der von Ihnen genannte Ansatz klingt für mich nach einer höheren Anfangsinvestition um später und länger weniger zu investieren. Je nach Unternehmensorganisation würde ich dafür einen strategische Entscheidungsprozess in Gang setzen (wollen).

Ralf Westphal - One Man Think Tank hat gesagt…

Dass es eine größere Anzahl an Monolithen gibt, die im Bewusstsein der Konsequenzen gebaut worden wären, bezweifle ich.

Weder bei Managern noch bei Entwicklern existiert eine Sensibilität für die trade-offs. Und selbst wenn sie existierte, mangelt es weithin an der schlichten Fähigkeit, es anders zu machen.

Insofern ist auch die "vorzeitige Optimierung", die ich hier beschreibe, nicht bewusst, sondern quasi alternativlos.

Natürlich fehlt es an Strategie. Aber gerade deshalb sehe ich Verantwortung bei der Softwareentwicklung, sich maximal offen zu halten. Das bedeutet in Zeiten, da wir keinem Ressourcenmangel auf den Maschinen mehr unterliegen, Software eben anders zu bauen.

"Time to market"... "Wir müssen das ASAP draußen haben!"... ach ja, damit wird alles begründet und entschuldigt. Wenn man sonst keine Ahnung hat, dann weiß man doch eines: Wer zu spät kommt, den bestraft der Markt. Und deshalb muss immer und alles huschhusch gehen, eilig, eilig.

Erstens bezweifle ich, dass das eine Strategie ist und auch noch eine gute. Zumindest nicht in sovielen Fällen wie angenommen. Es ist vielmehr der Ausdruck von Abwesenheit von Strategie. Niemand wurde bisher dafür gefeuert, dass er versucht, schnell zu sein. Niemand ist bisher dafür gerügt worden, andere angetrieben zu haben. "Time to market" ist somit ein Selbsterhaltungsmantra für Manager.

Doch das ist eine Sache der Unternehmensführung und eigentlich hier gar nicht Thema.

Selbst wenn man schnell und noch schneller sein muss, steht vielmehr die technische Frage im Raum: steht eine Serviceorientierung dem entgegen?

Ich behaupte, nein. Im Gegenteil. Software in Services zu zerlegen, erhöht (!) die Entwicklungsgeschwindigkeit. Nicht nur jetzt, sondern für alle Zeit. Zum Teil bieten das auch schon Komponenten, aber mit Services ist es noch nachhaltiger.

Wo liegt denn die höhere Anfangsinvestition? Ich kann sie gar nicht entdecken. Darin, sich überhaupt mal einen Gedanken zu machen, bevor man wie besengt loscodiert? Wohl kaum.

stmon hat gesagt…

Für mich ist es ein Problem des Mangeldenkens, weil die uns so drückenden Softwaremonolithen aus meiner Sicht Kinder des Mangeldenkens sind. Denn warum sollte man Code zu einem Monolithen zusammenschweißen, wenn nicht aus Angst vor Performance- und Speicherproblemen?

Gründe (ungeordnet)

* Ist ja nicht viel, was gemacht werden soll...
* Geht doch bestimmt schnell...
* Brauchen wir nur ein paar mal...
* [Hier eine beliebige Aussage einfügen]

Oft genug fangen Applikationen klein an, ohne sich Gedanken darüber zu machen (kleines VBA-Projekt). Dann kommen ein paar Ideen und aus der kleinen Lösung ist ein Homunkulus geworden.

Ich stimme dem Ziel zu, auch wenn ich mit den Gründen nicht d'accord bin... allerdings braucht es Mut/Chuzpe einfach mal eine vorhandene Lösung (die "Anwendung"; nicht den Gedanken dahinter) nicht weiterzuentwickeln, sondern dem digitalen Nirvana zu überlassen (been there, done that :)

Ralf Westphal - One Man Think Tank hat gesagt…

@stmon: Natürlich gibt es diese Gründe, die du nennst. Aber die liegen auf einer anderen Ebene bzw. bewegen sich in einem Rahmen, der durch das von mir skizzierte Denken vorgegeben wird.

Man kann schnell oder langsam fliegen - aber immer nur mit Rücksicht auf die Physik.

Und genauso kann man nach "Geht doch bestimmt schnell" usw. entwickeln - aber immer nur mit Rücksicht auf die Gegebenheiten der Hardware.

Physik/Hardwaremängel sind so tief eingebrannt in uns, dass wir alles andere daran ausrichten.

Dass das so ist, zeigen immer wieder völlig reflexhafte, geradezu instinktive Reaktionen von Entwicklern. Sie bekommen eine Aufgabe und wenden ohne Nachfrage und ohne weitere Beurteilung der Situation Muster an, die Performance optimieren oder Sicherheit vergrößern sollen.

Die Begründung ist: "Meiner Erfahrung nach..." D.h. der Blick ist rückwärtsgewandt. Ohne Reflexion. Man schaut nicht auf das, was ist, sondern bewegt sich in eingefahrenen Bahnen.

Dito bei der völlig unbewussten Optimierung zum Monolithen hin. Keine Reflexion, keine Abwägung, sondern einfach machen, machen, machen nach Schema F wie schon die letzten 50 Jahre.

Erfahrung ist ne gute Sache. Aber unreflektierte Erfahrung kostet Geld und Zeit.

Die Physik gilt noch wie schon immer. Aber die Mängel der Hardware gelten nicht mehr. Da lohnt sich also Reflexion.

stmon hat gesagt…

Du definierst sozusagen das "Mangeldenken" als Wert, woraus der Rest sich ableitet.

Also, dass die vorhandene Zeit ebenfalls als "Mangel" angesehen wird, und als Entschuldigung angesehen wird, mal "schnell" was zu machen, ohne sich irgendwann klar zu werden, dass eben ein Monolith (oder wie dies Monster auch immer heissen mag :) erstellt wird.

Mhm... im gewissen Sinne stimme ich zu (bei den Konsequenzen bin ich ohnehin schon dabei).

Noch nicht ganz konsent ;)

Ralf Westphal - One Man Think Tank hat gesagt…

@stmon: Zeit als Mangel hatte ich gar nicht so sehr auf dem Schirm. Aber da ist sicher etwas dran. Der Aspekt ist dann unverändert mangelvoll.

Aber eigentlich meinte ich erstmal die weiterhin im Stammhirn sitzende Vorstellung, Ressourcen wie Speicherplatz, Prozessorzeit und Kommunikationsgeschwindigkeit/-bandbreite seien noch Mangelware.

Ultimativ stimmt das natürlich, weil sie endlich sind. Nur in Relation zu dem, was wir heute erreichen wollen, stimmt das nicht mehr oder immer weniger. Vor allem viel weniger als früher.

Nur hat das keiner so richtig mitgekriegt. Deshalb wird unbewusst, reflexhaft optimiert. Also vorzeitig und damit unökonomisch.

Auch im Eleganzbegriff sehe ich davon noch Reste. Der hatte früher etwas mit Ressourceneffizienz zu tun. Welcher Algorithmus braucht weniger Speicher oder Cycles als die bisherigen? "Weniger" bedeutete dann oft auch "eleganter".

Diese Werte haben ihren Wert in einer bestimmten Umwelt, unter bestimmten Bedingungen. Keine Frage.

Sie werden aber zu Anachronismen, wenn sich die Umwelt ändert. Das hat sich massiv getan in den letzten 20-30 Jahren. Nur merken wir davon nichts in den Programmiergewohnheiten.

Wo früher ein Monolith womöglich eine Tugend war, wo es quasi nicht anders ging, als alles möglichst eng zu binden, weil sonst Performance oder Speicherverbrauch schlecht gewesen wären, da ist dieselbe Struktur heute schlicht kontraproduktiv.

Früher war es nötig, Zeugs überhaupt zum Laufen zu bringen. Heute ist es nötig, es unter ständig wechselnden Anforderungen am Laufen zu halten.

stmon hat gesagt…

Früher war es nötig, Zeugs überhaupt zum Laufen zu bringen. Heute ist es nötig, es unter ständig wechselnden Anforderungen am Laufen zu halten.

Ist nur die Frage, wann "früher" war ;)

Für mich persönlich stellt der größte Mangel die Zeit dar; allerdings nehme ich diesen Mangel als Herausforderung an, Code/Architektur/usw so zu entwerfen, dass die Handhabung/Änderung für mich zeitsparend ist, auch wenn ich am Anfang vielleicht etwas länger brauche.

Bitte entschuldigen Sie den langen Brief, ich hatte keine Zeit, einen kurzen zu schreiben. (Blaise Pascal)


mabra hat gesagt…

Hallo !

Ich wollte mal 'was aus der Praxis sagen .... und auch, warum
das einfach wahrscheinlich oft nicht funktionieren kann ...

Wie schon in anderen Beiträgen anklang, das Business hat keine
Strategie, die dazu paßt ... oder ??

Ich arbeite in einem Unternehmen mit > 50 Standorten und z. Zt.
vermutlich so etwa 300 Servern. Die Landschaft hat sich in den
letzten 10 Jahren daramatisch verändert dahin, das es keine Resourcen
mehr gibt. Die Netzwerke sind dermaßen langsam, das sie nur das
Nordüftigste tun. 200 der oben genannten Server sind natürlich
inzwischen virtualisiert.

Das Business betreibt das Geschäft des Mangels und erfindet genau
diesen jeden Tag neu..... !!!!!

Das alles ist Ergebnis der absoluten Optimierung der Businessprozesse,
auch bekannt als Globalisierung. => Zeit == Null !

Die schönen vielen Cpu-Cores/Threads sind nun volles Rohr auf
mehrere Terminalserver verteilt und nichts, garnichts arbeitet
wirklich füssig. Presentation Foundation?? Keine GPU da, nur
virtuelle, es lebe WinForms!

Apps mit mehreren Threads, die warten müssen, weil die Cpu keine
mehr frei hat ?? Das ist die Businesswelt ! Neue Welt ? Gibt's
leider nicht, schon ausverkauft.

Übrigens, ich sage keineswegs, das der architekonische Ansatz
falsch wäre, ganz im Gegenteil. Ich verfolge das seit Jahren
und bin begeistert[es lebe der Flow!].

Viele Grüße,
mabra
(Manfred)

[Ich könnte auch ein paar Performance-Vergleiche nachliefern ;-) ]