Donnerstag, 14. Januar 2010

MySQL vs. Memcached vs. Memcached + XCache ... Benchmark

Aus aktuellen Anlass hat mich Folgendes interessiert:

Auf einem Userprofil sollen 50 Freunde ausgegeben werden. Jeder User der online ist, soll dabei farblich anders dargestellt werden als die, die offline sind.

Die MySQL Query dazu sieht in etwa so aus: SELECT a.user_id, a.hat_freund, b.username, c.user_id AS online FROM friends AS a JOIN userdaten AS b ON a.hat_freund = b.user_id LEFT JOIN last_action AS c ON a.hat_freund = c.user_id AND c.last_action > UNIX_TIMESTAMP() - 1200 WHERE a.user_id = 111 ORDER BY a.seit DESC ...als "online" gelten also User, die in den letzten 20 Minuten eine Aktion durchgeführt haben.

So eine Query kommt zur Zeit zum Einsatz. Wir sind aber bemüht dem Datenbankserver so viel Last wie möglich zu entziehen und Cachingmethoden einzusetzen.


Verglichen wurde nun:

1. Der Istzustand, die reine MySql-Abfrage und die anschliessende Ausgabe der Daten.

2. Die reine MySql-Abfrage, mit anschliessender Serialisierung und Speicherung als Array in Memcached, sowie die Ausgabe der Daten aus der Datenbank. (Bzw. die soeben serialisierten Daten)

3. Das reine Auslesen des Resultsets aus Memcached und die Ausgabe.

4. Das reine Auslesen des Resultsets aus Memcached und die Ausgabe, mit dem Unterschied, dass in der Ausgabeschleife für jeden einzelnen User per XCache der aktuelle Onlinestatus abgefragt wird.

5. Das reine Auslesen des Resultsets aus Memcached und die Ausgabe, mit dem Unterschied, dass in der Ausgabeschleife für jeden einzelnen User per Memcached der aktuelle Onlinestatus abgefragt wird.

(Memcached läuft lokal. Datenbankserver im gleichen Rack.)

Die Ergebnisse:

1. normal aus datenbank ( 0.0036)

2. aus datenbank, werte in array speichern, in den cache packen und dann ausgeben ( 0.0043)

3. daten aus memcached auslesen und ausgeben ( 0.0010)

4. daten aus memcached auslesen und ausgeben. in der schleife jeden onlinestatus via xcache prüfen ( 0.0012)

5. daten aus memcached auslesen und ausgeben. in der schleife jeden onlinestatus via memcached prüfen ( 0.0046)



Auswertung:

Methode 3 ist hier eindeutig die Schnellste. Mit dieser Variante liesse sich allerdings nicht Anzeigen, wer von den ausgegebenen Usern gerade online ist bzw. wären diese Daten schnell veraltet, so dass der Cache höchstens ein paar Minuten Gültigkeit haben sollte.

Methode 4 sieht da schon vielversprechender aus. Speichert man die Useraktivitäten jeweils auch in einer XCache Variablen, so dauert es bei diesen 50 Durchgängen lediglich 0,0002 Sekunden um alle zu überprüfen. Dadurch kann der Teil, der mit Memcached gecached wird solange gültig sein, bis der User einen neuen Freund hinzugefügt oder gelöscht hat.

Methode 5 ist die Langsamste von allen. Auf diese Methode müsste man zurückgreifen, wenn man mehr als einen Webserver verwendet und XCache als Cachingsystem unbrauchbar wird*. Wenn man aber bedenkt, dass die Hauptaufgabe nicht ist, bedeutend schneller zu sein als MySQL, sondern nur, den Datenbankserver zu entlasten, so ist die Geschwindigkeit immernoch mehr als ausreichend.


Fazit:

Solange man noch nicht darüber nachdenkt, mehr als einen Webserver zu verwenden, sollte Methode 4 verwendet werden, bzw. Methode 3, wenn die Onlinezustände der User nicht angezeigt werden sollen.
Methode 4 geht bei 50 Durchläufen noch in Ordnung. Man sollte es mit den Schleifen jedoch nicht übertreiben. Die benötigte Zeit steigt entsprechend der Anzahl der Durchläufe!

Keine Kommentare: