Was ist eigentlich Software Defined Storage?

Cloud Computing boomt und beschert auch dem Konzept des Software Defined Storage (SDS) ordentlich Auftrieb. Worum geht es dabei eigentlich und warum ist SDS interessant? Auf Golem.de erklärt Martin Loschwitz das am Beispiel der SDS-Lösung Ceph.

Software Defined Storage (SDS) hat in Folge der Beliebtheit des Cloud Computings zu großer Verbreitung gefunden: Wenn Unternehmen heute Cloud-Setups planen, spielt SDS dabei fast immer eine Rolle. Der Begriff ist für viele aber bis heute eher abstrakt. Was genau ist damit eigentlich gemeint, und was sind die Unterschiede zwischen SDS-Setups und klassischen Storage-Appliances, etwa den Storage Area Networks (SAN) der etablierten Hersteller? Dieser Artikel erklärt die Grundlagen und erläutert am Beispiel von Ceph, wie SDS-Theorie zur Praxis wird.

Skalierbarkeit ist wichtig

Cloud-Setups sind immer Setups, bei denen Skalierbarkeit eine große Rolle spielt. Schließlich soll die Cloud zusammen mit dem Kundenstamm wachsen. Und ein neuer Kunde, der ad hoc etliche Terabyte Plattenplatz braucht, soll nicht zu einem anderen Anbieter wechseln, weil man selbst diesen Plattenplatz nicht schnell genug anbieten kann. Stattdessen muss sich das eigene Storage-System quasi augenblicklich um die benötigte Kapazität erweitern lassen.

Die moderne IT unterscheidet zwei Arten von Skalierbarkeit: Das Skalieren in die Höhe und das Skalieren in die Breite. Ersteres steckt in vorhandene Systeme Hardware nach; zweiteres ergänzt vorhandene Systeme um weitere Hardware und verteilt so die Last auf mehr Systeme insgesamt.

Das Skalieren in die Höhe funktioniert nur solange, bis das Zielsystem sich nicht mehr um zusätzliche Ressourcen erweitern lässt. Bei Servern etwa ist die Menge an möglichem RAM durch die Anzahl der Steckplätze einerseits und durch die maximale Kapazität der nutzbaren RAM-Riegel andererseits begrenzt. Ähnlich ist es bei klassischen Storage-Appliances, in die sich nur eine bestimmte Zahl von Festplatten hineinstecken lassen. Ist das Gehäuse voll, muss ein zweites Gerät her. Bei Admins sorgt das regelmäßig für Zähneknirschen, weil dann mehr als ein zu administrierendes Gerät existiert.

Das Skalieren in die Breite hat die genannten Probleme hingegen üblicherweise nicht: Die Zahl zu installierender Server ist höchstens durch Faktoren wie Platz im Rechenzentrum oder Strom eingeschränkt, nicht jedoch auf der technischen Seite. Für Cloud-Setups stehen deshalb meist Lösungen im Vordergrund, die in die Breite skalieren können.

Breitenskalierung eigentlich nichts Neues

Das Skalieren in die Breite ist nichts Neues. Das HTTP-Protokoll etwa nutzt das Konzept seit Jahrzehnten: Das Prinzip, einen Loadbalancer zu verwenden und die Anzahl der verfügbaren Backends von der tatsächlichen Last abhängig zu machen, folgt exakt denselben Ideen. Auch Datenbanken haben in den vergangenen Jahren beim Skalieren in die Breite nachgelegt: Sowohl MySQL – zum Beispiel per Galera – als auch PostgreSQL beherrschen entsprechende Funktionalität. Beim Thema Storage sah das eine ganze Weile anders aus. Klassische Speicher im Sinne von SAN-Storages etwa können eben nur in die Höhe skalieren, aber nicht in die Breite.

Des Übels Wurzel

Warum ist das Skalieren in die Breite bei klassischem Storage so schwer? Ein Blick unter die Haube hilft beim Verstehen. Praktisch alle Speichermedien der Gegenwart sind blockbasiert. Das gilt für sämtliche Geräte im Serverumfeld wie für USB-Sticks aus dem Computermarkt des Vertrauens. Blockbasierte Speicher lassen sich ab Werk nicht sinnvoll nutzen; zwar lassen sich Daten auf ihnen ablegen, aber wollte man exakt die gleichen Daten später wieder lesen, müsste man den kompletten Datenträger absuchen und aus dem Suchergebnis die passenden Daten herausfiltern. Damit Blockgeräte also nutzbar werden, müssen sie irgendwie sinnvoll organisiert sein.

Der klassische Ansatz sind dafür Dateisysteme. Diese legen auf dem Gerät eine entsprechende Struktur an, die abfragbar ist. Über den Umweg des Dateisystems lassen sich auf einem Blockgerät Daten zuverlässig finden. Das Problem hierbei ist, dass praktisch alle relevanten Dateisysteme für Linux so konstruiert sind, dass sie die konkrete Bindung an ein Blockgerät vorsehen. Es ist also unmöglich, das Dateisystem eines Datenträgers auf mehrere Blockgeräte zu verteilen. Doch gerade darum geht es ja bei Clouds. Systeme, die in die Breite skalieren können, sind immer verteilte Systeme.

Software Defined Storage ermöglicht verteiltes Speichern

Beim Skalieren in die Breite kommt das Konzept des Software Defined Storage ins Spiel. SDS-Lösungen fügen eine zusätzliche Ebene zwischen den physischen Datenträgern und dem Frontend ein, über das Endanwender (oder deren Programme) auf Daten zugreifen. Jene Ebene bietet dabei nicht nur das Interface zur Nutzerseite, es verteilt im Hintergrund auch die eingehenden Daten automatisch auf beinahe beliebig viele Speichergeräte.

Viele SDS-Lösungen folgen beispielsweise dem Prinzip, sämtliche Daten, die den Weg in den Speicher finden, als binäre Objekte zu behandeln. Binäre Objekte sind nach Belieben zerlegbar, solange sie beim Auslesen in korrekter Reihenfolge wieder zusammengesetzt werden. Genau das ist das Prinzip des sogenannten Object Stores, das vielen verteilten Speichern zugrunde liegt. Gelegentlich erscheinen beide Begriffe sogar synonym, auch wenn das nicht ganz korrekt ist. Denn es gibt am Markt auch SDS-Lösungen, die intern anders funktionieren.

Seinen Namen bekommt das Konzept des Software Defined Storage letztlich von genau dieser Ebene. Die Speicherlösung selbst ist als Software implementiert, die obendrein auf handelsüblicher Hardware läuft. Weil auf der Software-Ebene beinahe jede Funktionalität denkbar ist, stechen viele SDS-Lösungen klassische Storage-Appliances in Sachen Funktionalität gnadenlos aus.

Gerade weil das Frontend zur Anwenderseite hin einzig durch die SDS-Lösung selbst definiert ist, lassen sich auch mehrere Frontends unterschiedlichen Typs bauen – der gleiche Speicher ist dann auf mehreren Wegen nutzbar. So ist es beim Cloud Computing üblich, die Daten einer SDS-Lösung auch über eine klassische Schnittstelle für Blockgeräte anzubieten. Letztlich sieht die SDS-Lösung von außen dann noch immer aus wie ein normales Blockgerät, im Hintergrund arbeitet aber die nahtlos skalierbare SDS-Lösung.

Ceph als Beispiel par excellence

Was in der Theorie kompliziert klingt, lässt sich anhand einer aktuellen SDS-Lösung leichter erklären: Ceph. Die Geschichte des Projekts ist deutlich länger, als die meisten Nutzer das wohl glauben. Ceph-Erfinder Sage Weil begann die Arbeiten bereits vor etwa einem Jahrzehnt. Das Projekt war ursprünglich Weils Doktorarbeit an der University of Santa Cruz in Kalifornien, hatte aber auch einen Bezug zu Weils damaliger Arbeit. Er sollte für das US Department of Energy, also die amerikanische Energiebehörde, eine Storage-Lösung erfinden, die die Nachteile der damals dort laufenden Umgebung umgehen sollte.

Ganz am Anfang der Entwicklung stand das Ziel, ein mit POSIX kompatibles Dateisystem zu erstellen, das Nachteile bestehender Lösungen wie Lustre qua Design gar nicht erst hat. Im Laufe der Jahre wurde Ceph Weils Hauptbeschäftigung und schließlich zu einem US-Unternehmen namens Inktank, das der Linux-Distributor Red Hat inzwischen aufgekauft hat.

Ceph ist ein klassischer Objektspeicher und damit das perfekte Beispiel für Software Defined Storage. Die Lösung firmierte ursprünglich als Rados, ein Akronym für Reliable Autonomic Distributed Object Store. Ceph hingegen war der Codename des POSIX-Dateisystems, das als eigenes Frontend lediglich auf den RADOS-Cluster im Hintergrund zugreift. Im Kontext des Cloud-Booms entschied sich Weils Firma Inktank allerdings dazu, den Namen Ceph durchgehend zu verwenden. Das POSIX-Dateisystem heißt heute aus diesem Grund CephFS.

Zwei Basis-Komponenten

Ein typischer Ceph-Cluster besteht aus zwei Diensten, die innerhalb eines Clusters beinahe beliebig oft vorkommen: den OSDs auf der einen Seite und den MONs auf der anderen Seite.

OSD ist die Abkürzung für Object Storage Device. So bezeichnet Ceph den Dienst, der physische Platten in den Clusterverbund integriert. Die zuvor erwähnte Ebene, die verteilte Storage-Systeme zwischen die Nutzer und die physischen Geräte einfügen, stellen genau diese OSDs dar. Die Kommunikation mit den physischen Blockgeräten wickeln die OSD-Server im Hintergrund ab. Auch um die inhärente Replikation kümmern sich vorrangig die OSD-Dienste.

Dabei gilt, dass pro physischem Blockgerät ein OSD-Dienst läuft. Auf einem Server mit 24 Festplatten finden sich also 24 laufende OSD-Instanzen. OSDs bilden obendrein den Anlaufpunkt für Clients, um Daten anzuliefern oder abzuholen. Die Clients liefern Daten bei einem OSD an, das sich danach um die Replikation kümmert. Erst wenn die eingestellten Replikationsvorgaben erfüllt sind, erhält der Client die Nachricht, dass der Schreibvorgang erfolgreich war.

Die Monitoring-Server, kurz MONs, sind in Ceph die Cluster-Wachhunde: Sie führen Buch über vorhandene MONs und OSDs und erzwingen im Cluster ein Quorum auf der MON-Ebene. Das ist wichtig in Situationen, in denen der Cluster in mehrere Partitionen zerfällt, etwa weil Netzwerkhardware kaputtgeht: Die MONs stellen in solchen Szenarien sicher, dass Clients nur auf die Partition des Clusters schreibend zugreifen können, die die Mehrheit der insgesamt im Cluster bekannten MON-Server hinter sich weiß. MON-Server sind auch der erste Anlaufpunkt für Clients und OSDs gleichermaßen, wenn diese Informationen über die aktuelle Topologie des Clusters brauchen.

Die Platzierung von Daten

Dieser Punkt führt zu einem der interessantesten Probleme, wenn es um das Thema verteilte Speicherlösungen geht. Der zwischengeschaltete Layer trägt wie eingangs beschrieben die Verantwortung dafür, dass eingehende Daten auf den physischen Speichergeräten sinnvoll verteilt abgelegt werden. Er ist obendrein zuständig, wenn Clients spezifische Informationen über eines der Cluster-Frontends wieder auslesen wollen, denn dann läuft der Vorgang einfach in umgekehrter Reihenfolge ab.

Woher aber erfährt ein Client, der Daten in den Cluster laden möchte, welches OSD das richtige ist? Und wo bekommt jenes Primary OSD die Information her, auf welchen anderen OSDs es von den hochgeladenen Daten Replikate anlegen muss, bevor es dem Client einen erfolgreichen Schreibvorgang vermeldet?

Im Beispiel von Ceph kommt an dieser Stelle der Crush-Algorithmus ins Spiel. Er ist Cephs Placement-Algorithmus und ermöglicht es Clients wie OSDs, sich das jeweils passende Ziel-OSD für bestimmte Datensätze auszurechnen.

Crush als Dreh- und Angelpunkt

Der Crush-Algorithmus ist in Ceph der zentrale Punkt, wenn es um die Platzierung von Daten geht. Die Abkürzung steht für Controlled Replication Under Scalable Hashing. Gemeint ist das Prinzip, anhand dessen Clients oder OSDs die Ziel-OSDs für bestimmte Datensätze festlegen.

Zur Erinnerung, Ceph betrachtet sämtliche Daten als binäre Objekte. Wenn ein Client nun also Informationen in den Cluster laden möchte, findet zuerst die Aufteilung in Objekte statt. Für jedes der Objekte stellt sich dann die Frage, an welches OSD es zu senden ist und wohin es von dort repliziert wird.

Der Crush-Algorithmus beantwortet ebendiese Frage. Der Client organisiert sich zunächst von den MON-Servern des Ceph-Clusters das aktuelle Verzeichnis aller OSDs und stößt danach die Crush-Berechnung für das jeweilige Objekt an.

Crush lässt sich auch von außen beeinflussen: Die Crush-Map bietet dem Admin etwa die Möglichkeit, Rechner oder OSDs logisch zu gruppieren. Legt der Admin zum Beispiel fest, dass bestimmte Server in Rack 1 hängen und andere Server in Rack 2, so kann er im nächsten Schritt bestimmen, dass Replikate eines binären Objektes in beiden Racks vorhanden sein müssen.

Wenn der Client oder die OSDs danach die Crush-Kalkulation für ein bestimmtes Objekt durchführen, beziehen sie jene Faktoren mit ein und erhalten ein entsprechendes Ergebnis. Das gilt übrigens sowohl für Lese- wie auch für Schreibvorgänge. Solange sich die Topologie des Clusters nicht ändert, bleibt das Crush-Resultat identisch.

Parallellität als Matchwinner

Eine der größten Stärken von Ceph ist, dass Crush-Kalkulationen sowie Objekt-Uploads oder Objekt-Downloads parallel geschehen. Ein Client zerteilt eine Datei also in viele kleine Objekte und lädt diese anschließend parallel auf verschiedene OSDs. Er redet stets mit vielen Spindeln gleichzeitig und kombiniert so die Bandbreite beim Hoch- oder Herunterladen. Verglichen mit klassischen Storages erreicht Ceph so bei entsprechender Netzwerkhardware enorme Durchsatzwerte.

Drei Frontends

Aus Nutzersicht gestaltet sich der Umgang mit Ceph deutlich weniger komplex als beim Blick unter die Haube. Für Ceph existieren aktuell drei Frontends für verschiedene Aufgaben. Das Ceph Block Device greift im Hintergrund auf den Objektspeicher zu und gibt nach außen ein Blockdevice aus. Der Zugriff auf ein Ceph Block Device kann auf Linux-Systemen wahlweise über das dazu passende Kernel-Modul geschehen oder im Userspace über die C-Bibliothek Librados, die etwa in der virtuellen Maschine Qemu bereits integriert ist. Ein mit Ceph-Support kompiliertes Qemu kann also auf virtuelle Block-Devices in Ceph ohne den Kernel-Umweg zugreifen.

Kein fertiges Frontend, aber doch sehr nützlich ist die bereits erwähnte C-Bibliothek Librados. Diese bietet auf der Programmierebene die Möglichkeit, direkt auf Ceph zuzugreifen. Für Librados existieren zudem diverse Anbindungen für Skriptsprachen. Mittels PHP-Rados lässt sich etwa aus PHP-Anwendungen heraus direkt auf die Inhalte des Objektspeichers zugreifen.

Was abgedreht klingt, hat durchaus einen praktischen Nutzen. Viele Webanwendungen lagern statische Inhalte wie Bilder auf POSIX-Dateisystemen, obwohl sie deren Semantik nicht benötigen. Im genannten Beispiel bezieht die Webanwendung die Bilder stattdessen als Objekt direkt aus Ceph und umgeht so Hilfskonstrukte auf Basis von NFS (Network File System) oder ähnlichen Lösungen. Vergleichbare Lösungen mit Amazons Simple Storage Service (S3) haben sich mittlerweile etabliert.

Auf Librados basiert auch das Ceph Object Gateway. Dieses exponiert nach außen das Amazon-S3-Protokoll und das Openstack-Swift-Protokoll und bietet so Zugriff auf Ceph per HTTP-basierter Restful-API. Admins können Nutzern also über das Ceph Object Gateway einen objektbasierten Online-Speicherdienst im Stile von Dropbox, Amazon S3 oder Google Drive anbieten.

Nicht zu vergessen ist freilich auch das bereits erwähnte CephFS. Erst vor ein paar Monaten erreichte dieses die Reife für den produktiven Einsatz und war damit ironischerweise das letzte der drei beschriebenen Frontends – und das, obwohl es eigentlich die Keimzelle von Ceph darstellt, dessen Entwicklung vor mehr als zehn Jahren begonnen hat.

Über den Autor: Martin Gerhard Loschwitz ist Team Lead Openstack bei dem Hoster Syseleven in Berlin, der unter anderem auch Golem.de hostet. Er beschäftigt sich dort bevorzugt mit den Themen Distributed Storage, Software Defined Networking und Openstack.

Der Artikel erschien zuerst am 6.10.2016 auf Golem.de. Wir veröffentlichen ihn mit freundlicher Genehmigung.