Avatar

Ps0ke

Φίλιππος Στέφανος

Nocturnal Inclination

Nerdkram, Internethumor und der ganzen Rest.

mdbl0g Benchmark

When you build a file based blog system like I did, mdbl0g, you are often told: "That'll be way too slow, especially in PHP!". As I don't blog too often and won't have too many posts, it didn't bother me. But what if..? This challenged me to benchmark my code. I wrote a small bash script to generate posts with random names quickly and put some "lorem ipsum" in there the size is varying because of the iterator but each one is around 2,629 bytes (~2.6kB) of size. So I set out to create and test with 1,000; 10,000 and 100,000 files, and the results are quite pleasing. Everything went well for 1,000 and 10,000 and if at all only a small delay occurred. But with 100,000 posts things got ugly. Although the main page rendered surprisingly fast, trying to search fucked up the server. I even pushed up the set_time_limit() in PHP, but the server threw a 500 Internal Server Error. I think no one will ever gather 100,000 blog posts and so this benchmark proves to me, that a file based approach is not so much of an performance issue if you have a reasonable amount of data. The network latency is the bottleneck!

Results

The time is measured inside the PHP script to determine pure script rendering time without network latency.

The script

You can find the full script pasted at GitHub:gist.

#!/usr/bin/env bash
if [[ $# -ne 2 ]]; then
    echo "Usage: $0 path/to/target/dir <Number of files to create>"
    exit
fi

for i in `seq 1 $2+1`; do
    year=`shuf -i 1900-2012 -n 1`
    month=`shuf -i 10-12 -n 1`
    day=`shuf -i 10-31 -n 1`
    hour=`shuf -i 10-23 -n 1`
    min=`shuf -i 10-59 -n 1`
    echo "$i $year-$month-$day\_$hour-$min.md"

cat <<EOF > $1$year-$month-$day\_$hour-$min.md
Benchmark post #$i
Here’s to the crazy ones. ...

Lorem ipsum dolor sit amet ...
Vivamus placerat, nunc a accumsan ...

Sed ultrices purus eu erat ...
EOF
done

1,000 Files (~2.5MB)

% rm posts/*
zsh: sure you want to delete all the files in /home/ps0ke/html/mdbl0g/posts [yn]? y

% ls posts/ -1 | wc -l
0

% ./benchmark.sh posts/ 1000
...
997 1922-11-29\_10-19.md
998 1915-10-10\_13-58.md
999 1913-11-15\_14-33.md
1000 1962-11-30\_13-13.md
./benchmark.sh posts/ 1000  2.07s user 7.08s system 65% cpu 13.909 total

% ls posts/ -1 | wc -l
999

# First page, 5 posts
% curl -L -s http://ps0ke.de/mdbl0g/ | grep "Execution Time"
<!-- Execution Time: 0.02759s -->

# Search for 'crazy', matches all posts, renders 5 posts
% curl -L -s http://ps0ke.de/mdbl0g/search/crazy | grep "Execution Time"
<!-- Execution Time: 0.23799s -->

10,000 Files (~25MB)

% rm posts/*
zsh: sure you want to delete all the files in /home/ps0ke/html/mdbl0g/posts [yn]? y

% ls posts/ -1 | wc -l
0

% ./benchmark.sh posts/ 10000
...
9997 1908-10-14\_20-58.md
9998 1990-12-25\_11-26.md
9999 1925-12-10\_17-39.md
10000 1967-11-19\_17-48.md
./benchmark.sh posts/ 10000  20.88s user 72.58s system 69% cpu 2:14.51 total

% ls posts/ -1 | wc -l
9990

# First page, 5 posts
% curl -L -s http://ps0ke.de/mdbl0g/ | grep "Execution Time"
<!-- Execution Time: 0.11814s -->

# Search for 'crazy', matches all posts, renders 5 posts
% curl -L -s http://ps0ke.de/mdbl0g/search/crazy | grep "Execution Time"
<!-- Execution Time: 0.70745s -->

100,000 Files (~250MB)

% rm posts/*
zsh: sure you want to delete all the files in /home/ps0ke/html/mdbl0g/posts [yn]? y

% ls posts/ -1 | wc -l
0

% ./benchmark.sh posts/ 100000
99997 1962-10-12\_16-57.md
99998 1982-11-31\_12-33.md
99999 1938-12-13\_12-38.md
100000 1971-12-25\_21-15.md
./benchmark.sh posts/ 100000  219.87s user 960.45s system 67% cpu 29:02.07 total

% ls posts/ -1 | wc -l
98992

# First page, 5 posts
% curl -L -s http://ps0ke.de/mdbl0g/ | grep "Execution Time"
<!-- Execution Time: 0.75187s -->

# Search for 'crazy', matches all posts, renders 5 posts
% curl -L -s http://ps0ke.de/mdbl0g/search/crazy | grep "Execution Time"
[1]    21563 done       noglob curl -L -s http://ps0ke.de/mdbl0g/search/crazy | 
       21565 exit 1     grep "Execution Time"

# set_time_limit(5*60); >> index.php line 2

% curl -L -s http://ps0ke.de/mdbl0g/search/crazy
An internal server error occurred. Please try again later.

IRC Webinterface auf dem eigenen Server installieren

Info

Nach dem ich in einem vorherigen Artiel bereits erklärt habe, wie man einen IRC-Server aufsetzt, möchte ich jetzt noch beschreiben, wie man ein Web-Frontend, qwebirc installiert. Damit können besucher auch ohne Client nur mit einem Webbrowser den Chat verwenden. qwebirc wird auch vom QuakeNet IRC Netzwerk verwendet, einem der größten IRC Netzwerke der Welt--sollte also gut skalieren ;)

Dependencies

Als erstes laden wir die Dependaecies für das in Python geschriebene qwebirc herunter. Das zope.interface ist über den Python-Package-Manager easy_install verfügbar.

$ easy_install zope.interface

Als nächstes brauchen wir das Twisted framework. In einem temporären Verzeichnes laden wir es herunter und installieren es. (Auf aktuelle Downloads prüfen!)

$ cd tmp
$ wget http://twistedmatrix.com/Releases/Twisted/12.1/Twisted-12.1.0.tar.bz2
$ bunzip2 Twisted-12.1.0.tar.bz2
$ tar xvf Twisted-12.1.0.tar
$ cd Twisted-12.1.0
$ python setup.py install

Installation & Konfiguration

Nun, da alle wichtigen Dependancies installiert sind (optionale können auf der qwebirc Website nachgeschlagen werden), können wir qwebirc installieren. Dazu wechseln wir ins Homeverzeichnis und laden den aktuellen Source-tree mit der Versioningsoftware 'Mercurial' herunter (Wer möchte kann auch tarballs auf der Website finden).

$ cd
$ hg clone http://hg.qwebirc.org/qwebirc/

Jetzt müssen wir den Service noch konfigurieren. Dafür kopieren wir die Standardeinstellungen und ändern nur die wichtigsten Details.

$ cd qwebirc
$ cp config.py.example config.py

Benutzt dafür den Terminaleditor eurer Wahl z.B. vim oder nano.

$ nano config.py

Hier einfach die Verbindungsdaten eures IRC-Servers eintragen

# OPTION: IRCSERVER
#         Hostname (or IP address) of IRC server to connect to.
# OPTION: IRCPORT
#         Port of IRC server to connect to.
IRCSERVER, IRCPORT = "irc.ps0ke.de", 2342

Verwendet hier am besten eine Subdomain, vielleicht auch die, unter der euer IRC Server sowieso läuft.

# OPTION: BASE_URL
#         URL that this qwebirc instance will be available at, add the
#         port number if your instance runs on a port other than 80.
BASE_URL = "http://irc.ps0ke.de"

So wie ihr euer Netzwerk auf im ngircd genannt habt.

# OPTION: NETWORK_NAME
#         The name of your IRC network, displayed throughout the
#         application.
NETWORK_NAME = "EosinIRC"

Aus nano kommt ihr mit ^x wieder raus, dann zum speichern bestätigen und fertig. Damit ist die Konfiguration abgeschlossen!

Jetzt noch das ganze "kompilieren".

$ ./compile.py

qwebirc verwendet einen eigenen Webserver, nicht den normalen Apache. Damit dieser Server von außen auch erreichbar ist, müssen wir dem Apache noch sagen, wie er Anfragen durch zu reichen hat. Dafür erstellen wir im DocumentRoot eine Subdomain (hier mal irc.ps0ke.de genannt. Das muss die gleiche sein, die ihr in config.py als BASE_URL eingetragen habt.)

$ cd /var/www/virtual/ps0ke
$ mkdir irc.ps0ke.de
$ cd irc.ps0ke.de
$ nano .htaccess

Hier müsst ihr nun den richtigen Port angeben.

RewriteEngine On
RewriteRule (.*) http://localhost:9090/$1 [P]

Test

Um die Funktionstüchtigkeit zu Testen, starten wir den Server erstmal im Vordergrund.

$ cd ~/qwebirc
$ python run.py --no-daemon

Wenn ihr den Server jetzt unter der von euch eingerichteten Adresse erreichen könnt, habt ihr alles richtig gemacht ;)

Falls ihr Fehlermeldungen bekommt weil Port 9090 schon belegt ist, müsst ihr beim starten des Servers noch mit --port=xxxx einen anderen Port angeben und diesen dann auch in der .htaccess richtig eintragen.

Service Einrichten

Damit der Server auch nach einem crash oder einer downtime wieder automatisch angeht, verwenden wir ihn als Service. Uberspace.de hat dafür deamontools installiert. Falls noch nicht geschehen einfach ein eigenes ~/service Verzeichnis mit dem mitgelieferten Skript erstellen

$ uberspace-setup-svscan

und dann einen einen qwebric Service einrichten

$ uberspace-setup-service qwebirc "~/qwebirc/run.py --no-daemon"

Allerdings produziert der Server so Fehlermeldungen und wird nicht funktionieren. qwebirc erwartet nämlich genauso wie etherpad-lite, in seinem Verzeichnis gestartet zu werden. Vorher natürlich den Service runterfahren.

$ svc -d ~/service/qwebirc
$ cd ~/service/qwebirc
$ nano run

Deshalb ändern wir das run-Skript des Services noch kurz ab und wechseln vor dem Start in das ~/qwebirc Verzeichnis.

# Now let's go!
cd ~/qwebirc

Jetzt den Service wieder hochfahren und alles sollte gehen!

$ svc -u ~/service/qwebirc

Eigenen IRC Server ohne root-Rechte installieren

Info

Eine kurze Anleitung, wie man einen IRC-Server ohne root-Rechte installiert. In diesem Beispiel gehe ich von der Serverkonfiguration von uberspace.de aus, es sollte aber ähnlich auch überall sonst funktionieren.

Installation

Als erstes laden wir ngircd runter, ein kleiner IRC Server, der kaum Konfiguration braucht und einfach funktioniert.

Entweder über den package manager toast

$ toast arm ngircd

oder mit cURL (aktuellste Version raussuchen)

$ curl http://ngircd.barton.de/pub/ngircd/ngircd-19.1.tar.gz -O
$ tar -zxvf ngircd-19.1.tar.gz

Die Variante bei toast hat dabei den Vorteil, dass Toast bereits alle nötigen Ordner und Strukturen perfekt einrichtet, dass ngircd nicht in den normalen, nur für root zugänglichen Pfaden sucht und waltet. Wie man das manuell einstellt weiß ich nicht. Da dies ein uberspace.de Tutorial sein soll, und toast bei uberspace.de standardmäßig installiert ist, kümmere ich mich auch nicht weiter darum.

Einstellungen

Nun richten wie die Konfiguratinsdateien ein.

$ ln -s ~/.toast/pkg/ngircd/v19.1/1/root/etc ~/ngircd
$ cd ngircd
$ cp ngircd.conf ngircd.org.conf
$ chmod 444 ngircd.org.conf

Dies erstellt einen symbolischen Link ngircd in euer Homeverzeichnis und erstellt eine nicht beschreibbare Kopie der Standardkonfigurationsdatei. Nun müsst ihr an der eigentlichen Konfigurationsdatei noch einige Einstellungen vornehmen. Benutzt dafür einen Terminaleditor euerer Wahl wie zum Beispiel vim oder nano.

$ nano ngircd.conf

[Global]
    Name = irc.{username}.{server}.ubserspace.de
    Info = Info Text
    # Globales Serverpasswort. Das ; am Anfang entfernen um es zu aktivieren
    ;Password = {password}

    # Information about the server and the administrator, used by the
    # ADMIN command. Not required by server but by RFC!
    AdminInfo1 = Description
    AdminInfo2 = Location
    AdminEMail = admin@irc.server

    # Bitte einen anderen als den Standard '6667' verwenden
    Ports = {port}

    MotdFile = /home/{username}/ngircd/ngircd.motd

    ServerUID = {username}
    ServerGID = {username}

[Operator]
    Name = {name}
    Password = {password}

Ihr müsst die Werte in den geschweiften Klammern natürlich mit euren Werten ersetzen (ohne Klammern dann). Wenn ihr wollt könnt ihr dann noch einige permanente Channels einrichten. Die Konfiguration dafür sieht so aus:

# ein passwortgeschützter Channel
[Channel]
    Name = #protected
    Topic = a closed channel
    Modes = tnPk
    Key = password

# ein offener Channel
[Channel]
    Name = #open
    Topic = an open channel
    Modes = tnP

Aus nano kommt ihr mit ^x wieder raus, dann zum speichern bestätigen und fertig.

Jetzt noch eine "Message of the Day" Datei anlegen

$ echo "Willkommen auf meinem IRC Server!" > ngircd.motd

Test

Jetzt testen wir die Konfiguration. Das geht mit

$ ngircd -t

Dabei sollten keine Fehler auftreten, wenn doch, nochmal genau die Konfigdatei anschauen! Jetzt testen wir ob der Server überhaupt funktioniert und starten ihn dafür im Vordergrund:

$ ngircd -n

Und von einer anderen Shell versuchen wir in den Server zu "telneten" (schnell tippen!)

$ telnet localhost {port}
USER tester localhost tester :name
NICK tester

Dabei sollten wir eine Antwort vom Server bekommen und in der Shell des Servers sollten wir den Client connecten sehen

Einen Service aufsetzen

Damit der Server auch nach einem crash oder einer downtime wieder automatisch angeht, verwenden wir ihn als Service. Uberspace.de hat dafür deamontools installiert. Falls noch nicht geschehen einfach ein eigenes ~/service Verzeichnis mit dem mitgelieferten Skript erstellen

$ uberspace-setup-svscan

und dann einen einen ngircd Service einrichten

$ uberspace-setup-service ngircd "ngircd -n"

Nun müsst ihr noch ein Portforwarding bei den Leuten von uberspace.de beantragen und fertig :)


The New Ps0ke 2012 Design

Ps0ke

HTML5

CSS3

License

Switched from cc-by-nc-sa to the more leaned-back MIT license. Shortly considered beerware, but it was just too vaporous. Wouldn't mind a beer, though!


Steve Jobs



Ich hab lange nichts zum Tod Steve Jobs' geschrieben. Am Anfang verspürte ich sofort das Bedürfnis etwas aufzuschreiben. Das ganze kam ja so plötzlich und unerwartet. Aber was? Was schreibt man über einen Mann, denn man gar nicht gekannt hat, und trotzdem irgentwie betrauert? Ich wusste es einfach nicht. Außerdem war ich ein bisschen erschlagen vor lauter Nachrichten über Steve, Twitter war tagelang nicht zu benutzen und überall kamen Leute um sich darüber lustig zu machen, weil ich doch so ein Fanboy wäre. Ich brauchte einfach ein wenig Distanz zu der ganzen Sache.

Ich hatte wie durch Zufall ein paar Wochen vorher seine 2005 Stanford Commencement Address angehört und war völlig fasziniert von der Inspiration dieses Menschen. Wer die Rede noch nicht gehöhrt hat: Unbedingt anhören! Das hat nichts mit Apple-Fanboy-tum oder sonstwas zu tun, diese Rede ist einfach ein wunderbares Stück Lebensgeschichte voller Denkanstöße, gerade unter dem Licht, dass er nun wirklich tot ist. Nehmt euch die Viertelstunde.

Was ist denn nun mit Steve? Trauere ich um ihn? nicht wirklich. Ich glaube in dieser Hinsicht bin ich sowieso nicht der sentimentalste Mensch und ich kannte Steve nicht einmal. Außerdem habe ich seine großen Tage gar nicht mirerlebt, wie viele Andere. Für mich war er nie der große Gott, den viele andere Apple-Fans in ihm sahen. Er ist ein grandioses Genie gewesen - keine Frage, aber seine Menschlichen Qualitäten ließen ja Gerüchten zufolge schwerlich zu wünschen übrig. Und ja, er hat nicht so viel gespendet wie Bill Gates, er war ein diktatorischer Tyrann und gewiss kein perfekter Mensch, aber ich finde er hat trotzdem einiges für die Menschheit geleistet.

In wie weit das jetzt tatsächlich sein Werk und nicht das Anderer war, ist sicher fraglich, dennoch glaube ich, dass er mit seiner Ikonischen Figur und seinem strikten, visionären Auftreten Vieles erst möchlich gmeacht hat.

Es ist schade, dass er nicht mehr unter uns weilt!

Was heißt das aber nun für Apple und AAPL? Das die Aktie stürzt, war klar, und ich glaube Apple steht immer noch gut genug dar. Aebr wie sieht die Zukunft des wertvollsten Unternehmens der Welt aus, ohne die weltbekannte Führungsperson? Tim Cook hatte ja schon früher übernommen und ich glaube er wird das Kind auch ganz gut Schaukeln. Steve wollte ja noch weiter als Chairman in beratender Funktion zur Seite stehen, dies fällt jetzt leider weg. Ich glaube aber, er hat sich nach seiner Krebsdiagnose (wenn nicht schon früher) stark darum zu kümmern, ein Team zusammen zu stellen, dass die Firma gut in seinem Sinne weiterführen kann und wird. Außerdem wird er denke ich einen Plan für die Zukunft des Unternehmens gehabt haben und diesen sicher mit der Führungsetage eingehend besprochen.

Ich glaube sogar, dass es für die Firma frischen Wind geben könnte. Mir haben die letzten technischen (Lion, was für ein Mist) und politischen (Samsung-Klage-Kindergarten) Entscheidungen des Konzerns mehr und mehr missfallen und ich könnte mir denken, dass es in Zukunft wieder etwas anders gehen könnte, wenn da nicht mehr nur Steve, sondern vielleicht eher ein Team aus Leuten die Entscheidungen treffen. Alles könnte natürlich auch mit dem krankheitsbedingten Schwinden von Steves Autorität zu tun haben und jetzt stürzt Apple ins Verderben. Wir werden sehen, was die Zukunft bringt.

RIP Steve Jobs.

(Nur so am Rande: Dennis Ritchie, Erfinder der C Programmiersprache und Coautor von Unix ist auch kürzlich verstorben. So langsam geht die erste Generation von genialen IT Köpfen von uns und warscheinlich nicht mehr lange hin, da hat niemand mehr einen C64 als ersten Computer benutzt und sich als Datenreisender durch die Mailboxen fremder Server gehackt oder eine Anzeige wegen eines Datenklos bekommen. Wir müssen dafür Sorgen, dass dieses Gedankengut von Computerhistorie nicht verloren geht. Siehe auch: http://xxx.berlin.ccc.de/.)


2/16