Schlagwort-Archive: Attribut

Paradigmenwechsel: High Performance Webanwendungen

Ich programmiere schon seit einiger Zeit Webanwendungen. Selten stieß ich dabei auf irgendwelche Performanzgrenzen. Dynamische Webanwendungen sind vom Prinzip her ziemlich simpel gestrickt:

  1. Die Webanwendung erhält eine Anfrage
  2. Die Anwendung holt sich z.B. Daten aus der Datenbank, um die Anfrage beantworten zu können
  3. Die Webanwendung bereitet die Daten auf und gibt sie als HTML aus, die der Browser hübsch dem Benutzer anzeigt

Das gute, alte EVA-Prinzip: Eingabe, Verarbeitung, Ausgabe

Bei Servern, die nicht sonderlich viele Anfragen erhalten, ist das ein bewertes Prinzip. Ein schon etwas in die Jahre gekommener 1-Kern-Webserver konnte beispielsweise locker 5.000 Besucher am Tag bedienen. Nimmt die Anfragefrequenz einer Webseite jedoch weiter zu, muss man sich etwas überlegen. Eine Möglichkeit ist, sich weitere Server anzumieten, um bestimmte Aufgaben auszugliedern – z.B. ein eigener Datenbankserver.

Man kann auch aufs Cachen setzen: Anstatt bei jeder Anfrage die gleichen Berechnungen durchzuführen und auf die DB zuzugreifen, speichert man das Ergebnis oder die auszugebende Seite im Arbeitsspeicher zwischen, so dass sie von dort ohne teure CPU-Zeit und merklich schneller ausgegeben werden kann.

Und wenn diese Maßnahmen nicht mehr ausreichen? Was dann?

Vor genau diesem Problem stand Steve Huffman bei reddit, die monatlich 270 Millionen Anfragen erhielten. In folgendem Vortrag spricht er über die sieben Lehren aus der Zeit bei reddit (eine Transkription gibt es bei ThinkVitamin):

Lessons Learned while at Reddit from Carsonified on Vimeo.

Neben dem „Open Schema“ (oder Entity-Attribute-Value-Model) der Datenbankstruktur finde ich das Zusammenspiel zwischen Anwendung, Cache und Datenbank äußerst interessant. Sämtliche Inhalte von reddit liegen im Cache und sind vorberechnet, sodass die Inhalte ohne Berechnungen angezeigt werden können. Werden Inhalte verändert – etwa Upvote für ein Link, wird der Cache zur Anzeige der höheren Bewertung angelegt, sodass der Benutzer sofort die Rückmeldung bekommt, dass sein Vote erfolgreich war. Des weiteren wird in einer Queue vermerkt, dass der Link einen Vote erhalten hat. Im Hintergrund wird diese Queue abgearbeitet, sodass diese Berechnungen keinen Einfluss auf die Wartezeit des Anwenders haben. Der Vote-Eintrag in der Queue hat z.B. folgende Aktionen zur Folge

  1. Upvote wird in der persistente DB gespeichert, sodass Cache & DB konsistent gehalten werden
  2. Neuberechnung des Caches der betroffenen Übersichten (Listen)
  3. Überarbeitung des Accounts (Cache)
  4. etc.

Fazit

Diese Vorgehensweise der Programmierung einer Webanwendung unterscheidet sich also grundlegend von meiner bisherigen Programmierung: Daten werden redundant gehalten, weil Speicher billig, CPU aber teuer und ein schnell bedienter Kunde (Besucher) wichtig ist. Das Video mit den Einsichten von Steve Huffman in die Abläufe bei reddit stellen für mich einen Paradigmenwechsel dar.

Natürlich: Webanwendungen ohne den Ausblick auf viele Zugriffe, benötigen keine solche Programmierung. Wenn man jedoch auf Skalierbarkeit wert legt, sollte man sich die vorgestellten Lehren besser zu Herzen nehmen…

CSS Attribut Selektoren

Da schreibt man im letzten Artikel etwas über Regexp-Selektoren in JQuery und meint damit ein Problem zwar etwas umständlich, aber elegant gelöst zu habe. Einen Tag später allerdings stellt man fest, dass man den Umweg über JQuery gar nicht hätte gehen müssen, sondern gleich auf Attributbedingte Formate (wie es bei SELFHTML so schön deutsch heißt) hätte setzen müssen.

Ein HTML-Auszug sieht so aus:

[sourcecode lang=“html“]
<div id="posting_1234">
Dies ist ein <a href="http://link.de">Link</a> im Posting.</div>
<div>
Ein anderer <a href="http://andererlink.de">Link</a> in einem anderen DIV.</div>
<!– … –>
<div id="posting_1235">
Dies ist ein <a href="http://link.de">Link</a> im Posting.</div>
<div>
Ein anderer <a href="http://andererlink.de">Link</a> in einem anderen DIV.</div>
[/sourcecode]

Nun will man mit CSS alle Links innerhalb des td-Tags, dessen id mit td_posting_ anfängt, anders darstellen. Das kann man umständlich mit der gestern vorgestellten JQuery-Funktion hinbekommen, aber einfacher und direkter ist es mit den CSS Attribut Selektoren:

[sourcecode lang=“css“]
td[id^="td_posting_"] a:link{
text-decoration: underline;
color: #032846;
}
[/sourcecode]

Das ^-Zeichen hinter id dient dazu festzulegen, dass id mit der angegebenen Zeichenkette beginnen soll. Es wäre ja auch denkbar, dass id mit einer bestimmten Zeichenkette enden soll, denn müsste anstatt ^ ein $ Zeichen benutzt werden:

[sourcecode lang=“css“]
td[id$="ende"] a:link{
text-decoration: underline;
color: #032846;
}
[/sourcecode]

Wenn nur überprüft werden soll, ob eine Zeichenkette irgendwo in der ID vorkommt muss ein *-Zeichen benutzt werden:

[sourcecode lang=“css“]
td[id*="zeichen"] a:link{
text-decoration: underline;
color: #032846;
}
[/sourcecode]

Das deckt zwar viele Anwendungsfälle ab, aber wenn man auf einen komplizierteren regulären Ausdruck angewiesen ist, muss man auf die gestrige JQuery-Funktion zurück greifen.