Dienstag, 17. Januar 2017

Performanceoptimierung Von Webseiten

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.

Donnerstag, 8. Dezember 2016

Vortrag bei der Java User Group Dublin - Fotos

Jetzt sind die wirklich guten Fotos von meinen Vorträgen, IoT mit Tinkerforge und Software Robustheit, bei der Java User Group Dublin da:
https://www.flickr.com/photos/139932355@N08/albums/72157674941628376

Danke an die beiden netten Hosts: Barry und Gerry und an die Firma Tinkerforge für die Unterstützung.





Dieser Briefkasten (Dublin, Temple Bar) stammt aus der Zeit als George König war. GR bedeutet George Royal und nicht wie es einem die Iren erzählen George Rules. Man beachte das der Briefkasten irisch Grün und nicht Englisch rot ist!


Internet Radio

Jeder kennt Spotify und andere Internet Radio Stationen. Hier eine beachtenswerte Alternative aus San Francisco, somaFM. Es ist 100% Werbefrei und finanziert sich nur aus den Spenden der Hörer. Es sind auch Apps für iOS, macOS und Android verfügbar, man kann es auch via Browser hören. Die Apps haben kleine Macken, funktionieren aber sonst gut, d.h. man kann gut Musik hören. Inhaltlich gibt es diverse thematische Kanäle wie z.B. Groove Salad oder Secret Agent aber auch einen für Weihnachten (Chrismas Lounge).

SomaFM commercial free internet radio

Mittwoch, 12. Oktober 2016

Berechnen der CPU Nutzung in Bash

Für Last-Analysen, Performance-Analysen und Robustheitsanalysen ist es sinnvoll die CPU Auslastung des Zielsystems zu kennen um auf mögliche Ressourcenprobleme bei des CPU zu schliessen. Dabei sind die Programme top und stop die ersten Anlaufpunkte. Um aber die gesamte CPU Auslastung automatisch per BASH Script zu erfassen sind nur begrenzt geeignet. Alternativ kann man sysstat benutzen, welches aber erst installiert werden muss. Hier nun eine sehr einfache Methode die CPU Auslastung per BASH Script ohne Zusatzsoftware zu erfassen:

ps -A -o pcpu | tail -n+2 | paste -s -d '+' - | tr , . |bc

Dieser Wert muss dann noch durch die Anzahl der CPUs geteilt werden um die Auslastung des Servers zu ermitteln. Das tr ist nur auf Systemen notwendig, die ein Komma als Dezimal-Separator haben, sonst schadet es aber auch nicht.


Die Anzahl der Kerne eines Servers kann man auf verschiedene Weisen ermitteln. Hier die meine, welche für Linux als auch für macOS funktioniert:

getCores () {
    os=`uname`
    if [[ "$os" == 'Linux' ]]; then
        core=`nproc`
    elif [[ "$os" == 'Darwin' ]]; then
        core=`sysctl -n hw.ncpu`
    else
        echo "Error: Unsupported platform: $os"
        core=-1
        exit
    fi
}

Die Anzahl der Kerne wird in die BASH Variable $core geschrieben.



Mittwoch, 5. Oktober 2016

Schnell Analysen mit R: Ich kenn SQL aber wie mache ich das in R?

Hier eine kleine Anleitung für SQL erfahrene Benutzer um Daten schnell und effizient mit R zu analysieren.

Mit R kann ohne Zusatzpakete jedes Problem lösen. Leider sind einige Funktionen in R relativ umständlich und bei grossen Datenmengen nicht sehr performant. Ein R-Paket mit dem es schneller und einfacher geht ist: data.table. Alternativ können auch andere Pakete wie dplyr oder sqldf benutzt werden. Dplyr setzt auf Pipes (wie Splunk auch) zur Verarbeitung der Daten. Mit dem R-Paket sqldf werden die Daten in eine SQLite Datenbank übertragen. Dann können die Daten einfach mit SQL abgefragt werden: sqldf("select avg(vctotal), avg(dctotal) from a2 where label ='A'"). Hier noch eine Anmerkung zur Benutzung von Date Feldern in sqldf, die Date Strings müssen ins UTC ticks / unix epoch Werte umgerechnet werden. Das ist das interne Format der Datenbank.

Aber los gehts.

Voraussetzung:
  • data.table geladen
  • Daten aus CSV Datei in die Variable g geladen.

Anmerkungen
  • Row (R) und Tupel (SQL) werden hier synonym verwand.
  • Was in Programmiersprachen wie Java der Punkt ist ist in R das $ Zeichen.
  • Mit installiertem OpenMP laufen einige data.table Operationen schneller. Auf dem Mac installiert man OpenMP mit brew install openmpi

R data.table cheat sheet

Aufgabe
SQL
R + data.table
Anmerkung
Auswahl mit Hilfe eines Vergleichs Rows/Tupelselect * from g where dc < 10000g[ dc < 10000, ]Nicht das Komma vergessen
Nur die ersten 15 Rows anzeigenselect * from g limit 15
head( g, 15)
g[ 1:15, ]
Beide Varianten gehen
Mehrfach Auswahlselect * from g where dc < 10000 and dc > 500g[ dc < 10000 & dc > 500, ]
Zählen der Ergebnisseselect count(*) from gg[ , .N ]
.N ist eine spezielle Variable in data.table - alternativ kann man die Anzahl auch über dim(g)[1] bestimmen.
Mittelwert berechnenselect avg(dc) from gg[ , mean(dc) ]In R heisst der Mittelwert mean und nicht average
Mittelwert und Median berechnen???g[ , c(mean(dc), median(dc)) ]Hier müssen die Berechnungen mittel c() zusammengefasst werden
Mittelwert berechnen bezogen auf verschiedene Gruppenselect avg(dc) from g grouped by ABg[ , mean(dc), by = AB ]Achte auf das = nach dem by
Auswahl mit einer Liste
select * from where visit IN (values)
a[ a$visit %in% meineListe ]wichtig sind hier die umschliessenden % Zeichen, meineListe ist eine Liste mit den Selektionierten - values sind die Werte selbst
Umgekehrte Auswahl mit einer Listeselect * from where visit NOT IN (values)a[ !(a$visit %in% meineListe) ]Negation mit !
Vorkommen von Werten zählenselect count(*) from g grouped by visittable( g$visit )um teure Operationen zu testen, kann man die Operation auf einem Subset durchführen table( g[1:50]$visit )
Left outer joinselect * from g, tg[ t ]
Anmerkung: es müssen in g und t die Spalten als Key gesetzt werden die man für den Join benutzen möchte
setkey(g, visit)
setkey(t, visit)
Berechnen einer neuen SpalteALTER TABLE g ADD vkok AS (vc<10000 & vc>500) a1[ , vkok:=(vc < 10000 & vc > 500) ]Hier wird in Place eine neue Spalte mit boolschen Werten berechnet: vkok
Löschen einer  SpalteALTER TABLE c DROP COLUMN vcgroup g$vcgroup = NULL
Teilen ein Menge in gleich grosse Teilmengen (Buckets)
g1$vcg = as.numeric( cut2( g1$vc, g = 5) )Es wird eine neue Spalte den Daten hinzugefügt die die Gruppennummer des Buckets enthält. Die Buckets enthalten gleich viele Element, dies kann wie folgt geprüft werden: g1[, .N , by = vcg]
Die Buckets werden entlang der Dimension vc gebildet. Aufsummiert ergeben die Buckets eine Percentil-Zerlegung der Daten.
Auswahl einer Menge Mittels LikeSELECT * FROM a1 WHERE url LIKE "amount.json"a1[ like(url,"amount.json") ]Die LIKE Funktion ist eine Art sehr einfacher Grep
SortierenSELECT * FROM a1 ORDER BY ttfb ASCa1[ order(ttfb) ]Sortiert das Ergebnis der Abfrage nach dem Feld ttfb. Es können auch mehrere Felder angegeben werden, nach denen sortiert wird. Wichtig, hier keine Anführungszeichen beim Feldnamen (colname) verwenden.

Mittwoch, 14. September 2016

Robust Code: Update von Daten mittels Switch

Stell dir vor du downloadest regelmäßig eine Datei, die du danach weiter verarbeitest. Hier zur Illustration als Bash:

curl -sS "http://eber-p.com/report.csv" | wc -l

Wenn jetzt der Download aus irgend einem Grund fehlschlägt, dann bricht die Datenverarbeitung ab. Dein Service liefert keine Ergebnis mehr. Hier pflanzt sich ein Fehler durch mehrere Systeme fort. Das kann gewollt sein, meistens möchte man aber eine robuste Lösung die nicht bei jedem Downloadfehler zusammenbricht. Dies kann man erreichen, in dem man die alte Datei nicht überschreibt, sondern als Fall Back behält und sie ggf. erst nach einem erfolgreichen Download überschreibt.

wget "http://eber-p.com/report.csv" 
r=`ls -t report.csv* | head -n 1`
cat $r | wc -l   


Wichtig ist nur, dass man die Benutzung des Fall Backs dokumentiert, im Log File und oder in der Antwort des Services. Letztere wird hier nicht gemacht.

Kurz zusammengefasst die robuste Softwarelösung:

  1. Lose Kopplung von Programmteilen die unterschiedliche Funktionen hat, hier Datenbeschaffung und Logik (hier zählen der Zeilen des Reports). 
  2. Puffern von alten Daten und Nutzung von diesen Daten als Fallback.

Zum Thema hier noch ein passender Link. Dort wird diese Problematik unter dem Begriff Be Atomic beschrieben.

Hier das ganze Beispiel-Skript:
#! /bin/sh

echo "Test with right URL"
u="http://ebert-p.com/report.csv"

echo "Non robust code"
curl -sS  $u | wc -l

echo "Robust code"
wget -q -a log.log  $u
r=`ls -t report.csv* | head -n 1`
cat $r | wc -l         


echo "Test with wrong URL"
u="http://ebert-p.com/report_wrong.csv"

echo "Non robust code"
curl -sS  $u | wc -l

echo "Robust code"
wget -q -a log.log  $u
r=`ls -t report.csv* | head -n 1`
cat $r | wc -l   

Und die Konsolen Ausgabe:
Test with right URL
Non robust code
    1518
Robust code
    1518
Test with wrong URL
Non robust code
      24
Robust code
    1518