Spielt man die neueste Version 22 des Android Development Kits (ADK) auf, so kann man mit IDEA IntelliJ seine Projekte nicht mehr kompilieren. Neben dem Problem mit den fehlenden Build-Tools liegt es auch daran, dass einige Sachen nicht mehr dort sind, wo sie noch bei Version 21 waren. Man erhält den Fehler
android-apt-compiler: Cannot run program "/opt/android-sdk-linux_86/platform-tools/aapt": error=2, Datei oder Verzeichnis nicht gefunden (File or directory not found).
Setzt man den Link, so klappt dieser Schritt, aber der nächste scheitert mit
Android Dex: Cannot find file /opt/android-sdk-linux_86/platform-tools/lib/dx.jar
Um beide Probleme zu lösen und wieder kopilieren zu können, wechselt man im ADK Verzeichnis in das Unterverzeichnis platform-tools und setzt zwei Symbolische Links:
ln -s ../build-tools/17.0.0/aapt .
ln -s ../build-tools/17.0.0/lib .
Und schon kann man wieder kompilieren.
Dienstag, 28. Mai 2013
Mittwoch, 8. Mai 2013
Google Maps API v2 im Android Emulator
Google hat seine Maps Anwendung auf die Version 2 aktualisiert. Diese lässt sich nicht so einfach im Android Emulator verwenden, denn dieser wird mit der alten Version ausgeliefert und eine Anwendung, die die neue API verwendet, liefert nur eine Fehlermeldung, dass man Upgraden soll. Es gibt aber einen Trick, wie man Google Maps trotzdem im Emulator zum Laufen bekommt:
Zuerst benötigt man ein AVD mit mindestens API Level 9 (2.3.1), aber ohne Google APIs:
Man kann auch eine höhere Version wählen, aber wie gesagt muss sie ohne Google APIs sein. Google Maps sollte laut Manifest auch mit Version 8 laufen, aber man erhält dann eine Fehlermeldung über ein inkompatibles CPU/ABI Interface.
Als nächstes benötigt man zwei APKs, die man am besten von einem gerooteten Android erhält:
adb -d pull /data/app/com.android.vending-2.apk
adb -d pull /data/app/com.google.android.gms-2.apk
Sollten die Dateien nicht gefunden werden, kann man mit
adb -d shell
shell@android:/$ su
shell@android:/# ls /data/app/
nachsehen, ob sie eventuell doch eine andere Zahl hinten stehen haben. Hier die MD5-Prüfsummen der aktuellen Dateien:
558e12681e333d91f39f688aadbaf6ee com.android.vending-2.apk
2d3daf756852d813cd78366342b33d4d com.google.android.gms-2.apk
Zuerst benötigt man ein AVD mit mindestens API Level 9 (2.3.1), aber ohne Google APIs:
Emulator Einstellungen aus dem Android SDK
Man kann auch eine höhere Version wählen, aber wie gesagt muss sie ohne Google APIs sein. Google Maps sollte laut Manifest auch mit Version 8 laufen, aber man erhält dann eine Fehlermeldung über ein inkompatibles CPU/ABI Interface.
Als nächstes benötigt man zwei APKs, die man am besten von einem gerooteten Android erhält:
adb -d pull /data/app/com.android.vending-2.apk
adb -d pull /data/app/com.google.android.gms-2.apk
Sollten die Dateien nicht gefunden werden, kann man mit
adb -d shell
shell@android:/$ su
shell@android:/# ls /data/app/
nachsehen, ob sie eventuell doch eine andere Zahl hinten stehen haben. Hier die MD5-Prüfsummen der aktuellen Dateien:
558e12681e333d91f39f688aadbaf6ee com.android.vending-2.apk
2d3daf756852d813cd78366342b33d4d com.google.android.gms-2.apk
Jetzt kann man den Emulator starten und die APKs installieren
adb -e install com.android.vending-2.apk
adb -e install com.google.android.gms-2.apk
Google Maps API v2 im Android Emulator
Will man Google Maps direkt verwenden, benotigt man noch com.google.android.apps.maps-1.apk, wobei man hier aufpassen muss, von welchem Gerät man sie bekommt. Die von meinem Nexus 4 läuft nur ab API Level 14 (4.0):
Google Maps im Emulator
Donnerstag, 18. April 2013
Langsame USB Sticks unter Kubuntu beschleunigen
Unter Kubuntu werden USB-Sticks mit der Option "sync" gemountet. Dies hat auf meinem System zur Folge, dass nur mit ca. 150kB/s auf den Stick geschrieben wird. Man erkennt einen solchen Mount, an der Ausgabe des Befehls mount:
/dev/sdc1 on /media/disk type vfat (rw,nosuid,nodev,sync,gid=46,umask=002,uhelper=hal)
/dev/sdc1 on /media/disk type vfat (rw,nosuid,nodev,sync,gid=46,umask=002,uhelper=hal)
Um das Verhalten umzustellen, muss man in der Datei
/etc/halevt/halevt.xml
alle 4 Stellen mit "-o sync" entfernen und danach mit
service halevt restart
die Änderungen aktivieren. Danach werden USB-Sticks so gemountet:
/dev/sdc1 on /media/disk type vfat (rw,nosuid,nodev,gid=46,umask=002,uhelper=hal)
und die Geschwindigkeit ist deutlich höher. Aber Vorsicht! Durch das fehlende Sync wird der Schreib-Cache aktiviert, so dass Schreibzugriffe den Eindruck erwecken, sie währen abgeschlossen, aber in Wirklichkeit schreibt Linux im Hintergrund noch auf den USB-Stick. Deshalb den Stick nach einem Schreibvorgang nicht abziehen, sondern sauber aushängen.
Mittwoch, 3. April 2013
VMware Server 2.0 auf Ubuntu 12.04 LTS installieren
Ich habe (mal wieder) einen Ubuntu 12.04 LTS-Server mit einem VMware Server 2.0.2 versorgt. Dieses Produkt ist seit 2010 eingestellt, funktioniert aber immer noch prächtig. Allerdings ist die Installation unter einem neueren Linux nicht so einfach. Die Vorgehensweise ist für Fedora hier beschrieben. Unter Ubuntu macht man Folgendes:
Zuerst die notwendigen Pakete installieren:
Hierbei alle Werte auf den Vorgaben belassen, aber 'vmware-config.pl' noch nicht starten lassen. In der Datei '/etc/default/grub' diesen Eintrag setzen, um den NMI Watchdog zu deaktivieren:
http://<server>:8222/
oder
https://<server>:8333/
erreicht werden. Anmelden kann man sich mit den Zugangsdaten von Root, sprich Benutzername "root" und dessen Passwort. Hat er noch keines, muss eines mit
http://localhost:8222/
auf den Server zugreifen.
Zuerst die notwendigen Pakete installieren:
apt-get -y install linux-headers-$(uname -r) build-essential patch unp module-assistantDann das Paket VMware-server-2.0.2-203138.x86_64.tar.gz auspacken und installieren:
unp VMware-server-2.0.2-203138.x86_64.tar.gz cd vmware-server-distrib ./vmware-install.pl
Hierbei alle Werte auf den Vorgaben belassen, aber 'vmware-config.pl' noch nicht starten lassen. In der Datei '/etc/default/grub' diesen Eintrag setzen, um den NMI Watchdog zu deaktivieren:
GRUB_CMDLINE_LINUX="nmi_watchdog=0"und die Änderung mit
update-grub2aktivieren und rebooten. Danach diese Befehle eingeben, um VMware auf den neueren Kernel vorzubereiten:
cd ~
m-a prepare
ln -s /usr/src/linux-headers-`uname -r`/include/generated/autoconf.h /usr/src/linux-headers-`uname -r`/include/linux/autoconf.h ln -s /usr/src/linux-headers-`uname -r`/include/generated/utsrelease.h /usr/src/linux-headers-`uname -r`/include/linux/utsrelease.h
Die obigen Befehle muss man auch eingeben, nachdem ein neuer Kernel installiert wurde.
wget http://www.jlbond.com/downloads/vmware-server-2.0.2-203138-linux_2.6.42+.tar.bz2 tar xvjf vmware-server-2.0.2-203138-linux_2.6.42+.tar.bz2 patch -d /usr/bin -p0 < vmware-config.pl.patch pushd /usr/lib/vmware/modules/source mkdir backups; cp -a *.tar backups/ mkdir working; ls *.tar | xargs -n 1 tar -C working/ -xf pushd working patch -p1 < ~/vmware-server-2.0.2-203138-linux-2.6.42.patch
tar cf ../vmci.tar vmci-only tar cf ../vmmon.tar vmmon-only tar cf ../vmnet.tar vmnet-only tar cf ../vsock.tar vsock-only popd; rm -rf working/ ;popd pushd /usr/lib/vmware/lib; mv libxml2.so.2 SKIP-libxml2.so.2 ; popdDanach kann VMware konfiguriert werden
vmware-config.plHierzu benötigt man einen gültigen Lizenzschlüssel. Er beschwert sich auch über die Version des GCC Compilers - hier einfach die Frage, ob der Compiler ok ist, mit "yes" beantworten. Nach dem Ende des Skriptes läuft der Server schon und kann unter
http://<server>:8222/
oder
https://<server>:8333/
erreicht werden. Anmelden kann man sich mit den Zugangsdaten von Root, sprich Benutzername "root" und dessen Passwort. Hat er noch keines, muss eines mit
passwd rootvergeben werden. Sinnvollerweise erlaubt man als erstes einem anderen die Administration und entfernt dann wieder das Passwort für root beispielsweise mit
passwd -l rootStandardmäßig sind die Ports 902/TCP, 8222/TCP und 8333/TCP für alle offen. Sollte der Server am Internet betrieben werden, dann am besten über die Firewall sperren, z.B. so alle Zugriffe über eth0:
iptables -A INPUT -i eth0 -p tcp --dport 902 -j DROP iptables -A INPUT -i eth0 -p tcp --dport 8222 -j DROP iptables -A INPUT -i eth0 -p tcp --dport 8333 -j DROPWill man dann selbst zugreifen kann man beispielsweise einen SSH-Tunnel aufbauen:
ssh -L 8222:localhost:8222 <server>dann kann man über
http://localhost:8222/
auf den Server zugreifen.
Freitag, 8. März 2013
Bigdata, NoSQL, was ist das überhaupt? Intermezzo
Ich hab eine Frage bekommen: braucht man NoSQL aktuell in der Wirtschaft wirklich?
BigData und NoSQL sind die logischen Ergebnisse der aktuellen Entwicklung: die Datenmengen werden immer größer, weil immer mehr Prozesse technisiert werden (ELSTER, SEPA etc.), immer mehr Daten generiert werden (Megapixel, FullHD, 3D, etc.) und immer mehr Ereignisse elektronisch erfasst werden (Smart Meter, Bio-Monitoring, Web-Logging, etc.). Das Problem ist, dass die Speichertechnologie hierbei nicht mitkommt. Ein Speichermedium zeichnet sich zur 2 Eigenschaften aus:
- Kapazität
- IO-Leistung, aufgeteilt in
a. Anfragen pro Sekunde
b. Durchsatz pro Sekunde
Während 1. in den letzten 15 Jahren um den Faktor 4.000 gestiegen ist, hat sich 2. nur um den Faktor 10 verbessert. Die Erfahrung zeigt, dass Festplatten immer zu 80-90% voll sind, unabhängig von der Größe (stimmt vom meiner ersten 20MB Festplatte bis zu meinen heutigen 3 TB). Dies bedeutet, dass wir heutzutage 400 mal langsamer sind, als vor 15 Jahren, wenn wir alle unsere Daten lesen wollen. Deshalb ist es unklug zu glauben, man kann die gleiche Vorgehensweise, wie vor 15 Jahren verwenden. NoSQL sorgt dafür, dass man weniger Anfragen pro Sekunde benötigt, um die gleiche Leistung zu erzielen, während die BigData-Produkte den Durchsatz pro Sekunde durch massive Parallelisierung erhöhen.
Berechtigt ist die Frage natürlich, was das ganze der Wirtschaft bringt. Genau die gleiche Frage wurde vor 70 Jahren gestellt, als die ersten Rechenmaschinen aufkamen. Und es ist klar, "a fool with a tool is still a fool". NoSQL macht Dinge wie eBay, Facebook, Google erst möglich. BigData schafft es, zeitnah Informationen zu liefern. Ich weiß von einem Beispiel eines großen Telefonanbieters, bei dem in einer Vorstandssitzung eine Frage aufkam. Diese konnte die Technik mit klassischem SQL nach 4 Tagen beantworten. Nach der Umstellung auf BigData konnten ähnliche Fragen in 5 Minuten beantwortet werden. Bei Scooter Attack hatte ich ähnliche Erfolge erzielen können, dort aber von 2 Minuten runter auf 5 Sekunden. Und Speicherkapazität von 9 GB auf 0,5 GB. Es geht auch gar nicht so sehr um die Frage, ob NoSQL/BigData besser oder schlechter ist, als klassisches SQL. Es geht vielmehr darum, welches für was am besten geeignet ist. Früher gab es nur SQL; jetzt kann man zwischen zwei Möglichkeiten wählen, die beide ihre Stärken und Schwächen haben. Was man daraus macht, das bleibt einem immer noch selbst überlassen.
Sonntag, 24. Februar 2013
Bigdata, NoSQL, was ist das überhaupt? Teil 2: ACID vs NoSQL
Sobald man auf einer Datenbank mehrere Befehle gleichzeitig ausführen will, beispielsweise von mehreren Benutzern, muss man sich Gedanken über die Koordinierung der Zugriffe machen. Glücklicherweise haben dies bereits viele schlaue Leute gemacht und deshalb hat man dieses Thema vor einigen Jahren als erledigt angesehen: ACID lautet die Lösung, die so allgegenwärtig ist, dass man sich lange nicht vorstellen konnte, wie eine Datenbank ohne ACID überhaupt benutzbar sein soll. ACID beschreibt 4 Anforderungen an eine Datenbank, die einen geordneten Betrieb beim gleichzeitigen Zugriff sicher stellen. Wo Licht ist, ist auch Schatten und so hat ACID nicht nur Vorteile, sondern es bremst in der Praxis Datenbanken aus. NoSQL bricht mit diesen Anforderungen und kann so deutlich höhere Leistungszahlen erreichen. Was ist ACID, warum bremst es die Datenbank aus und wie schafft eine NoSQL-Datenbank es, ohne ACID einen geordneten Zugriff sicher zu stellen? Um diese Fragen geht es in den folgenden Absätzen.
Um diese Funktionalität sicher zu stellen, muss eine Datenbank mit so genannten Sperren arbeiten: Datensätze oder ganze Tabellen werden gegen den Zugriff von anderen Transaktionen gesperrt. Eine triviale Implementation würde im oben genannten Umbuchungs-Beispiel die Datensätze beider Konten sperren, bis die Transaktion abgeschlossen ist, damit bei einem Abbruch der Transaktion keine weitere Transaktion mit einem falschen Kontostand arbeitet. Diese Sperren sind "teuer", denn bei jedem Zugriff muss geprüft werden, ob eine andere Transaktion auf diesen Datensatz zugreift. Noch teurer wird es, wenn die Datenbank auf einem Cluster mit mehreren Servern ausgeführt wird, was auch der Hauptgrund ist, dass klassiche Datenbankcluster selten aus mehr als einer Handvoll Servern bestehen. Auch besteht die Gefahr von so genannten Deadlocks: zwei Transaktionen behindern sich gegenseitig, indem beide einen Teil der Datensätze gesperrt haben und auf die jeweils anderen Datensätze zugreifen möchten.
NoSQL-Datenbanken bieten auch atomare Zugriffe an, jedoch sind die Möglichkeiten für Sperren stark eingeschränkt. So kann eine Sperre beispielsweise nur einen einzigen Datensatz umfassen und nicht mehrere oder gar Datensätze in mehreren Tabellen. Damit löst man zwar das Problem der verteilten Sperren und kann problemlos auf Cluster mit hunderten von Servern skalieren, für den Programmierer erhöht sich aber der Aufwand. In der Praxis ist dies aber auch bei klassischen Datenbanken der Fall, denn wenn Performanceprobleme auftreten, sind Transaktionen einer der ersten Punkte, die optimiert - sprich weg gelassen - werden. So gesehen machen NoSQL-Datenbanken nur das, was man bei Hochleistungsanwendungen sowieso schon immer gemacht hat: möglichst wenig Transaktionen.
Constraints verhindern sehr sicher, dass falsche Befehle die Datenbank in einen inkonsistenten Zustand bringen. Sie bedeutet aber auch einen Mehraufwand für die Datenbank, denn bei jedem Einfügen einer Rechnung muss geprüft werden, ob die Kundennummer existiert. Sofern der Programmcode korrekt ist, ist eine solche Prüfung immer erfolgreich. Dies bewegt Datenbankadministratoren dazu, bei Performanceproblemen der Datenbank die Constraints einfach zu entfernen, um die überflüssigen Überprüfungen zu vermeiden. Genau dies ist auch bei NoSQL-Datenbanken der Fall, die auf Constraints größtenteils verzichten. Hierbei nimmt man bewusst in Kauf, dass sich eine Datenbank kurzzeitig in einem inkonsistenten Zustand befindet: soll beispielsweise eine Rechnung mit ihren Rechnungspositionen gespeichert werden, so legt man zuerst die Positionen ab und dann erst den Rechnungskopf. Damit erreicht man, dass bei einer Navigation über den Rechnungskopf die dazu gehörenden Positionen immer vorhanden sind. Geht man dagegen über die Positionen und sucht den Rechnungskopf, so kann es sein, dass dieser (noch) nicht existiert. Dies muss der Programmierer beachten, wenn mit NoSQL gearbeitet wird. Und ebenso der Programmierer einer klassischen SQL-Datenbank, wenn die Constrainst aus Gründen der Geschwindigkeit entfernt wurden.
Bei NoSQL-Datenbanken umfassen Transaktionen immer nur einen Datensatz, so dass die angesprochenden Probleme gar nicht erst auftreten können und entsprechend die maximale Geschwindigkeit erreicht wird.
NoSQL garantiert auch, dass Daten nach dem Ende einer Transaktion ausfallsicher geschrieben sind. Es wird jedoch nicht garantiert, dass alle Knoten sofort über die Änderung informiert werden, sondern nur, dass sie irgendwann die Änderung erhalten werden. Man spricht von "eventually consistent", was nicht "eventuell" sondern "schlussendlich" bedeutet. In der Regel handelt es hier um Sekundenbruchteile, bis alle Knoten die Änderung erhalten haben. Damit ist ein Betrieb auch rechnenzentrumsübergreifend möglich, was die Ausfallsicherheit erhöht. Der Programmierer muss jedoch beachten, dass Änderungen nicht sofort für alle sichtbar sind. Dass dies von den Kunden akzeptiert wird, sieht man an Meldungen großer Internetseiten in der Art "es kann einige Minuten dauern, bis Ihre Änderungen in Ihrem Kundenkonto sichtbar werden".
A - Atomic
Das A in ACID steht für Atomic, womit gemeint ist, dass jede Operation auf der Datenbank unteilbar ist, eben "atomar". Dies bedeutet, dass jeder Befehl entweder komplett ausgeführt wird oder komplett nicht ausgeführt wird. Aktualisiert man beispielsweise alle Datensätze, so sind entweder alle aktualisiert oder keiner. Über so genannte Transaktionen gilt dies auch für eine Folge von Befehlen. Dies ist wichtig für Umbuchungen, beispielsweise von einem Konto auf ein anderes: der erste Befehl verringert den Kontostand des Ausgangskontos und der zweite Befehl erhöht den des Zielkontos. Es wäre fatal, wenn nur der erste Befehl ausgeführt wird und nicht der zweite, denn dann würden sich Kunden schnell beschweren.Um diese Funktionalität sicher zu stellen, muss eine Datenbank mit so genannten Sperren arbeiten: Datensätze oder ganze Tabellen werden gegen den Zugriff von anderen Transaktionen gesperrt. Eine triviale Implementation würde im oben genannten Umbuchungs-Beispiel die Datensätze beider Konten sperren, bis die Transaktion abgeschlossen ist, damit bei einem Abbruch der Transaktion keine weitere Transaktion mit einem falschen Kontostand arbeitet. Diese Sperren sind "teuer", denn bei jedem Zugriff muss geprüft werden, ob eine andere Transaktion auf diesen Datensatz zugreift. Noch teurer wird es, wenn die Datenbank auf einem Cluster mit mehreren Servern ausgeführt wird, was auch der Hauptgrund ist, dass klassiche Datenbankcluster selten aus mehr als einer Handvoll Servern bestehen. Auch besteht die Gefahr von so genannten Deadlocks: zwei Transaktionen behindern sich gegenseitig, indem beide einen Teil der Datensätze gesperrt haben und auf die jeweils anderen Datensätze zugreifen möchten.
NoSQL-Datenbanken bieten auch atomare Zugriffe an, jedoch sind die Möglichkeiten für Sperren stark eingeschränkt. So kann eine Sperre beispielsweise nur einen einzigen Datensatz umfassen und nicht mehrere oder gar Datensätze in mehreren Tabellen. Damit löst man zwar das Problem der verteilten Sperren und kann problemlos auf Cluster mit hunderten von Servern skalieren, für den Programmierer erhöht sich aber der Aufwand. In der Praxis ist dies aber auch bei klassischen Datenbanken der Fall, denn wenn Performanceprobleme auftreten, sind Transaktionen einer der ersten Punkte, die optimiert - sprich weg gelassen - werden. So gesehen machen NoSQL-Datenbanken nur das, was man bei Hochleistungsanwendungen sowieso schon immer gemacht hat: möglichst wenig Transaktionen.
C - Consistent
Programmierer wünschen sich, dass Datenbanken konsistent sind, denn mit inkonsistenten Daten besteht die Gefahr von falschen Ergebnissen. Konsistenz bei Datenbanken wird mit so genannten Constraints - auf deutsch "Einschränkungen" - sichergestellt. Diese definieren Anforderungen an Datensätze und das Datenbanksystem verhindert, dass die Tabellen in einen Zustand gerät, der Constraints verletzt. Ein Beispiel für eine solche Einschränkung ist "jede in einer Rechnung angegebene Kundennummer gehört zu einem Kundendatensatz". Gibt es also einen Rechnungsdatensatz mit der Kundennummer 1234, so muss es auch einen Kunden mit dieser Nummer in der Datenbank geben. Soll der Kunde gelöscht werden, so müssen zuerst alle seine Rechnungen entfernt werden, sonst verweigert die Datenbank das Löschen des Kunden.Constraints verhindern sehr sicher, dass falsche Befehle die Datenbank in einen inkonsistenten Zustand bringen. Sie bedeutet aber auch einen Mehraufwand für die Datenbank, denn bei jedem Einfügen einer Rechnung muss geprüft werden, ob die Kundennummer existiert. Sofern der Programmcode korrekt ist, ist eine solche Prüfung immer erfolgreich. Dies bewegt Datenbankadministratoren dazu, bei Performanceproblemen der Datenbank die Constraints einfach zu entfernen, um die überflüssigen Überprüfungen zu vermeiden. Genau dies ist auch bei NoSQL-Datenbanken der Fall, die auf Constraints größtenteils verzichten. Hierbei nimmt man bewusst in Kauf, dass sich eine Datenbank kurzzeitig in einem inkonsistenten Zustand befindet: soll beispielsweise eine Rechnung mit ihren Rechnungspositionen gespeichert werden, so legt man zuerst die Positionen ab und dann erst den Rechnungskopf. Damit erreicht man, dass bei einer Navigation über den Rechnungskopf die dazu gehörenden Positionen immer vorhanden sind. Geht man dagegen über die Positionen und sucht den Rechnungskopf, so kann es sein, dass dieser (noch) nicht existiert. Dies muss der Programmierer beachten, wenn mit NoSQL gearbeitet wird. Und ebenso der Programmierer einer klassischen SQL-Datenbank, wenn die Constrainst aus Gründen der Geschwindigkeit entfernt wurden.
I - Independent
Mehrere gleichzeitig laufende Transaktionen sollten sich nicht gegenseitig beeinflussen. In der Praxis wird diese Anforderung meist etwas gelockert. Eine Frage ist, ob Änderungen innerhalb einer Transaktion für andere Transaktionen sichtbar sein sollen, bevor die Transaktion abgeschlossen ist. Dies kann zur Folge haben, dass Transaktionen Datensätze sehen, die niemals wirklich in geschrieben werden, da die entsprechende Transaktion abgebrochen wurde - der Fachmann spricht von "Phantom Reads". Wenn im Anwendungsfall Transaktionen sehr selten abgebrochen werden und Phantom Reads toleriert werden können, kann die Transaktions-Isolation entsprechend reduziert werden, was zu mehr Geschwindigkeit führt.Bei NoSQL-Datenbanken umfassen Transaktionen immer nur einen Datensatz, so dass die angesprochenden Probleme gar nicht erst auftreten können und entsprechend die maximale Geschwindigkeit erreicht wird.
D - Durable
Wenn die Datenbank dem Programm signalisiert, dass eine Transaktion abgeschlossen ist, dann kann man den Stecker ziehen und sich sicher sein, dass nach einem Neustart die Änderungen der Transaktion vorhanden sind. Ebenso, dass das Lesen nach dem Ende der Transaktion die geänderten Daten zurückliefert. In einem Cluster bedeutet dies, dass alle Knoten (zumindest diejenigen mit Kontakt zu Clients) über die Änderung informiert sein müssen, bevor die Datenbank den Erfolg zurückmelden darf, damit auch bei einer Verbindung zu eine anderen Knoten die gleichen Daten zurückgeliefert werden. Dies führt zu Verzögerungen nach Abschluss der Transaktion, so dass der Client weniger Transaktionen pro Sekunde ausführen kann. Auch gibt es sehr hohe Anforderungen an die Übertragungsgeschwindigkeit und Latenz zwischen den einzelnen Datenbankknoten, so dass ein über mehrere Rechenzentren verteilten Betrieb in der Regel nicht machbar ist.NoSQL garantiert auch, dass Daten nach dem Ende einer Transaktion ausfallsicher geschrieben sind. Es wird jedoch nicht garantiert, dass alle Knoten sofort über die Änderung informiert werden, sondern nur, dass sie irgendwann die Änderung erhalten werden. Man spricht von "eventually consistent", was nicht "eventuell" sondern "schlussendlich" bedeutet. In der Regel handelt es hier um Sekundenbruchteile, bis alle Knoten die Änderung erhalten haben. Damit ist ein Betrieb auch rechnenzentrumsübergreifend möglich, was die Ausfallsicherheit erhöht. Der Programmierer muss jedoch beachten, dass Änderungen nicht sofort für alle sichtbar sind. Dass dies von den Kunden akzeptiert wird, sieht man an Meldungen großer Internetseiten in der Art "es kann einige Minuten dauern, bis Ihre Änderungen in Ihrem Kundenkonto sichtbar werden".
Fazit
NoSQL macht bei den ACID-Kriterien zum Großteil Dinge, die bei klassischen Datenbanken zum Standardrepertoire der Geschwindigkeitsverbesserung gehören. Da hiermit Garantien verwässert werden, bedeutet dies generell einen höheren Aufwand für den Programmierer. Da die Prüfungen aber nicht nur deaktiviert werden, sondern gar nicht vorhanden sind, bieten NoSQL-Datenbanken eine deutlich höhere Geschwindigkeit, als herkömmliche SQL-Datenbanken. Denn wie lautet ein Bekannter Ausspruch eines Google-Entwicklers: kein Code ist schneller als der, der nicht ausgeführt wird.Bigdata, NoSQL, was ist das überhaupt? Teil 1: KeyValueStores
Bis vor nicht allzu langer Zeit war mit "Datenbank" meist eine relationale Datenbank gemeint, die über SQL angesprochen werden konnte, wie beispielsweise MySQL, PostgreSQL oder Microsofts SQL-Server, um nur einige zu nennen. SQL ist das "Esperanto der Datenbanken", wodurch es für Software-Entwickler leichter ist, mehrere Datenbanken zu unterstützen, da alle die gleiche Sprache sprechen. Eine SQL-Datenbank hat Tabellen, ähnlich denen einer Tabellenkalkulation: die Datensätze sind die Zeilen und die Felder der Datensätze sind die Spalten. Jeder Datensatz hat die gleichen Felder, beispielsweise "Vorname" und "Nachname" in einer Kundentabelle und jedes Feld hat einen Typ, der für alle Datensätze gleich ist. Diese Art der Datenspeicherung ist für Menschen sehr leicht verständlich, da es die natürliche Art ist, wie man auch auf einem Blatt Papier eine Liste von Personen anlegen würde.
Diese Speicherung in Tabellen mit festen Feldern hat leider einen Nachteil: wenn man ein Feld hinzufügen möchte, muss üblicherweise die Tabelle kopieren, um bei jedem Datensatz Platz für das neue Feld zu schaffen; genauso beim Ändern oder Löschen eines Feldes. Während eines solchen Kopiervorganges ist die Datenbank nicht (oder zumindest nicht voll) verfügbar. Bei wenigen Datensätzen oder eine hausinternen Datenbank, die nachts nicht genutzt wird, sind solche Ausfälle kein Problem. Ist man ein Internet-Startup mit einer guten Idee, so ärgert dieses Problem jedoch gleich mehrfach: zum einen muss man 24/7 verfügbar sein, da das Internet nicht schläft. Dazu kommt eine oftmals rapide steigende Zahl an Nutzern und damit viele Datensätze. Als Startup entwickelt man noch kräftig an der Software, so dass die Struktur sehr oft geändert werden muss. Hierzu ein Beispiel: die besten Android Apps haben mehr als 100 Millionen Downloads. Legt man für jeden dieser Nutzer ein Kundenkonto an und jedes Kundenkonto belegt 1 Kilobyte an Speicher, so benötigt man 100GB Speicherplatz. Nicht sonderlich viel in der heutigen Zeit. Das Problem ist, dass eine aktuelle Festplatte im Idealfall etwa 15 Minuten benötigt, um diese Datenmenge zu lesen oder zu schreiben. Ein RAID-System ist natürlich entsprechend schneller, aber auch da wird man kaum unter eine Minute kommen.
In der Praxis sind die Zeiten bedingt durch die Umrechnung und Neu-Indizierung eher ein gutes Stück länger. Hier kommt das erste NoSQL ins Spiel: Key-Value-Stores (KVS), auf Deutsch: Speicherung von Schlüssel-Wert-Paaren. Statt jedem Datensatz eine starre Anzahl an Feldern zuzuordnen, legt man eine variable Anzahl solcher Schlüssel-Wert-Paare ab. Also beispielsweise "Vorname = Kurt", "Nachname = Huwig" usw. Natürlich belegt dies mehr Speicherplatz, da die Feldnamen in jedem Datensatz nochmal drin stehen. Wie man oben gesehen hat, ist Speicherplatz aber nicht das Problem. Will man bei einem KVS ein neues Feld hinzufügen, braucht man an den bestehenden Daten nichts zu ändern sondern legt bei neuen Datensätzen einfach das neue Feld an. Oder fügt alten Datensätze das Feld im laufenden Betrieb hinzu und sobald man damit fertig ist, kann es genutzt werden. Ein Nachteil soll aber verschwiegen werden: bei SQL-Datenbanken ist es möglich, Datenbankfelder als notwendig zu definieren, so dass keine Datensätze angelegt werden können, in denen das Feld nicht gesetzt ist. Dies ist bei KVS nicht möglich, aber in der Praxis auch kein Problem: wurde früher vom Client direkt auf die Datenbank zugegriffen (Two-Tier) wird heute in der Regel eine Middleware eingesetzt, die alle Zugriffe des Clients bearbeitet und selbst mit der Datenbank spricht (Three-Tier oder Multi-Tier). Damit ist es leicht möglich, diese Konsistenzprüfung von der Datenbank in den Middle-Tier zu verlegen und hat damit mehr Möglichkeiten der Prüfung, als herkömmliche SQL-Datenbanken anbieten.
Abonnieren
Posts (Atom)