Derzeit ist ja NoSQL im Trend, und das wohl zu Recht. Bei vielen Projekten ist eine relationale Datenbank einfach nur Overkill, da oft stupide immer wieder die gleichen Datensätze abgefragt werden und die Möglichkeiten einer relationen DB nur zu einem Bruchteil verwendet bzw. benötigt werden. Aus diesem Grunde haben wir uns einmal intensiver mit den aktuellen NoSQL-Engines beschäftigt und sind zu überraschenden Ergebnissen gekommen.
Als Testumgebung diente eine VMware VM bzw. anschließend ein Dedizierter-Server (Quad-Opteron, 8 GB RAM), um noch besser die echte Performance messen zu können. Wir haben mit einem kleinen Java-Programm immer mehrere 100k bzw. millionen Datensätze (je nachdem, was so reinpasste

) geschrieben und wieder ausgelesen, jeweils mit nur einem Key in Form eines Integer. Ein kompletter "Datensatz" bestand aus jeweils so um die 200 Byte in Form eines Zufalls-String. Die Tests wurden auf zwei via GBit zum Server verbundenen MacBook's Pro durchgeführt. Die Reads wurden meist mit 30-40 Threads zu je 500-800 Datensätzen ausgeführt, um halbwegs eine echte Situation mit mehreren Clients nachzustellen.
Als erstes war
Cassandra dran, wovon wir uns viel erhofften. Denn Digg, Facebook, Twitter und
Andere können ja nicht irren. Oder etwa doch? Ehrlichgesagt waren unsere Tests mehr als ernüchternd. Sowohl mit Java, PERL und auch PHP schafften wir nicht mehr als 100 Writes pro Sekunde, egal wie wir es anstellten (batched, einzeln). Auf dem Server selbst gab es komischerweise keinerlei CPU- oder I/O-Last. Wir machen daher das
Thrift-Interface für die schlechte Performance verantwortlich. Thrift ist ein Code-Generator, der auf Wunsch aus einem Template für viele Programmiersprachen API's baut. Das ist zwar sehr angenehm und schick, aber offenbar langsam. Abschließend konnten wir allerdings nicht gänzlich klären, warum Cassandra bei uns versagt hat. Auch die durchaus freundliche Mailingliste konnte auf unsere
Anfrage hin das Problem nicht klären. Fakt scheint, dass Cassandra erst bei vielen Clients aufblüht. Wenn man von 100 Clients aus tatsächlich jeweils 100 Writes/sek schafft, sieht das Ergebnis schon wieder besser aus. Erwähnen sollte man vielleicht an dieser Stelle auch noch, dass Cassandra und Thrift relativ schlecht dokumentiert sind, was sicher auch an den Versionen 0.x liegt. Die Reads haben wir aufgrund des ernüchternden Write-Performance gar nicht erst getestet, sorry..
Memcached darf in dieser Runde natürlich nicht fehlen, zumal wir damit bereits gute Erfahrungen im Produktiveinsatz gemacht haben. Unser Java-Testprogramm schaffte hier 1000 Writes/sek und ganz ordentliche 10k Reads/sek. Was bei Memcached auffällt, ist die nahezu nicht vorhandene CPU-Auslastung, egal wie sehr man den Server quält. Diese Tatsache und auch Erfahrungen aus der Praxis zeigen, dass sehr viele Connects und gleichzeitige Abfragen wunderbar schnell beantwortet werden könnne. Problematisch ist natürlich, dass kein Backup vorliegt, wenn der Server abstirbt. Es gibt zwar einige
Tools/Scripte, die einen Dump erlauben, getestet haben wie dies allerdings nicht.
Diese Lücke füllt
MemcacheDB - hier werden die Daten zusätzlich zu der Kopie im Speicher noch in eine
Berkeley DB geschrieben. Leider ist das letzte MemcacheDB-Release von 2008. Ob das nun daran liegt, dass die Software perfekt funktioniert oder ob die Entwickler keine Lust mehr haben, kann man nur erahnen. Wir mussten zumindest Berkeley DB 4.7 von Hand kompilieren, da die MemcacheDB nur damit zusammenarbeiten wollte. Aktuelle wäre Berkeley DB 4.8. Die Ergebnisse waren nicht direkt schlecht, wir schafften 600 Writes/sek und um die 5k Reads. Da die Daten eben noch sicher auf Platte geschrieben werden, kann die Performance nicht mit Memcached mithalten. Natürlich merkt man auch die Arbeit auf der Platte entsprechend an der Serverlast, die Werte waren aber im Rahmen.
Redis war ebenfalls einen Blick wert und beeindruckt mit dem wohl größten
Funktionsumfang. Die
Command Reference liest sich beeindruckend, teilweise schon fast wie die eines "echten" Datenbankservers. Ebenso beeindruckend sind eigentlich auch die Testergebnisse: 30k Writes und Reads pro Sekunde. Allerdings war die CPU hier auch ziemlich gut ausgelastet, wenn man viele gleichzeitige Zugriffe simuliert. In der Config kann man bestimmte Intervalle festlegen, in denen ein Dump auf die Platte geschrieben wird, z.B. "alle 300 Sekunden, wenn sich in dieser Zeit mindestens 1000 Datensätze verändert haben". Das macht einen Restore im Fehlerfall problemlos möglich.
Zu guter Letzt kam ein von einem netten Kollegen geschriebenes
Java-Programm zum Einsatz. Es lauscht auf einem Port und nimmt dort Anfragen entgegen, nachdem es vorher über einen anderen Port mit Daten gefüttert wurde. Die Daten werden im Speicher in Form einer Hasttable gehalten. Als Key dient auch hier die Integer-ID. Der Speed ist wahrlich beeindruckend. 330k Writes pro Sekunde sind hier möglich (im Test wurden 5mio Zeilen in ca. 15 Sekunden geschrieben!!). Auch der lesende Zugriff kann sich sehen lassen, hier werden nahezu die gleichen Werte erreicht. Damit hätten wir auf keinen Fall gerechnet, aber wahrscheinlich ist eine minimale Lösung manchmal einfach die Beste

. Mal schauen, wie sich die eigene Lösung in weiteren Lasttests beweist - vielleicht kommt sie ja bis zum Produktiveinsatz. Von der Geschwindigkeit und Anpassbarkeit her ist die eigene Lösung zumindest bisher die erste Wahl. Auch einen Dump z.B. einmal pro Stunde auf die Platte zu schreiben ist damit einfach möglich, ebenso das Restore aus diesem Dump. Achja, die CPU-Auslastung hält sich erstaunlicherweise ebenfalls in Grenzen. Einzelne Ausschläge an nahezu 100%, sonst eher moderat. Java wurde übrigens jeweils mit -Xmx7168m gestartet, konnte sich also bis zu 7 GByte RAM abzapfen.
Falls ihr Erfahrungen mit NoSQL habt, freuen wir uns über Kommentare. Außerdem möchten wir zu bedenken geben, dass unsere Tests natürlich nicht repräsentativ sind. Nicht immer kommt es nur auf schnelle Writes und Reads an. Diesmal aber eben schon ..
NoSQL-Vergleich bei uns im Admin-Blog: http://bit.ly/c0B9Pc
Aufgenommen: Mar 24, 22:30
NoSQL Testing: Cassandra, Memcached, Redis und "einfach nur" Java http://ff.im/-i3MYI
Aufgenommen: Mar 24, 23:09
Aufgenommen: Mar 25, 05:38
NoSQL Testing: Cassandra, Memcached, Redis und "einfach nur" Java - Administrator's Blog: http://www.rackspaceclou... http://bit.ly/dvePRK
Aufgenommen: Sep 06, 10:32