Freitag, 1. Dezember 2017

Software Zuverlässigkeit, Verfügbarkeit und Six Sigma

Alle nicht-funktionalen Anforderungen (NFA) an Software zahlen auf die Verfügbarkeit der Software ein. Aber welche Verfügbarkeit soll man anstreben?

Zu erst nach dieser Formel wird die Verfügbarkeit berechnet:

Verfügbarkeit [%] = (Gesamtzeit - Zeit mit Fehlern) * 100 / Gesamtzeit

Bei klassischen Industrieprodukten nimmt man eine Zeitspanne die auf der durchschnittlichen Lebenszeit der Produkte basiert (MTBF). Aber bei Software gibt es keine MTBF, weil die Ausfälle von Software weder auf Verschleiss wie bei mechanischen Produkten oder dem Zufall wie bei elektronischen Bauteilen beruhen. Deshalb wird bei Server-Diensten wie E-Commerz Lösungen oft die letzten 365 Tage als Betrachtungszeitraum genommen. Aber was bedeutet ein Verfügbarkeitswert von 99.9%, ist das gut? Die Antwort ist ... ein bisschen komplizierter. Zuerst mal ein kleine Übersicht was solche Prozentwerte eigentlich an Zeit bedeuten:



D.h. bei einer Verfügbarkeit von 99.9% habe ich mehr als 8h Ausfall im Jahr. Das ist sicher mehr als man bei einer hohen Zahl wie 99.9% erwartet hätte. Aber welche Werte sollte man für die Verfügbarkeit anstreben? Im Gegensatz zu mechanischen oder elektronischen Systemen kann man sich bei Software auf noch keinen Standards oder Normen abstützen. Aber es gibt als universelles Qualitätsmanagementsystem Six Sigma. Man kann jetzt versuchen Six Sigma auf Softwarezuverlässigkeit anzuwenden. Als Grenzwert bzw. anzustrebender Wert bietet sich Level 6 von Six Sigma an mit einer Wert von 99,99966% Fehlerfreiheit an. Setzt man diese Zuverlässigkeit zu Grunde, dann hat man nur noch 1,8 Minuten Ausfall im Jahr.

Nachdem das Ziel klar ist, stellt sich jetzt die Frage, ist dieses Ziel realistisch und wie kommt man dahin?

Mittwoch, 29. November 2017

Warum wir Robustness Test brauchen.

Es gibt einen sehr einfachen Grund für Robustness Tests, Robustness Tests helfen dabei die Verfügbarkeit von Softwaresystemen zu steigern. Es gibt drei wesentliche Einflussfaktoren die zu einer Reduzierung der Softwarezuverlässigkeit führen:

  1. Anzahl bzw. Frequenz von Störfällen (Incidents)
  2. Dauer von Störfällen (Duration of Incidents)
  3. Auswirkung oder Umfang von Störfällen (Impact of Incidents)
Robustness Test wirken sich positiv auf alle drei Faktoren aus.
  1. Robustness Test ermöglichen es ein Softwarearchitektur zu wählen bei denen ein Störfall auf das betroffene System beschränkt bleibt und es zu keiner Fehlerkaskade kommt. So wird im Falle eines Störfalls der Umfang begrenzt.
  2. Durch die Reduktion des Umfangs des Störfalls auf eine Einzelsystem wird für die Wiederherstellung des Betriebs weniger Zeit benötigt. Es sind keine Aufwendigen Startprozeduren notwendig wie z.B. starte als erstes Db Server, dann die App Server, warte auf App Server für 3 Minuten bis sie voll funktionsfähig sind, 3. wäre Cache vor, ...
  3. Und als drittes führen Robustness Test zum frühzeitigen Aufdecken von noch unbekannten Problemen die in der Zukunft zu Störfällen geworden wären.
  4. Und als letztes verhindern Robustness Test das Wiederauftreten bekannter Störfälle in dem man bekannt Störfallszenarien als Robustness Test umsetzt und regelmässig testet. Auch so wird die Anzahl der Störfälle reduziert. Für diesen Fall kann man auch eine Testabdeckung berechnen, d.h. wieviele bekannt Störfälle werden regelmässig durch Robustness Test abgedeckt, bzw. simuliert.

Zusammenfassend kann man festhalten Robustness Test sind sie Art von Test die man zum prüfen von nicht-funktionalen Anforderungen (NFA) benötigt.

Montag, 26. Juni 2017

Nicht-funktionale Anforderungen: Seamless Deployment

Ein System soll unter Last deployed werden können ohne das es negative Auswirkungen auf den Kunden hat, das bezeichnet man als Seamless Deployment. Vor allem ist diese Anforderung wichtig, weil durch das Heute übliche Continuouse Deployment (CD) permanent neue Softwareversionen released werden. Dieser Test muss unter üblichen Lasten d.h. Volllast durchgeführt werden.

Montag, 12. Juni 2017

Bad Code: Multiple Exit Point Problem

Lange war mir nicht klar warum multiple Exit Points ein Problem sein sollen. Sei sind eine einfache Möglichkeit schlanken und einfachen Code zu schreiben. Bis jetzt.

Ich muss gerade bestehenden Code für Monitoring instrumentalisieren, das mache ich auf sehr einfache und verständliche Art mittels System.currentTimeMillis().  Das Hauptproblem sind multiple Exit Points:

  1. Exit Points können übersehen werden. Das passiert bei langen Methoden manchmal nicht sehr schnell. 
  2. Das Code auf Try Blöcken entfernt werden (Premature Optimization) und ich Code umkopieren muss um die Logik zu erhalten. Oder anders ausgedrückt: Code der eigentlich zum Try gehört aber sich nicht im Try Block befindet. Er steht nach dem letzten Catch, welche return Anweisungen enthalten. Dieser Code muss wieder in den Try Block eingefügt werden.


Fazit:

  1. Multiple Exit Points sind keine gut Idee, 
  2. Ausser die Methode ist ein 5-Zeiler.
  3. Unit-Test sind die Basis des erfolgreichen Refactorings.



Zurück auf den alten Stand mit Git

Wenn man z.B. den Master oder einen wichtigen Branch zerstört hat und auf einen funktionierenden Softwarestand zurückkehren möchte muss man folgende zwei Schritte durchführen:

1) Den HEAD auf den entsprechenden funktionierenden Commit zurücksetzen und diese Änderung auf den Master pushen:
git revert --no-commit 14y6c335..HEAD
git commit
git push
Jetzt funktioniert der Master und Head wieder.


2) Lokal sind noch die alten, also die defekten Daten vorhanden, die kann man jetzt ggf editieren oder einen neuen Branch erzeugen oder einfach zurücksetzen. Dann ist die lokale Kopie wieder identisch mit dem Master und Head.
git reset HEAD --hard

Mittwoch, 26. April 2017

Docker: Oracles Java auf einem Ubuntu Image

Das geht ganz einfach, bei den meisten gängigen Images bekommt man OpenJDK oder die Images sind nicht gewartet. Also hier eine relativ einfache, mögliche Lösung:

FROM ubuntu:latest
MAINTAINER mirko.ebert@g****.com

RUN apt-get update; apt-get -y upgrade
RUN apt-get -y  install software-properties-common
RUN add-apt-repository ppa:webupd8team/java
RUN apt-get update
RUN echo debconf shared/accepted-oracle-license-v1-1 select true |  debconf-set-selections
RUN echo debconf shared/accepted-oracle-license-v1-1 seen   true |  debconf-set-selections
RUN apt-get -y  install  oracle-java8-installer


RUN apt-get clean

Donnerstag, 6. April 2017

R Package Helper: Finden aller benötigten R Pakete

So kann man alle R Pakete in einem Projekt finden und in eine Datei schreiben.

RUN grep -r -h library src | tr '()' ' ' | tr '"' ' ' | awk '{print $2}' > DEPENDENCIES.txt

Später kann man diese Datei im Dockerfile verwenden um im Docker alle benutzen R Pakete zu installieren:

RUN cat DEPENDENCIES.txt  | xargs -i Rscript -e 'install.packages("{}", repos="http://cran.us.r-project.org")'

Donnerstag, 9. März 2017

Awesome macOS command line tools

Eigentlich ist dem Titel nichts mehr hinzuzufügen. Unter https://github.com/herrbischoff/awesome-osx-command-line findet man eine sehr gute Sammlung von oft unbekannten macOS Commandozeilen Werkzeugen und Aufrufen die das Leben für Terminal-fixierte Leute auf dem Mac deutlich erleichtern. Ein paar der Sachen liefen bei mir schon. Jetzt haben ich neue Dinge um die Arbeit zu vereinfachen.

Mittwoch, 8. März 2017

Robustness Test Scenario: Slow Down Connection via Command tc

Ein Robustness Test Szenario ist die langsame Verbindung zwischen Servern. Der Grund für so eine Störung können vielfältig sein, liegen aber meistens im Bereich Last, Lastenverteilung und fehlerhafte Software. Konkret können massives Logging (Debug Schalter in Live vergessen) zu massiven Schreiboperationen führen, wenn die Festplatte nicht lokal ist sondern per NAS bereitgestellt wird, kann dieses Logging auch andere Diensten Beeinträchtigen, weil das NAS ausgelastet ist.

Dieses Szenario kann jetzt auf verschiedenen Wege simuliert werden. Man kann das Logging simulieren oder man kann die Netzwerkschnittstelle drosseln. Bei SSH Verbindungen ist dies einfach, dort gibt es einen passenden Schalter, den gibt es auch bei CURL und Webbrowser wie Chrome können das auch. Aber es gibt für Linux auch einen allgemeineren Weg mit dem Commando tc. TC steht für Traffic Control und erlaubt das Drosseln der Verbindungsgeschwindigkeit (Bandbreite, bandwidth) und eine Erhöhung der Netzwerklatenz (ping, trafic shaping).

Hier ein kleines Beispiel.
Ein Ping auf Google.com Dauer etwas länger als 9ms.

Jetzt fügen wir 500ms Latenz hinzu.
sudo tc qdisc add dev eth0 root netem delay 500ms


Jetzt benötigt der Ping 509 ms.

Danach noch alle Änderungen rückgängig machen.
sudo tc qdisc del dev eth0 root

Das gleich funktioniert auch mit der Begrenzung des Traffic Durchsatzes. Neben Robustness Test lassen sich auch Web Performance Messungen mit unterschiedlichen Anbindungen (3G, UMTS, ...) simulieren.

Link:

  1. http://mark.koli.ch/slowdown-throttle-bandwidth-linux-network-interface
  2. https://github.com/markkolich/blog/blob/master/content/entries/slowdown-throttle-bandwidth-linux-network-interface.md

Mittwoch, 15. Februar 2017

Welches Kompressionsverfahren ist das Beste?

Es gibt schon einige Verfahren um Daten Klei zu kriegen. Auf Wikipedia zähle ich mehr als 20, auch wenn da eher historische Verfahren dabei sind oder Verfahren, die fast gleich sind. Der inspiriert vom letzten Versuch zu BROTLI und ZOPFLI (Link) habe ich den Versuch um die beliebten Verfahren LZMA und BZIP2 ergänzt.


Datei Uncompressed Gzip Compression rate Zopfli Compression rate Brotli Compression rate LZMA Compression rate BZIP2 Compression rate
redirect_frame.html 431 300 1,4 274 1,6 194 2,2 294 1,5 312 1,4
runtasticOTTO.html 162730 35690 4,6 34091 4,8 30535 5,3 32182 5,1 34682 4,7
www.ebert-p.com.html 15134 3191 4,7 3064 4,9 2568 5,9 3099 4,9 3924 3,9

Ergebnisse

  1. Jede Kompression ist besser als Keine.
  2. BROTLI ist das Verfahren der Wahl und sollte auf den Web-Servern aktiviert werden.
  3. Wenn BROTLI nicht geht, dann sollte man ZOPFLI nehmen.
  4. LZMA ist wie ZOPFLI eine gute Wahl.
  5. BZIP2 kann kaum punkten ist auf einem ähnlichen Niveau die GZIP. Hier sollte man wegen seiner Verbreitung eher auf GZIP setzen.

Dienstag, 14. Februar 2017

Performanceoptimierung von Webseiten: Besser komprimieren mit Googels Brotli und Zopfli

Noch dem man das HTML und allen anderen Test-basierten Inhalte einer Website minifizioert hat, kann man auch bei der Kompression selbst auch noch ein paar Bytes rausholen. Und weil Google alle Probleme schon etwas früher als ich hatte, hat Google auch schon eine Lösung. Und die Lösung heisst: BROTLI und ZOPFLI anstelle von DEFATE und GZIP.

ZOPFLI ist ein GZIP kompatibles Kompressionsverfahren, das hat den Vorteil es musss nur durch den Web-Server unterstützt werden, alle gängigen Web-Browser sind GZIP fähig und damit auch ZOPFLI fähig.

BROTLI ist dagegen nicht kompatibel und versucht die Vorteile von LZMA oder BZIP2 (hohe) Kompression mit einem günstigeren Laufzeitverhalten zu kombinieren. LZMA und BZIP benötigen im Vergleich zu GZIP und verwandte wesentlich mehr Sei für die Kompression bzw. De-Kompression. Was sich negativ auf die Ladezeit einer Web-Seite auswirken kann, speziell auf die TTFB (Time to first byte). Lesenswert ist hier der Vergleich von den Google-Entwicklern (Link 2).

Aber jetzt mal einen eigenen Test. Zuerst müssen beide Programme mittels Paketmanager installiert werden. Dann geht es los. Alle Programme werden in der Standardkonfiguration benutzt, es gibt keine weitere Optimierungen. Weil die nur BROTLI, ZOPFLI und GZIP für Web-Server relevant sind werd nur die getestet. Alle Grössen-Angaben in Byte.

Datei Original Gzip Komprssionsrate Zopfli Komprssionsrate Brotli Komprssionsrate
redirect_frame.html 431 300 1,4 274 1,6 194 2,2
runtasticOTTO.html 162730 35690 4,6 34091 4,8 30535 5,3
www.ebert-p.com.html 15134 3191 4,7 3064 4,9 2568 5,9

Ergebnisse

  1. ZOPFLI schlägt GZIP, die Kompressionsrate verbessert sich um 0,2.
  2. BROTLI schlägt ZOPFLI, die Kompressionsrate verbessert sich deutlich um mehr als 0,4.
  3. Kleine und grosse Dateien profitieren von BROTLI und ZOPFLI.

Links

  1. http://caniuse.com/#search=brotli
  2. https://cran.r-project.org/web/packages/brotli/vignettes/brotli-2015-09-22.pdf
  3. https://www.golem.de/news/datenkompression-auf-googles-zopfli-folgt-brotli-1509-116438.html
  4. https://devcentral.f5.com/articles/ops-briefing-amp-html-and-brotli

Montag, 13. Februar 2017

Performanceoptimierung von Webseiten: HTML Minifizieren

Das nur minifixiertes CSS und JS ausgeliefert wir ist heute sicher Standard. So werden viele Bytes bei der Übertragung gespart, auch in den den Zeiten von GZIP und HTTP/2 ist das noch so. Nur ist der Effekt des Minifizierens geringer. Leider wird sehr oft vergessen auch das HTML selbst zu minifizieren. Auch ist hier die Tooluntzerstützuzng nicht so üppig wie beim Minifizieren von CSS und JS. Aber es gibt z.B. für Wordpress ein Plugin, das gut Ergebnisse liefert, bei mir spart es ca. 15% der zu übertragenen Bytes, bei eingeschalteter GZIP Kompression.

  • Minify HTML von Tim Eckel
Wenn man HTML minifixiert kann Einsparungen zwischen 15 bis 33 % der zu übertragenen Bytes einsparen. Nach entsprechender Kompression ist immer noch mit einem einstelligen Prozentwert an Einsparung zu rechnen. Das klingt nicht viel, lohnt sich aber, weil der Aufwand relativ gering ist. Der Zeitlich Vorteil beim laden einen komplexen Seite kann zwischen 0,5 ms bei einem schnell angebunden Desktop Computer und 35 ms bei einem Samsung Galaxy S5 mit 3G (regular) liegen. Probieren kann man dies einfach mit den Chrome Developer Tools. Dazu kommt, dass das HTML sehr wichtig für den Seitenaufbau ist, auch wenn Bilder einen grösseren Byte-Beitrag zur Webseite leisten. Weitere positive Aspekte:
  • Durch das geringere Datenvolumen verringert sich die Wahrscheinlichkeit für Re-Transmits, vor allem in überfüllten Netzen (Prime Time, Mobile Networks). 
  • Auch die Menge der Ausreisser der Ladezeit verringern sich. 
  • Die Connection kann früher für andere Daten genutzt werden. 
HTML Minifizierung ist nicht gleich HTML Minifizierung, hier gibt es verschiedene Aspekte:

  1. Entfernen von allen Whitspace Chars
  2. Minifizieren von Inline JS
  3. Entfernen von Kommentaren
  4. Entfernen von XHTML Closing Tags
  5. Entfernen von Domains von internen URLs
  6. Case sensitive Tags
  7. HTML Entities zu Unicode umwandeln 6 byte -> 2 byte 
  8. Leere Tags und Attribute entfernen
Links



Graphische Trendanalyse von stark schwankenden Messwerten mit R

Statistisch lässt sich das Problem recht einfach mit dem XX-Test und ähnliche Test lösen. Neben diese Aussage ist es notwendig die Rohdaten entsprechend graphisch aufzubereiten, weil man mit Grafiken wesentlich besser überzeugt als mit der Angabe von Wahrscheinlichkeit oder Koeffizienten.

Die graphische Aufbereitung von stark schwankenden (volatiler) Messwerten kann man einfach als Signalverarbeitungsproblem sehen. Zuerst muss man das Signal (Messwerte) glätten und danach schärfen.

Die mathematische Entsprechung einer einfachen Glättungsfunktion, bei der Bildverarbeitung spricht man auch von einem Weichzeichner, ist der gleitende Mittelwert mit einer Gauss-Verteilungs-Gewichtung.

In R sieht dass dann wie folgt aus:
library('smoother')
smth.gaussian(dtDateRange$duration_min, window = kSmoothingWindowSize, tails = T)


Hier ein Ergebnis in graphischer Form. Klar sind hier die unterschiedlichen Bereich erkennbar. Man kann das Ergebnis noch deutlich verbesser um alle hochfrequenten Schwingungen zu eliminieren.
Hier noch ein anderes Beispiel für die graphische Trendanalyse inclusive der originalen Werte.


Dienstag, 17. Januar 2017

Performanceoptimierung von Webseiten: Prefetching

Neben den vielen Ideen zur Steigerung der Performance war das Prefetching eine. Das gab es schon seit sehr frühen HTML Versionen und war über die Jahre ein wenig in Verruf geraten. Danach wurde Prefetching mittels Selbstgebauten Loader via JS und CSS  realisiert. Soweit zur Vergangenheit. 

Es gibt heute wieder die Möglichkeit Dinge vorzuladen. Das führt nur zu einer Verbesserung der Performance auf den Folgeseiten einer Website, eventuell kann man auch Einstiegsseiten beschleunigen, das müsste man genau Testen. 

Mit HTML5 geht es wieder sehr einfach und man kann nicht nur einzelne Seiten oder Resource vorladen, sondern z.B. auch ein DNS Prefetching machen. Hier ein paar Links, ja Wikipedia aber die Englische:


Sonntag, 1. Januar 2017

Identifizieren von allen Geräten im lokalen Netzwerk

Mittels Ping findet man einfach heraus ob ein Server läuft. Mittels einer Schleife kann man so z.B. ein Netzwerksegment scannen Leider antwortet nicht jedes Gerät auf einen Ping. Eine Alternative ist Nmap. Z.B kann man mit einem Einzeiler ein lokales Netzwerksegment scannen:
nmap -sn 192.168.0.0-255 

Am Beste man schickt gleich ARP hinterher um alle Netzwerk Elemente zu finden:
arp -a | grep -v '^?'

So werden auch Handys gefunden.

Nmap und Arp lassen sich über die üblichen Paketmanager installieren, auch mit brew auf dem Mac.