Kapitel 1. Fibel zur Big Data-Technologie

Diese Arbeit wurde mithilfe von KI übersetzt. Wir freuen uns über dein Feedback und deine Kommentare: translation-feedback@oreilly.com

Apache Hadoop ist ein eng integriertes Ökosystem aus verschiedenen Softwareprodukten, die für eine skalierbare und zuverlässige verteilte Speicherung und Verarbeitung sorgen. Die Inspiration für einen Großteil des Hadoop-Ökosystems war eine Reihe von Veröffentlichungen von Google in den 2000er Jahren, in denen Innovationen für Systeme zur zuverlässigen Speicherung (das Google File System), Verarbeitung (MapReduce, Pregel) und Abfragen mit geringer Latenz (Bigtable) auf Hunderten bis Tausenden von potenziell unzuverlässigen Servern beschrieben wurden. Für Google war die Entwicklung dieser Systeme in erster Linie eine Frage der Zweckmäßigkeit: Es gab damals einfach keine Technologien, die in der Lage waren, die riesigen Datenmengen, mit denen das Unternehmen zu tun hatte, zu speichern und zu verarbeiten. Der herkömmliche Ansatz für die Berechnung von Datenmengen bestand darin, in ein paar extrem leistungsstarke Server mit vielen Prozessoren und viel Arbeitsspeicher zu investieren, die Daten von einer Speicherebene (z. B. NAS oder SAN) einzuschleusen, eine Berechnung durchzuführen und die Ergebnisse zurück in die Speicherung zu schreiben. Als der Umfang der Daten zunahm, erwies sich dieser Ansatz als unpraktisch und teuer.

Die wichtigste Innovation, die sich bis heute bewährt hat, bestand darin, die Datensätze auf viele Rechner zu verteilen und alle Berechnungen auf diesen Daten in viele unabhängige "Shared-Nothing"-Bausteine aufzuteilen, die jeweils auf denselben Rechnern ausgeführt werden konnten, auf denen die Daten gespeichert waren. Bisherige Technologien konnten zwar auf mehreren Servern ausgeführt werden, waren aber in der Regel stark auf die Kommunikation zwischen den verteilten Komponenten angewiesen, was mit zunehmender Parallelität zu abnehmenden Erträgen führt (siehe Amdahls Gesetz). Im Gegensatz dazu wird das Problem der Skalierung beim Distributed-by-Design-Ansatz auf natürliche Weise gelöst, da jeder unabhängige Teil der Berechnung nur für einen kleinen Teil des Datensatzes verantwortlich ist. Eine größere Speicherung und Rechenleistung kann einfach durch das Hinzufügen weiterer Server erreicht werden - eine sogenannte horizontal skalierbare Architektur. Ein wichtiger Punkt bei der Entwicklung von Rechnern in solchen Größenordnungen ist die Annahme, dass Komponenten ausfallen können, um aus unzuverlässigen Komponenten ein zuverlässiges System zu machen. Solche Entwürfe lösen das Problem der kosteneffizienten Skalierung, da Speicherung und Berechnung auf Standard-Servern realisiert werden können.

Hinweis

Mit den Fortschritten im Bereich der Standardnetzwerke und dem allgemeinen Trend zum Cloud Computing und zur Speicherung wird die Anforderung, Berechnungen lokal zu den Daten durchzuführen, immer unwichtiger. Wenn deine Netzwerkinfrastruktur gut genug ist, ist es nicht mehr unbedingt erforderlich, dieselbe Hardware für die Berechnung und Speicherung zu verwenden. Der verteilte Charakter und der horizontal skalierbare Ansatz sind jedoch immer noch grundlegend für den effizienten Betrieb dieser Systeme.

Hadoop ist eine Open-Source-Implementierung dieser Techniken. Im Kern bietet es ein verteiltes Dateisystem (HDFS) und eine Möglichkeit, Prozesse in einem Server-Cluster auszuführen (YARN). Die ursprüngliche verteilte Verarbeitungsanwendung, die auf Hadoop aufbaut, war MapReduce, aber seit der Einführung von Hadoop hat sich eine Vielzahl von zusätzlichen Software-Frameworks und Bibliotheken entwickelt, die jeweils einen anderen Anwendungsfall abdecken. Im folgenden Abschnitt geben wir einen Überblick über die Kerntechnologien des Hadoop-Projekts sowie über einige der beliebtesten Open-Source-Frameworks, die auf Hadoop-Clustern laufen.

Ein Rundgang durch die Landschaft

Wenn wir "Hadoop" sagen, meinen wir in der Regel Hadoop und alle Data-Engineering-Projekte und -Frameworks, die um Hadoop herum entstanden sind. In diesem Abschnitt gehen wir kurz auf einige Schlüsseltechnologien ein, kategorisiert nach Anwendungsfällen. Wir sind nicht in der Lage, jedes Framework im Detail zu behandeln - in vielen Fällen gibt es eigene Abhandlungen auf Buchniveau -, aber wir versuchen, ein Gefühl dafür zu vermitteln, was sie tun. Dieser Abschnitt kann übersprungen werden, wenn du mit diesen Technologien bereits vertraut bist, oder du kannst ihn als praktische Kurzreferenz nutzen, um dich an die Grundlagen zu erinnern.

Der Zoo der Frameworks und die Art und Weise, wie sie sich aufeinander beziehen und voneinander abhängen, kann anfangs entmutigend wirken, aber mit etwas Einarbeitung werden die Zusammenhänge klarer. Vielleicht hast du schon Darstellungen wie in Abbildung 1-2 gesehen, die zeigen, wie die verschiedenen Komponenten aufeinander aufbauen. Diese Diagramme können eine nützliche Hilfe zum Verständnis sein, aber sie machen nicht immer alle Abhängigkeiten zwischen den Projekten deutlich. Projekte hängen auf unterschiedliche Weise voneinander ab, aber wir können uns zwei Hauptarten von Abhängigkeiten vorstellen: Daten und Kontrolle. Auf der Datenebene ist eine Komponente beim Lesen und Schreiben von Daten von einer anderen Komponente abhängig, während auf der Steuerungsebene eine Komponente bei Metadaten oder Koordination von einer anderen Komponente abhängig ist. Für die grafisch Interessierten sind einige dieser Beziehungen in Abbildung 1-3 dargestellt. Keine Panik, das soll dich nicht abschrecken und es ist in diesem Stadium auch nicht wichtig, dass du genau verstehst, wie die Abhängigkeiten zwischen den Komponenten funktionieren. Die Diagramme zeigen aber, wie wichtig es ist, ein grundlegendes Verständnis für den Zweck der einzelnen Elemente im Stack zu entwickeln. Das Ziel dieses Abschnitts ist es, dir diesen Kontext zu vermitteln.

amdp 0102
Abbildung 1-2. Standarddarstellung der Technologien und Abhängigkeiten im Hadoop-Stack
amdp 0103
Abbildung 1-3. Grafische Darstellung einiger Abhängigkeiten zwischen Komponenten in der Daten- und Kontrollebene
Hinweis

Wenn es mehrere Technologien mit ähnlichem Design, ähnlicher Architektur und ähnlichem Anwendungsfall gibt, behandeln wir nur eine, bemühen uns aber, so weit wie möglich auf die Alternativen hinzuweisen, entweder im Text oder in den Abschnitten "Bitte beachten".

Kernkomponenten

Die erste Gruppe von Projekten sind diejenigen, die den Kern des Hadoop-Projekts selbst bilden oder Schlüsseltechnologien für den Rest des Stacks sind: HDFS, YARN, Apache ZooKeeper und der Apache Hive Metastore. Zusammen bilden diese Projekte die Grundlage, von der die meisten anderen Frameworks, Projekte und Anwendungen, die auf dem Cluster laufen, abhängen.

HDFS

Das Hadoop Distributed File System (HDFS) ist das skalierbare, fehlertolerante und verteilte Dateisystem für Hadoop. Basierend auf dem ursprünglichen Anwendungsfall der Analyse großer Datenmengen ist HDFS dafür optimiert, sehr große Mengen unveränderlicher Daten zu speichern, wobei der Zugriff auf die Dateien in der Regel in langen sequentiellen Abfragen erfolgt. HDFS ist die entscheidende Technologie für viele der anderen Komponenten im Stack.

Beim Speichern von Daten unterteilt HDFS eine Datei in Blöcke mit konfigurierbarer Größe, in der Regel etwa wie 128 MiB, und speichert ein Replikat jedes Blocks auf mehreren Servern, um die Ausfallsicherheit und Parallelität der Daten zu gewährleisten. Auf jedem Worker Node im Cluster läuft ein Daemon namens DataNode, der neue Blöcke annimmt und sie auf seinen lokalen Festplatten speichert. Der DataNode ist auch für die Bereitstellung der Daten an die Clients verantwortlich. Der DataNode kennt nur die Blöcke und ihre IDs; er weiß nicht, zu welcher Datei ein bestimmtes Replikat gehört. Diese Informationen werden von einem koordinierenden Prozess, dem NameNode, verwaltet, der auf den Master-Servern läuft und für die Zuordnung der Dateien zu den Blöcken sowie für die Metadaten zu den Dateien selbst (Namen, Berechtigungen, Attribute und Replikationsfaktor) zuständig ist.

Kunden, die Blöcke speichern wollen, müssen zunächst mit dem NameNode kommunizieren, um eine Liste von DataNodes zu erhalten, auf die jeder Block geschrieben werden soll. Der Kunde schreibt an den ersten DataNode, der wiederum die Daten an den nächsten DataNode weiterleitet, und so weiter in einer Pipeline. Bei der Bereitstellung einer Liste von Datenknoten für die Pipeline berücksichtigt der NameNode eine Reihe von Faktoren, darunter den verfügbaren Platz auf dem Datenknoten und den Standort des Knotens - seine Rack-Locality. Der NameNode sichert sich gegen Knoten- und Rack-Ausfälle ab, indem er sicherstellt, dass sich jeder Block auf mindestens zwei verschiedenen Racks befindet. In Abbildung 1-4 schreibt ein Kunde eine Datei, die aus drei Blöcken besteht, in das HDFS, und der Prozess verteilt und repliziert die Daten auf die DataNodes.

amdp 0104
Abbildung 1-4. Der HDFS-Schreibprozess und wie Blöcke auf DataNodes verteilt werden

Beim Lesen von Daten fragt der Client den NameNode nach einer Liste von DataNodes, die die Blöcke für die benötigten Dateien enthalten. Der Kunde liest die Daten dann direkt von den DataNodes, wobei er Replikate bevorzugt, die lokal oder in der Nähe des Netzwerks liegen.

Das Design von HDFS bedeutet, dass es keine Aktualisierungen an den gespeicherten Dateien zulässt. Das kann auf den ersten Blick recht restriktiv erscheinen, bis du erkennst, dass diese Unveränderlichkeit es ermöglicht, die erforderliche horizontale Skalierbarkeit und Ausfallsicherheit auf relativ einfache Weise zu erreichen.

HDFS ist fehlertolerant, weil der Ausfall einer einzelnen Festplatte, eines Datenknotens oder sogar eines Racks die Sicherheit der Daten nicht gefährdet. In solchen Situationen weist der NameNode einfach einen der DataNodes, der ein überlebendes Replikat unterhält, an, den Block auf einen anderen DataNode zu kopieren, bis der erforderliche Replikationsfaktor wiederhergestellt ist. Kunden, die Daten lesen, werden zu einem der verbleibenden Replikate geleitet. Auf diese Weise ist das gesamte System selbstheilend, vorausgesetzt, wir sorgen für ausreichende Kapazität und Redundanz im Cluster selbst.

HDFS ist skalierbar, da wir die Kapazität des Dateisystems einfach erhöhen können, indem wir weitere DataNodes mit lokaler Speicherung hinzufügen. Das hat auch den angenehmen Nebeneffekt, dass sich der verfügbare Lese- und Schreibdurchsatz von HDFS insgesamt erhöht.

Es ist jedoch wichtig zu wissen, dass HDFS diese Ausfallsicherheit und Skalierbarkeit nicht von alleine erreicht. Wir müssen die richtigen Server verwenden und den Aufbau unserer Cluster so gestalten, dass wir die Ausfallsicherheit und Skalierbarkeit von HDFS nutzen können - und genau darum geht es in diesem Buch. In Kapitel 3 wird ausführlich erläutert, wie HDFS mit den Servern interagiert, auf denen seine Daemons laufen, und wie es die lokal angeschlossenen Festplatten in diesen Servern nutzt. In Kapitel 4 gehen wir auf die Optionen ein, die bei der Erstellung eines Netzwerkplans zur Verfügung stehen, und in Kapitel 12 beschreiben wir, wie man HDFS so hochverfügbar und fehlertolerant wie möglich macht.

Eine letzte Anmerkung, bevor wir weitermachen. In dieser kurzen Beschreibung von HDFS haben wir über die Tatsache hinweggesehen, dass Hadoop viele dieser Details vom Client abstrahiert. Die API, die ein Client verwendet, ist eigentlich ein Hadoop-kompatibles Dateisystem, von dem HDFS nur eine Implementierung ist. Wir werden in diesem Buch auch andere gängige Implementierungen kennenlernen, z. B. Cloud-basierte Objektspeicher wie Amazon S3.

YARN

Es ist zwar nützlich, Daten skalierbar und widerstandsfähig zu speichern, aber was wir wirklich wollen, ist, dass wir aus diesen Daten Erkenntnisse ableiten können. Dazu müssen wir in der Lage sein, aus den Daten Berechnungen durchzuführen, die mit den zu erwartenden Datenmengen in unserem Hadoop-Dateisystem skalieren können. Außerdem müssen wir in der Lage sein, viele verschiedene Berechnungen gleichzeitig auszuführen, um die verfügbaren Ressourcen des Clusters effizient zu nutzen und den Aufwand für den Datenzugriff zu minimieren. Jede Berechnung verarbeitet unterschiedliche Datenmengen und erfordert unterschiedliche Mengen an Rechenleistung und Speicher. Um diese konkurrierenden Anforderungen zu bewältigen, brauchen wir einen zentralen Clustermanager, der über alle verfügbaren Rechenressourcen und die aktuellen konkurrierenden Arbeitslasten informiert ist.

Genau dafür ist YARN (Yet Another Resource Negotiator) gedacht. YARN lässt auf jedem Worker-Knoten einen Daemon laufen, den NodeManager, der einem Master-Prozess, dem ResourceManager, Bericht erstattet. Jeder NodeManager teilt dem ResourceManager mit, wie viele Rechenressourcen (in Form von virtuellen Kernen oder vcores) und wie viel Arbeitsspeicher auf seinem Knoten verfügbar sind. Die Ressourcen werden in Form von Containern an die Anwendungen verteilt, die auf dem Cluster laufen. Jeder Container hat einen bestimmten Ressourcenbedarf, z. B. 10 Container mit je 4 virtuellen Kernen und 8 GB RAM. Die NodeManager sind dafür verantwortlich, Container auf ihren lokalen Knoten zu starten und zu überwachen und sie zu beenden, wenn sie die ihnen zugewiesenen Ressourcen überschreiten.

Eine Anwendung, die Berechnungen im Cluster durchführen möchte, muss zunächst den ResourceManager um einen einzelnen Container bitten, in dem ihr eigener Koordinationsprozess, der ApplicationMaster (AM), ausgeführt wird. Trotz seines Namens läuft der AM tatsächlich auf einem der Arbeitsrechner. Die ApplicationMaster der verschiedenen Anwendungen werden auf verschiedenen Arbeitsmaschinen ausgeführt, um sicherzustellen, dass der Ausfall einer einzelnen Arbeitsmaschine nur eine Teilmenge der im Cluster laufenden Anwendungen beeinträchtigt. Sobald der AM läuft, fordert er zusätzliche Container vom ResourceManager an, um seine eigentlichen Berechnungen durchzuführen. Dieser Prozess ist in Abbildung 1-5 skizziert: Drei Clients führen Anwendungen mit unterschiedlichen Ressourcenanforderungen aus, die in unterschiedlich große Container übersetzt und zur Ausführung auf die NodeManager verteilt werden.

amdp 0105
Abbildung 1-5. Ausführung einer YARN-Anwendung.

Der ResourceManager führt einen speziellen Thread aus, der für die Zeitplanung der Anwendungsanfragen zuständig ist und sicherstellt, dass die Container gerecht zwischen den Anwendungen und Nutzern, die Anwendungen im Cluster ausführen, aufgeteilt werden. Dieses Zeitplannungsprogramm bemüht sich um eine gerechte Verteilung der Kerne und des Arbeitsspeichers zwischen den Tenants. Tenants und Workloads werden in hierarchische Pools unterteilt, von denen jeder einen konfigurierbaren Anteil an den gesamten Cluster-Ressourcen hat.

Aus der Beschreibung sollte klar hervorgehen, dass YARN selbst keine Berechnungen durchführt, sondern vielmehr ein Framework ist, mit dem solche Anwendungen über einen Cluster verteilt gestartet werden können. YARN bietet eine Reihe von APIs für die Erstellung dieser Anwendungen; zwei dieser Implementierungen, MapReduce und Apache Spark, werden in "Berechnungs-Frameworks" behandelt .

Mehr darüber, wie du YARN hochverfügbar machst, erfährst du in Kapitel 12.

Apache ZooKeeper

Das Problem des Konsenses ist ein wichtiges Thema in der Informatik. Wenn eine Anwendung auf viele Knotenpunkte verteilt ist, besteht ein Hauptproblem darin, diese unterschiedlichen Komponenten dazu zu bringen, sich auf die Werte einiger gemeinsamer Parameter zu einigen. Bei Frameworks mit mehreren Master-Prozessen ist die Einigung darüber, welcher Prozess der aktive Master und welcher der Standby-Prozess sein soll, entscheidend für den korrekten Betrieb.

Apache ZooKeeper ist der robuste, verteilte Konfigurationsdienst für das Hadoop-Ökosystem. Im ZooKeeper werden die Konfigurationsdaten in einem dateisystemähnlichen Baum von Knoten, den sogenannten znodes, gespeichert und abgerufen, von denen jeder Daten enthalten und der Elternteil von null oder mehr Kindknoten sein kann. Clients öffnen eine Verbindung zu einem einzelnen ZooKeeper-Server, um die znodes zu erstellen, zu lesen, zu aktualisieren und zu löschen.

Um die Ausfallsicherheit zu gewährleisten, sollten die ZooKeeper-Instanzen als Ensemble auf verschiedenen Servern eingesetzt werden. Da ZooKeeper mit einem Mehrheitskonsens arbeitet, ist eine ungerade Anzahl von Servern erforderlich, um ein Quorum zu bilden. Obwohl auch eine gerade Anzahl von Servern eingesetzt werden kann, bietet der zusätzliche Server keine zusätzliche Ausfallsicherheit für das Ensemble. Die Funktionalität jedes Servers ist identisch, aber ein Server des Ensembles wird zum "Leader Node" gewählt - alle anderen Server werden als "Follower" bezeichnet. ZooKeeper garantiert, dass Datenaktualisierungen von einer Mehrheit der ZooKeeper-Server durchgeführt werden. Solange die Mehrheit der Server in Betrieb ist, ist das Ensemble funktionsfähig. Kunden können Verbindungen zu jedem der Server herstellen, um Lese- und Schreibvorgänge durchzuführen, aber die Schreibvorgänge werden von den Folgeservern an den Leader weitergeleitet, um die Konsistenz zu gewährleisten. ZooKeeper stellt sicher, dass alle Zustände konsistent sind, indem es garantiert, dass Aktualisierungen immer in der gleichen Reihenfolge durchgeführt werden.

Tipp

Im Allgemeinen kann ein Quorum mit n Mitgliedern bis zu floor((n-1)/2) Ausfälle überstehen und trotzdem betriebsbereit sein. Ein Ensemble mit vier Mitgliedern hat also die gleichen Ausfallsicherheitseigenschaften wie ein Ensemble mit drei Mitgliedern.

Wie in Tabelle 1-1 dargestellt, verlassen sich viele Frameworks im Ökosystem auf ZooKeeper, um hochverfügbare Master-Prozesse zu verwalten, Aufgaben zu koordinieren, den Status zu verfolgen und allgemeine Konfigurationsparameter zu setzen. Mehr darüber, wie ZooKeeper von anderen Komponenten für die Hochverfügbarkeit genutzt wird, erfährst du in Kapitel 12.

Tabelle 1-1. ZooKeeper-Abhängigkeiten
Projekt Verwendung von ZooKeeper

HDFS

Koordination der Hochverfügbarkeit

HBase

Metadaten und Koordination

Solr

Metadaten und Koordination

Kafka

Metadaten und Koordination

YARN

Koordination der Hochverfügbarkeit

Bienenstock

Sperren von Tabellen und Partitionen und hohe Verfügbarkeit

Apache Hive Metastore

Wir werden die Abfragefunktionen von Apache Hive in einem späteren Abschnitt behandeln, wenn wir über analytische SQL-Engines sprechen, aber eine Komponente des Projekts - der Hive Metastore - ist eine so wichtige unterstützende Technologie für andere Komponenten des Stacks, dass wir sie schon früh in dieser Übersicht vorstellen müssen.

Der Hive Metastore sammelt Informationen über die strukturierten Datensätze (im Gegensatz zu unstrukturierten Binärdaten), die sich in Hadoop befinden, und organisiert sie in einer logischen Hierarchie von Datenbanken, Tabellen und Ansichten. Hive-Tabellen haben definierte Schemata, die bei der Tabellenerstellung festgelegt werden. Diese Tabellen unterstützen die meisten der gängigen Datentypen, die du aus der Welt der relationalen Datenbanken kennst. Es wird erwartet, dass die zugrunde liegenden Daten in der Speicherung mit diesem Schema übereinstimmen, aber bei HDFS wird dies erst zur Laufzeit überprüft, was als Schema on Read bezeichnet wird. Hive-Tabellen können für Daten in einer Reihe von Speicher-Engines definiert werden, darunter Apache HBase und Apache Kudu, aber der mit Abstand häufigste Speicherort ist HDFS.

In HDFS sind Hive-Tabellen nichts anderes als Verzeichnisse mit Dateien. Bei großen Tabellen unterstützt Hive die Partitionierung über Unterverzeichnisse innerhalb des Tabellenverzeichnisses, die wiederum verschachtelte Partitionen enthalten können, falls erforderlich. Innerhalb einer einzelnen Partition oder in einer unpartitionierten Tabelle sollten alle Dateien im gleichen Format gespeichert werden, z. B. als kommagetrennte Textdateien oder in einem Binärformat wie Parquet oder ORC. Im Metaspeicher können Tabellen entweder als verwaltete oder als externe Tabellen definiert werden. Bei verwalteten Tabellen steuert Hive aktiv die Daten in der Speicher-Engine: Wenn eine Tabelle erstellt wird, baut Hive die Strukturen in der Speicher-Engine auf, indem es z. B. Verzeichnisse im HDFS erstellt. Wenn eine Tabelle gelöscht wird, löscht Hive die Daten in der Speicherung. Bei externen Tabellen nimmt Hive keine Änderungen an der zugrundeliegenden Speicher-Engine vor, sondern pflegt lediglich die Metadaten für die Tabelle in seiner Datenbank.

Andere Projekte wie Apache Impala und Apache Spark verlassen sich auf den Hive Metastore als einzige Quelle der Wahrheit für Metadaten über strukturierte Datensätze innerhalb des Clusters. Als solche ist sie eine wichtige Komponente in jedem Einsatz.

Tiefer gehen

Es gibt einige sehr gute Bücher über das Hadoop-Ökosystem, die es wert sind, gelesen zu werden, um ein gründliches Verständnis zu erlangen. Siehe insbesondere:

Computergestützte Rahmenwerke

Mit den Kernkomponenten von Hadoop haben wir Daten, die im HDFS gespeichert sind, und eine Möglichkeit, verteilte Anwendungen über YARN auszuführen. Es sind viele Frameworks entstanden, die es den Nutzern ermöglichen, beliebige Berechnungen zu definieren und zusammenzustellen und diese Berechnungen in kleinere Teile aufzuteilen und verteilt auszuführen. Schauen wir uns zwei der wichtigsten Frameworks an.

Hadoop MapReduce

MapReduce ist die ursprüngliche Anwendung, für die Hadoop entwickelt wurde. Es handelt sich um eine Java-basierte Implementierung des Plans, der in Googles MapReduce-Papier beschrieben wurde. Ursprünglich war es ein eigenständiges Framework, das auf dem Cluster lief, aber es wurde später auf YARN portiert, als sich das Hadoop-Projekt weiterentwickelte, um mehr Anwendungen und Anwendungsfälle zu unterstützen. Obwohl es von neueren Engines wie Apache Spark und Apache Flink abgelöst wurde, ist es immer noch wert, verstanden zu werden, da viele übergeordnete Frameworks ihre Eingaben in MapReduce-Aufträge zur Ausführung kompilieren. Dazu gehören:

  • Apache Hive

  • Apache Sqoop

  • Apache Oozie

  • Apache Pig

Hinweis

Die Begriffe map und reduce stammen aus der funktionalen Programmierung, bei der map eine Transformationsfunktion auf jedes Element einer Sammlung anwendet und reduce eine Aggregationsfunktion auf jedes Element einer Liste, um sie zu weniger Werten zusammenzufassen.

Im Wesentlichen unterteilt MapReduce eine Berechnung in drei aufeinander folgende Phasen: map, shuffle und reduce. In der Map-Phase werden die relevanten Daten aus dem HDFS gelesen und parallel von mehreren unabhängigen Map-Tasks verarbeitet. Diese Tasks sollten idealerweise überall dort ausgeführt werden, wo sich die Daten befinden - in der Regel streben wir einen Map Task pro HDFS-Block an. Der Nutzer definiert eine map() Funktion (im Code), die jeden Datensatz in der Datei verarbeitet und Schlüsselwerte für die nächste Phase ausgibt. In der Shuffle-Phase werden die Map-Outputs von MapReduce abgeholt und über das Netzwerk verschickt, um als Input für die Reduce-Tasks zu dienen. Eine benutzerdefinierte Funktion ( reduce() ) empfängt nacheinander alle Werte für einen Schlüssel und fasst sie zu weniger Werten zusammen, die die Eingaben zusammenfassen. Das Wesentliche des Prozesses ist in Abbildung 1-6 dargestellt. Im Beispiel werden die Dateien von den Mappern aus dem HDFS gelesen und anhand einer ID-Spalte nach Schlüsseln gemischt. Die Reducer fassen die restlichen Spalten zusammen und schreiben die Ergebnisse zurück ins HDFS.

amdp 0106
Abbildung 1-6. Einfache Aggregation in MapReduce

Die Abfolgen dieser drei einfachen linearen Stufen können zusammengesetzt und zu Berechnungen beliebiger Komplexität kombiniert werden, z. B. zu erweiterten Transformationen, Joins, Aggregationen und mehr. Bei einfachen Transformationen, die keine Aggregationen erfordern, ist die Reduktionsphase manchmal gar nicht erforderlich. Normalerweise werden die Ergebnisse eines MapReduce-Auftrags wieder im HDFS gespeichert, wo sie als Input für andere Aufträge dienen können.

Trotz seiner Einfachheit ist MapReduce unglaublich leistungsfähig und extrem robust und skalierbar. Es hat allerdings auch einige Nachteile. Erstens ist es aus Sicht des Nutzers ziemlich aufwändig: Er muss die Funktionen map() und reduce() in Java programmieren und kompilieren, was für viele Analysten eine zu hohe Hürde darstellt - komplexe Verarbeitungspipelines in MapReduce zu erstellen, kann eine entmutigende Aufgabe sein. Zweitens ist MapReduce selbst nicht besonders effizient. Es führt eine Menge plattenbasierter E/A durch, was bei der Kombination von Verarbeitungsstufen oder iterativen Operationen teuer werden kann. Mehrstufige Pipelines werden aus einzelnen MapReduce-Aufträgen mit einer HDFS-I/O-Barriere dazwischen zusammengesetzt, ohne dass mögliche Optimierungen im gesamten Verarbeitungsgraphen erkannt werden.

Aufgrund dieser Nachteile wurde eine Reihe von Nachfolgern von MapReduce entwickelt, die sowohl die Entwicklung vereinfachen als auch die Verarbeitungspipelines effizienter machen sollen. Trotzdem sind die konzeptionellen Grundlagen von MapReduce - die Aufteilung der Datenverarbeitung in mehrere unabhängige Aufgaben, die auf verschiedenen Rechnern ausgeführt werden (Maps), deren Ergebnisse dann auf einer anderen Gruppe von Rechnern zusammengeführt und gruppiert werden (Reduces) - grundlegend für alle verteilten Datenverarbeitungssysteme, einschließlich SQL-basierter Frameworks. Apache Spark, Apache Flink und Apache Impala sind, obwohl sie sich alle in ihren Besonderheiten unterscheiden, im Wesentlichen verschiedene Implementierungen dieses Konzepts.

Apache Spark

Apache Spark ist ein verteiltes Berechnungsframework, bei dem Effizienz und Benutzerfreundlichkeit im Vordergrund stehen und das sowohl Batch- als auch Streaming-Berechnungen unterstützt. Anstatt dass der Nutzer die notwendigen Datenmanipulationen in Form von reinen map() und reduce() Funktionen ausdrücken muss, wie es bei MapReduce der Fall ist, bietet Spark eine reichhaltige API mit allgemeinen Operationen wie Filtern, Verbinden, Gruppieren und Aggregieren direkt auf Datensätzen, die aus Zeilen bestehen, die alle einem bestimmten Typ oder Schema entsprechen. Neben der Verwendung von API-Methoden können die Nutzer auch direkt Operationen mit einem SQL-Dialekt (daher der allgemeine Name dieser Funktionen, Spark SQL) durchführen, so dass ein Großteil der Pipelines nicht mehr programmatisch erstellt werden muss. Mit seiner API macht Spark das Zusammenstellen komplexer Verarbeitungspipelines für den Benutzer viel einfacher. Ein einfaches Beispiel: In Abbildung 1-7 werden drei Datensätze eingelesen. Zwei davon werden zusammengeführt und mit einem dritten, gefilterten Datensatz verbunden. Das Ergebnis wird nach einer Spalte gruppiert, aggregiert und in eine Ausgabe geschrieben. Die Quellen und Senken der Datensätze können stapelgesteuert sein und HDFS oder Kudu nutzen oder in einem Stream zu und von Kafka verarbeitet werden.

amdp 0107
Abbildung 1-7. Eine typische einfache Aggregation in Spark

Ein wesentliches Merkmal der Operationen auf Datensätzen ist, dass die Verarbeitungsgraphen vor der Ausführung einen Standard-Abfrageoptimierer durchlaufen, der den Optimierern in relationalen Datenbanken oder massiv parallel arbeitenden Abfrage-Engines sehr ähnlich ist. Dieser Optimierer kann den Verarbeitungsgraphen neu anordnen, kombinieren und beschneiden, um die effizienteste Ausführungspipeline zu erhalten. Auf diese Weise kann die Ausführungs-Engine Datensätze viel effizienter bearbeiten und vermeidet einen Großteil der Zwischen-E/A, unter der MapReduce leidet.

Eines der Hauptziele bei der Entwicklung von Spark war es, den Arbeitsspeicher der Worker Nodes voll auszunutzen, der in immer größeren Mengen auf handelsüblichen Servern verfügbar ist. Die Möglichkeit, Daten im Hauptspeicher zu speichern und abzurufen, und zwar mit einer Geschwindigkeit, die um Größenordnungen schneller ist als die von Festplatten, macht bestimmte Arbeitslasten radikal effizienter. Vor allem verteilte maschinelle Lernprozesse, die oft iterativ auf denselben Datensätzen arbeiten, können enorme Laufzeitvorteile gegenüber der entsprechenden MapReduce-Ausführung erzielen. Wenn die Daten nicht vollständig in den Speicher passen, werden die Partitionen, die nicht zwischengespeichert werden können, auf die Festplatte ausgelagert oder zur Laufzeit transparent neu berechnet.

Spark implementiert die Stream-Verarbeitung als eine Reihe regelmäßiger Mikrobatches von Datensätzen. Dieser Ansatz erfordert nur geringfügige Unterschiede im Code für die auf die Daten angewendeten Transformationen und Aktionen - im Grunde genommen kann derselbe oder ein sehr ähnlicher Code sowohl im Batch- als auch im Streaming-Modus verwendet werden. Ein Nachteil des Micro-Batching-Ansatzes besteht darin, dass die Verarbeitung eines Ereignisses mindestens so lange dauert wie die Zeit zwischen den Batches, so dass er sich nicht für Anwendungsfälle eignet, die Latenzen im Millisekundenbereich erfordern. Diese potenzielle Schwäche ist aber auch eine Stärke, denn Microbatching ermöglicht einen viel höheren Datendurchsatz, als er bei der Verarbeitung einzelner Ereignisse erreicht werden kann. Im Allgemeinen gibt es relativ wenige Streaming-Anwendungsfälle, die wirklich Antwortzeiten von unter einer Sekunde erfordern. Die strukturierte Streaming-Funktionalität von Spark verspricht jedoch, viele der Vorteile eines optimierten Spark-Batch-Berechnungsgraphen in einen Streaming-Kontext zu übertragen und einen kontinuierlichen Streaming-Modus mit niedriger Latenz zu ermöglichen.

Spark bietet eine Reihe von integrierten Bibliotheken und APIs für maschinelles Lernen. Spark MLlib ermöglicht es, den Prozess der Erstellung eines Machine-Learning-Modells (Datenvorbereitung, Bereinigung, Merkmalsextraktion und Algorithmusausführung) in einer verteilten Pipeline zusammenzufassen. Nicht alle Algorithmen für maschinelles Lernen können automatisch verteilt ausgeführt werden. Deshalb enthält Spark einige Implementierungen für gängige Problemklassen wie Clustering, Klassifizierung und Regression sowie kollaboratives Filtern.

Spark ist ein außerordentlich leistungsfähiges Framework für die Datenverarbeitung und wird oft (zu Recht) die erste Wahl, wenn es darum geht, neue Anwendungsfälle für Stapelverarbeitung, maschinelles Lernen und Streaming zu entwickeln. Anwendungsarchitekten sollten auch Optionen wie Apache Flink für Batch- und Stream-Verarbeitung und Apache Impala (siehe "Apache Impala") für interaktives SQL in Betracht ziehen.

Tiefer gehen

Noch einmal: Hadoop: The Definitive Guide, von Tom White, ist die beste Quelle, um mehr über Hadoop MapReduce zu erfahren. Für Spark gibt es ein paar gute Referenzen:

Analytische SQL-Engines

MapReduce und Spark sind zwar extrem flexible und leistungsstarke Frameworks, aber um sie zu nutzen, musst du in einer Sprache wie Java, Scala oder Python programmieren können und mit der Bereitstellung und Ausführung von Code über die Kommandozeile vertraut sein. Die Realität sieht so aus, dass SQL in den meisten Unternehmen nach wie vor die Lingua franca der Analytik ist und die größte und am leichtesten zugängliche Kompetenzbasis darstellt. Manchmal musst du Dinge erledigen, ohne dass du eine komplette Anwendung programmieren, kompilieren, bereitstellen und ausführen musst. Außerdem interagieren viele Tools zur Entscheidungsunterstützung und Business Intelligence ausschließlich über SQL mit Datenspeichern. Aus diesen Gründen wurde viel Zeit und Mühe in die Entwicklung von SQL-ähnlichen Schnittstellen zu strukturierten Daten in Hadoop gesteckt. Viele von ihnen nutzen MapReduce oder Spark als zugrundeliegenden Berechnungsmechanismus, aber einige sind auch eigenständige Berechnungsmaschinen. Jede Engine konzentriert sich auf die Abfrage von Daten, die bereits in der Speicherung vorhanden sind, oder auf das Einfügen neuer Daten in großen Mengen in diese Engines. Sie sind für groß angelegte Analysen konzipiert und nicht für die Verarbeitung kleinerer Transaktionen. Schauen wir uns die wichtigsten Akteure an.

Apache Hive

Apache Hive ist die ursprüngliche Data-Warehousing-Technologie für Hadoop. Sie wurde bei Facebook entwickelt und bot als erste eine SQL-ähnliche Sprache namens HiveQL, mit der Analysten strukturierte Daten, die im HDFS gespeichert sind, abfragen können, ohne erst Code kompilieren und bereitstellen zu müssen. Hive unterstützt gängige SQL-Abfragekonzepte wie Tabellen-Joins, Unions, Subqueries und Views. Auf einer hohen Ebene analysiert Hive eine Benutzerabfrage, optimiert sie und kompiliert sie in eine oder mehrere verkettete Batch-Berechnungen, die es auf dem Cluster ausführt. Normalerweise werden diese Berechnungen als MapReduce-Aufträge ausgeführt, aber Hive kann auch Apache Tez und Spark als Backing Execution Engine nutzen. Hive besteht aus zwei Hauptkomponenten: einem Metadatenserver und einem Abfrageserver. Den Hive Metastore haben wir bereits behandelt, daher konzentrieren wir uns in diesem Abschnitt auf die Abfragefunktionen.

Benutzer, die SQL-Abfragen ausführen möchten, tun dies über den Abfrageserver, den HiveServer2 (HS2). Die Nutzer/innen öffnen Sitzungen mit dem Abfrageserver und stellen Abfragen im HQL-Dialekt. Hive analysiert diese Abfragen, optimiert sie so weit wie möglich und kompiliert sie zu einem oder mehreren Batch-Aufträgen. Aufträge, die Unterabfragen enthalten, werden zu mehrstufigen Aufträgen kompiliert, wobei die Zwischendaten aus jeder Stufe an einem temporären Ort im HDFS gespeichert werden. HS2 unterstützt mehrere gleichzeitige Benutzersitzungen und stellt die Konsistenz über gemeinsame oder exklusive Sperren in ZooKeeper sicher. Der Abfrageparser und -compiler verwendet einen kostenbasierten Optimierer, um einen Abfrageplan zu erstellen, und kann Tabellen- und Spaltenstatistiken (die auch im Metaspeicher gespeichert werden) verwenden, um die richtige Strategie beim Verbinden von Tabellen zu wählen. Hive kann mit Hilfe der eingebauten Serialisierungs- und Deserialisierungsbibliotheken ( SerDes genannt) eine Vielzahl von Dateiformaten lesen und kann auch um eigene Formate erweitert werden.

Abbildung 1-8 zeigt eine Übersicht über den Betrieb von Hive. Ein Client sendet im Rahmen einer Benutzersitzung Abfragen an eine HiveServer2-Instanz. HiveServer2 ruft die Informationen für die Datenbanken und Tabellen in den Abfragen aus dem Hive Metastore ab. Die Abfragen werden dann optimiert und in Sequenzen von Aufträgen (J) in MapReduce, Tez oder Spark zusammengestellt. Nach Abschluss der Aufträge werden die Ergebnisse über HiveServer2 an den Remote-Client zurückgegeben.

amdp 0108
Abbildung 1-8. High-Level-Übersicht über den Betrieb von Hive

Hive wird im Allgemeinen nicht als interaktive Abfrage-Engine betrachtet (obwohl in letzter Zeit Geschwindigkeitsverbesserungen durch langlebige Prozesse vorgenommen wurden, die es in diesen Bereich bringen). Viele Abfragen resultieren in Ketten von MapReduce-Aufträgen, deren Ausführung viele Minuten (oder sogar Stunden) dauern kann. Hive eignet sich daher ideal für Offline-Batch-Aufträge für Extrahier-, Transformier- und Ladevorgänge (ETL), Berichte oder andere Massendatenmanipulationen. Hive-basierte Workflows sind ein bewährter Bestandteil von Big-Data-Clustern und im Allgemeinen äußerst robust. Auch wenn Spark SQL immer beliebter wird, bleibt Hive ein unverzichtbares Werkzeug im Big-Data-Toolkit - und wird es auch weiterhin bleiben.

Wir werden noch einmal auf Hive zurückkommen, wenn wir in Kapitel 12 besprechen, wie man es für hohe Verfügbarkeit einsetzt.

Tiefer gehen

Viele Informationen über Hive finden sich in Blogbeiträgen und anderen Artikeln, die im Internet verteilt sind, aber es gibt einige gute Referenzen:

Hinweis

Obwohl wir es unter "Computational Frameworks" behandelt haben , ist Spark auch ein wichtiger Akteur im Bereich der analytischen SQL. Die SQL-Funktionalität von Spark unterstützt eine breite Palette von Arbeitslasten für ETL und Reporting und kann auch bei interaktiven Abfragen eine Rolle spielen. Für neue Implementierungen von Batch-SQL-Workloads sollte Spark wahrscheinlich als Standardstartpunkt betrachtet werden.

Apache Impala

Apache Impala ist eine MPP-Engine (Massively Parallel Processing), die schnelle, interaktive SQL-Abfragen auf riesigen Datensätzen in Hadoop oder einer Cloud Speicherung unterstützt. Ihr Hauptziel ist es, mehrere gleichzeitige Ad-hoc-Abfragen im Stil von Berichten zu ermöglichen, die Terabytes an Daten innerhalb weniger Sekunden verarbeiten. Die Lösung richtet sich vor allem an Analysten, die ihre eigenen SQL-Abfragen direkt oder mit Hilfe von UI-gesteuerten Business Intelligence (BI)-Tools durchführen möchten.

Im Gegensatz zu Hive oder Spark SQL wandelt Impala die Abfragen nicht in Batch-Aufträge um, die unter YARN laufen. Stattdessen ist es ein eigenständiger, in C++ implementierter Dienst mit eigenen Worker-Prozessen, die Abfragen ausführen, den Impala-Daemons. Anders als bei Hive gibt es keinen zentralen Abfrageserver; jeder Impala-Daemon kann Benutzerabfragen annehmen und fungiert als Koordinationsknoten für die Abfrage. Nutzer können Abfragen über JDBC oder ODBC, über eine Benutzeroberfläche wie Hue oder über die mitgelieferte Kommandozeile einreichen. Eingereichte Abfragen werden zu einem verteilten Abfrageplan zusammengestellt. Dieser Plan ist ein in Fragmente unterteilter Operatorbaum. Jedes Fragment ist eine Gruppe von Planknoten im Baum, die gemeinsam ausgeführt werden können. Der Daemon sendet verschiedene Instanzen der Planfragmente an die Daemons im Cluster, damit diese sie gegen ihre lokalen Daten ausführen, wobei sie in einem oder mehreren Threads innerhalb des Daemonprozesses ausgeführt werden.

Da Impala den Schwerpunkt auf Geschwindigkeit und Effizienz legt, verwendet es ein anderes Ausführungsmodell, bei dem die Daten von der Quelle durch einen Baum von verteilten Operatoren gestreamt werden. Von Scan-Knoten gelesene Zeilen werden von Fragment-Instanzen verarbeitet und an andere Instanzen gestreamt, die für das Zusammenführen, Gruppieren oder Aggregieren über Austauschoperatoren zuständig sein können. Die endgültigen Ergebnisse der verteilten Fragment-Instanzen werden an den Coordinator-Daemon zurückgesendet, der alle abschließenden Aggregationen durchführt, bevor er den Nutzer darüber informiert, dass Ergebnisse abgerufen werden können.

Der Abfrageprozess ist in Abbildung 1-9 skizziert. Ein Client wählt einen Impala-Daemon-Server aus, an den er seine Abfrage sendet. Dieser Koordinationsknoten kompiliert und optimiert die Abfrage in Remote-Ausführungsfragmente, die an die anderen Daemons im Cluster gesendet werden (Abfrageinitialisierung). Die Daemons führen die Operatoren in den Fragmenten aus und tauschen bei Bedarf Zeilen untereinander aus (verteilte Ausführung). Sobald sie verfügbar sind, leiten sie die Ergebnisse an den Koordinator weiter, der ggf. abschließende Aggregationen und Berechnungen durchführt, bevor er sie an den Kunden weiterleitet.

amdp 0109
Abbildung 1-9. Eine vereinfachte Ansicht des Abfrageausführungsprozesses in Impala

Impala kann Daten aus einer Vielzahl von Datenquellen lesen, darunter Textdateien, HBase-Tabellen und Avro, aber sein bevorzugtes Format auf der Festplatte ist Parquet. Impala kann die Tatsache nutzen, dass Parquet-Dateien Daten nach Spalten speichern, um die von der Festplatte gelesenen Daten auf die Spalten zu beschränken, auf die in der Abfrage selbst verweist. Impala verwendet außerdem Prädikat-Pushdown, um Zeilen direkt beim Lesen herauszufiltern. Derzeit kann Impala Daten lesen, die in HDFS, Apache HBase, Apache Kudu, Amazon S3 und Microsoft Azure Data Lake Store (ADLS) gespeichert sind.

Tiefer gehen

Für weitere Informationen über Impala empfehlen wir :

Bedenke auch

Es gibt noch viele weitere analytische Frameworks da draußen. Einige andere SQL-basierte verteilte Abfrage-Engines, die du auf jeden Fall im Auge behalten und für deine Anwendungsfälle in Betracht ziehen solltest, sind :

Speicherung von Motoren

Die ursprüngliche Speicher-Engine im Hadoop-Ökosystem ist HDFS, die sich hervorragend für die Speicherung großer Mengen von reinen Append-Daten eignet, auf die in sequenziellen Abfragen zugegriffen wird. Aber wie sieht es mit anderen Zugriffsmustern aus, z. B. dem Abrufen und Aktualisieren von Datensätzen nach dem Zufallsprinzip? Was ist mit der Dokumentensuche? Viele Workloads befassen sich mit großen und vielfältigen Datensätzen, sind aber nicht analytischer Natur. Für diese verschiedenen Anwendungsfälle wurden einige Projekte entwickelt oder für die Verwendung mit Hadoop angepasst.

Apache HBase

Der Wunsch einiger früher Webunternehmen, Dutzende von Milliarden bis Billionen von Datensätzen zu speichern und deren effiziente Abfrage und Aktualisierung zu ermöglichen, führte zur Entwicklung von Apache HBase - einem halbstrukturierten Key-Value-Speicher mit wahlfreiem Zugriff, der HDFS als persistenten Speicher nutzt. Wie bei vielen Hadoop-Projekten stammte der ursprüngliche Entwurf für das Framework aus einem Papier von Google, in dem das System Bigtable beschrieben wurde. Im Wesentlichen bietet HBase eine Möglichkeit, Lese- und Schreibvorgänge mit wahlfreiem Zugriff (die für HDFS sehr ineffizient sind) in sequenzielle E/A umzuwandeln (was HDFS hervorragend beherrscht).

HBase ist kein relationaler Speicher. Stattdessen speichert es halbstrukturierte Schlüssel-Wert-Paare, sogenannte Zellen, in einer verteilten Tabelle. HBase unterteilt den Schlüssel einer Zelle in eine Hierarchie von Komponenten, damit zusammengehörige Zellen effizient gemeinsam gespeichert und abgerufen werden können. Der erste Teil des Schlüssels wird als Zeilenschlüssel bezeichnet und definiert eine logische Gruppierung von Zellen, die als Zeile bezeichnet wird. Danach wird der Schlüssel weiter in Spaltenfamilien unterteilt, die wiederum eine Gruppierung von Zellen darstellen. Die Spaltenfamilien werden separat im Speicher und auf der Festplatte gespeichert, und es gibt normalerweise nicht mehr als eine Handvoll pro Tabelle. Spaltenfamilien sind der einzige Teil des Schlüsselschemas, der bei der Erstellung der Tabelle definiert werden muss. Innerhalb einer Spaltenfamilie gibt es eine weitere Unterteilung, den sogenannten Spaltenqualifizierer, von denen es pro Zeile Millionen oder mehr geben kann. Schließlich hat jede Zelle einen Zeitstempel, der eine Version definiert. Mehrere Zellen mit unterschiedlichen Zeitstempeln, aber ansonsten demselben Schlüssel, können als unterschiedliche Versionen gespeichert werden. HBase behandelt jede Komponente des Schlüssels (mit Ausnahme des Zeitstempels) und den Wert als Byte-Arrays. Daher gibt es in HBase keine Beschränkungen für die Typen in einem Teil der Zelle, und HBase ist ein halbstrukturierter Speicher.

In HBase werden die Zellen in der Reihenfolge ihrer Schlüsselkomponenten gespeichert. Sie werden zuerst nach ihrem Zeilenschlüssel, dann nach der Spaltenfamilie, dem Spaltenqualifizierer und schließlich nach dem Zeitstempel sortiert. HBase verwendet eine horizontale Partitionierung, d.h. die Zellen in einer Tabelle werden in Partitionen aufgeteilt, die über den Cluster verteilt sind. Der Bereich der Zeilenschlüssel in einer Tabelle ist in Partitionen unterteilt, die Regionen genannt werden und jeweils für einen nicht überlappenden Bereich der sortierten Zeilenschlüssel zuständig sind. Die Grenzen zwischen den Regionen werden Regionensplits genannt. Wenn du zum Beispiel weißt, dass deine Zeilen Schlüssel mit einem zufälligen alphabetischen Präfix haben werden, könntest du deine Tabelle zunächst mit 26 Regionen erstellen, mit Splits bei b, c, d, ..., v, w, x, y, z. Jeder Schlüssel, der mit a beginnt, kommt in die erste Region, c in die dritte Region und z in die letzte Region. Neue Splits können manuell hinzugefügt werden oder werden von HBase automatisch für ausgelastete Regionen erstellt. Auf diese Weise kann eine Tabelle leicht verteilt und skaliert werden.

Die Lernkurve für die operativen Aspekte von HBase kann steil sein und ist nicht unbedingt etwas für schwache Nerven. Das richtige Design für die Tabelle und die Zellschlüssel ist absolut entscheidend für die Leistung deines bestimmten Anwendungsfalls und Zugriffsmusters. Das richtige Tabellenlayout zu entwerfen, erfordert ein solides Verständnis der Funktionsweise von HBase. Andernfalls kann es zu pathologischem Verhalten kommen, wie z. B. Scans der gesamten Tabelle, Hotspotting von Regionen oder Verdichtungsstürme. HBase eignet sich hervorragend für zufällige I/O-Workloads: gut verteilte Schreib- oder Leseanfragen für relativ kleine Gruppen von Zellen, entweder über Row-Gets oder Range-Scans. Es ist nicht so gut darin, viel größere Scans zu unterstützen, wie sie für analytische Workloads typisch sind. Die Ausführung und Rücksendung an den Kunden ist teuer. Solche Workloads lassen sich in der Regel viel besser direkt mit den HDFS-Dateien selbst durchführen.

Wenn sie gut verwaltet und richtig eingesetzt wird, ist HBase eines der wertvollsten Tools im Ökosystem und kann bei riesigen Datenmengen eine rasante Leistung liefern. Es sollte unbedingt genutzt werden - du musst nur sicherstellen, dass du es für die richtige Sache und auf die richtige Art und Weise verwendest.

Tiefer gehen

Es gibt einige Referenzen, die du unbedingt lesen musst, wenn du HBase ernsthaft nutzen oder betreiben willst:

Bedenke auch

HBase ist nicht der einzige semistrukturierte Speicher, der auf HDFS basiert. Andere sind:

Apachen-Kudu

Einer der Hauptprobleme der traditionellen Hadoop-basierten Architektur ist, dass mehrere Speicher-Engines verwendet werden müssen, um sowohl effiziente Analysen mit hohem Durchsatz als auch Lesezugriffe mit niedriger Latenz auf dieselben Daten zu ermöglichen. Dies führt zu relativ komplexen Ingestions- und Orchestrierungspipelines. In solchen Anwendungsfällen werden HBase oder Accumulo für die Abfragen mit wahlfreiem Zugriff und eine Kombination aus HDFS, Parquet und Impala, Spark SQL oder Hive für die analytischen Workloads benötigt.

Wenn die eingehenden Daten Aktualisierungen bestehender Zeilen enthalten, wird das Bild noch komplizierter, da dies ein komplettes Neuschreiben der Daten im HDFS oder komplexe Abfragen unter Anwendung der neuesten Deltas erfordern kann. Aus diesem Grund haben die Entwickler von Kudu eine Speicher- und Abfrage-Engine entwickelt, die sowohl Zugriffsmuster (random-access und sequentielle Scans) als auch Aktualisierungen bestehender Daten effizient ermöglicht. Um dies zu ermöglichen, sind natürlich einige Kompromisse bei der Leistung unvermeidlich, aber das Ziel ist es, an das Leistungsniveau der jeweiligen nativen Technologien heranzukommen, d.h. Lesevorgänge mit wahlfreiem Zugriff innerhalb von zehn Millisekunden und Dateiscans mit Hunderten von MiB/s durchzuführen.

Kudu ist ein strukturierter Datenspeicher, der Zeilen mit typisierten Spalten in Tabellen mit einem vordefinierten Schema speichert. Eine Teilmenge der Spalten wird als Primärschlüssel für die Tabelle festgelegt und bildet einen Index in der Tabelle, mit dem Kudu Zeilenabfragen durchführen kann. Kudu unterstützt die folgenden Schreiboperationen: Einfügen, Aktualisieren, Upsert (Einfügen, wenn die Zeile nicht existiert, oder Aktualisieren, wenn sie existiert) und Löschen. Auf der Leseseite können Clients einen Scan mit Spaltenprojektionen erstellen und Zeilen durch Prädikate auf der Grundlage von Spaltenwerten filtern.

Kudu verteilt die Tabellen durch horizontale Partitionierung über den Cluster. Eine Tabelle wird durch einen der beiden Partitionierungsmechanismen oder durch eine Kombination aus beiden in Tabletten aufgeteilt. Eine Zeile kann sich nur in einem Tablett befinden, und innerhalb jedes Tablets verwaltet Kudu einen sortierten Index der Primärschlüsselspalten. Der erste Partitionierungsmechanismus ist die Bereichspartitionierung und sollte den Nutzern von HBase und Accumulo bekannt sein. Jedes Tablett hat eine obere und untere Grenze innerhalb des Bereichs, und alle Zeilen mit Partitionsschlüsseln, die innerhalb des Bereichs sortiert sind, gehören zu dem Tablett.

Der zweite Partitionierungsmechanismus ist die Hash-Partitionierung. Die Nutzer können eine feste Anzahl von Hash-Buckets angeben, durch die die Tabelle partitioniert wird, und eine oder mehrere Spalten aus der Zeile auswählen, die zur Berechnung des Hash für jede Zeile verwendet werden sollen. Für jede Zeile berechnet Kudu den Hash der Spalten modulo der Anzahl der Buckets und ordnet die Zeile entsprechend einem Tablet zu.

Die beiden Partitionierungsmechanismen können kombiniert werden, um mehrere Partitionierungsebenen zu schaffen, mit null oder mehr Hash-Partitionierungsebenen (jede hasht einen anderen Satz von Spalten) und einer optionalen Bereichspartition. Die mehrstufige Partitionierung ist für bestimmte Anwendungsfälle, bei denen es sonst zu einem Hotspotting beim Schreiben kommen würde, äußerst nützlich. Zeitreihen werden zum Beispiel immer an das Ende eines Bereichs geschrieben, was bei einer reinen Bereichspartitionierung nur ein Tablett wäre. Durch das Hinzufügen einer Hash-Partition auf einer sinnvollen Spalte können die Schreibvorgänge gleichmäßig auf alle Tablets in der Tabelle verteilt werden und die Tabelle kann skaliert werden, indem jeder Hash-Bucket durch den Bereich aufgeteilt wird.

Bei allen Speicher- und Abfrageprogrammen ist die Wahl des richtigen Schemas und Tabellenlayouts für einen effizienten Betrieb wichtig. Das ist auch bei Kudu nicht anders, und Praktiker müssen sich mit den Kompromissen vertraut machen, die mit verschiedenen Zeilenschemata und Partitionierungsstrategien einhergehen, um die optimale Kombination für den jeweiligen Anwendungsfall zu wählen. Häufige Anwendungsfälle für Kudu sind:

  • Große metrische Zeitreihen, wie sie in IoT-Datensätzen vorkommen

  • Reporting-Workloads auf großen, veränderlichen Datenbeständen, wie z. B. OLAP-ähnliche Analysen auf Sternschema-Tabellen

Tiefer gehen

Der beste Ausgangspunkt, um mehr über Kudu zu erfahren, ist die offizielle Projektdokumentation. Weitere lesenswerte Ressourcen sind:

Apache Solr

Manchmal ist SQL nicht genug. Manche Anwendungen benötigen die Möglichkeit, flexiblere Suchvorgänge in unstrukturierten oder halbstrukturierten Daten durchzuführen. In vielen Anwendungsfällen, z. B. bei der Logsuche, der Dokumentensammlung und der Cybersecurity-Analyse, können Daten über Freitextsuche, Fuzzy-Suche, Facettensuche, Phonem-Matching, Synonym-Matching, Geodaten-Suche und mehr abgerufen werden. Für diese Anforderungen, die oft als Unternehmenssuche bezeichnet werden, brauchen wir die Fähigkeit, Milliarden von Dokumenten und Hunderte von Terabytes an Daten automatisch zu verarbeiten, zu analysieren, zu indizieren und abzufragen. Derzeit gibt es zwei Haupttechnologien in diesem Ökosystem: Apache Solr und Elasticsearch. Wir behandeln hier nur Apache Solr, aber auch Elasticsearch ist eine gute Wahl für den produktiven Einsatz. Beide sind es wert, für deinen Anwendungsfall der Unternehmenssuche sorgfältig untersucht zu werden.

Um seine Suchfunktionen zu unterstützen, verwendet Solr die von Apache Lucene bereitgestellten invertierten Indizes, bei denen es sich einfach um Zuordnungen von Begriffen zu einer Liste passender Dokumente handelt. Begriffe können Wörter, Stämme, Bereiche, Zahlen, Koordinaten und mehr sein. Dokumente enthalten Felder, die die Art der darin gefundenen Begriffe definieren. Felder können in einzelne Token aufgeteilt und separat indexiert werden. Die Felder, die ein Dokument enthält, werden in einem Schema definiert.

Die Struktur der Indexverarbeitung und -speicherung ermöglicht ein schnelles Auffinden von Dokumenten in einer Rangfolge, und eine Reihe von fortschrittlichen Abfrageparsern kann exakten Abgleich, unscharfen Abgleich, Abgleich mit regulären Ausdrücken und mehr durchführen. Für eine bestimmte Abfrage sucht ein Indexsucher nach Dokumenten, die mit den Prädikaten der Abfrage übereinstimmen. Die Dokumente werden bewertet und optional nach bestimmten Kriterien sortiert; standardmäßig werden die Dokumente mit der höchsten Bewertung zuerst angezeigt.

Im Wesentlichen verpackt Solr die Lucene-Bibliothek in einen RESTful-Dienst, der Indexmanagement sowie flexible und zusammensetzbare Abfrage- und Indexierungspipelines bietet. Mit der SolrCloud-Funktionalität kann ein logischer Index für eine skalierbare Abfrageverarbeitung und Indizierung auf viele Rechner verteilt werden. Solr kann seine Indexdateien zusätzlich auf HDFS speichern, um die Ausfallsicherheit und die skalierbare Speicherung zu gewährleisten.

Solr speichert Dokumente in Sammlungen. Sammlungen können mit einem vordefinierten Schema erstellt werden, in dem die Felder und ihre Typen vom Benutzer festgelegt werden. Für Anwendungsfälle, die mit Dokumenten mit beliebigen Namen zu tun haben, können dynamische Felder verwendet werden. Diese legen fest, welcher Typ für Dokumentfelder verwendet werden soll, die einem bestimmten Namensmuster entsprechen. Solr-Sammlungen können auch im sogenannten schemalosen Modus arbeiten. In diesem Modus errät Solr die Typen der gelieferten Felder und fügt neue Felder hinzu, sobald sie in den Dokumenten auftauchen.

SolrCloud ermöglicht die Partitionierung und Verteilung von Sammlungen auf Solr-Servern und damit die Speicherung von Milliarden von Dokumenten und die Unterstützung einer hohen Abfragegleichzeitigkeit. Wie alle Speicher- und Abfrage-Engines hat auch Solr seine Stärken und Schwächen. Im Allgemeinen kann eine gut betriebene und konfigurierte SolrCloud-Bereitstellung verteilte Sammlungen mit Milliarden von Dokumenten unterstützen, aber du musst darauf achten, die Abfrage- und Indexierungslast richtig zu verteilen. Die Stärken von Solr liegen in der flexiblen Abfragesyntax und der Fähigkeit, komplexe Suchabfragen in Sekundenschnelle über Millionen von Dokumenten durchzuführen und dem Kunden schließlich einige Dutzend bis Hunderte von Dokumenten zurückzugeben. Es eignet sich in der Regel nicht für umfangreiche analytische Anwendungsfälle, bei denen Millionen von Dokumenten auf einmal zurückgegeben werden. Und für diejenigen, die nicht ohne sie leben können, unterstützt Solr jetzt einen SQL-Dialekt für die Abfrage von Sammlungen.

Mehr über die Verwendung von Solr in hochverfügbaren Kontexten erfährst du in "Solr".

Tiefer gehen

Wir haben hier nur die absoluten Grundlagen von Solr behandelt. Wir empfehlen dir dringend, die offizielle Dokumentation zu konsultieren, die viel mehr Details über das Schema-Design und den Betrieb von SolrCloud enthält. Auch die folgenden Seiten sind einen Blick wert:

  • Solr in Action, 3rd Edition, von Trey Grainger und Timothy Potter (Manning). Dieses Buch ist zwar etwas veraltet, enthält aber eine hervorragende Beschreibung der Funktionsweise von Solr.

  • Solr 'n Stuff. Der Blog von Yonik Seeley enthält eine Fülle von Hintergrundinformationen zu verschiedenen Solr-Funktionen und einen "Unofficial Solr Guide".

Bedenke auch

Wie wir bereits erwähnt haben, ist Elasticsearch eine gute Alternative zu Solr.

Apache Kafka

Einer der Hauptgründe für einen Cluster ist eine einzige Plattform, die Daten aus einer Vielzahl von Quellen speichern und verarbeiten kann. Die Datenquellen in einem Unternehmen sind vielfältig: Webprotokolle, Maschinenprotokolle, Geschäftsereignisse, Transaktionsdaten, Textdokumente, Bilder und mehr. Diese Daten kommen auf unterschiedliche Weise an, z. B. als Push- oder Pull-Daten, in Stapeln oder als Streams, und in einer Vielzahl von Protokollen: HTTP, SCP/SFTP, JDBC, AMQP, JMS und mehr. Innerhalb des Ökosystems der Plattform gibt es mehrere Senken für eingehende Daten: HDFS, HBase, Elasticsearch und Kudu, um nur einige zu nennen. Die Verwaltung und Orchestrierung des Ingestion in die Plattform in all diesen Modi kann schnell zu einem Design- und Betriebsalptraum werden.

Vor allem bei Streaming-Daten haben die etablierten Message Broker-Technologien Schwierigkeiten, den Anforderungen von Big Data gerecht zu werden. Besonders problematisch ist die Unterstützung von Hunderten von Clients, die alle mit hohen Bandbreiten schreiben und lesen und ihre eigenen Positionen in den Datenströmen beibehalten wollen. Es ist eine Herausforderung, mit diesen Technologien eine skalierbare Lieferung zu gewährleisten und mit Datenrückständen umzugehen, die durch große Mengen an eingehenden Datenströmen oder fehlgeschlagene nachgelagerte Prozesse entstehen. Diese Anforderungen führten direkt zur Entwicklung von Apache Kafka bei LinkedIn.

Tipp

Mehr über die Hintergründe und Beweggründe für eine logbasierte Publish/Subscribe-Architektur erfährst du in "The Log: Was jeder Softwareentwickler über die vereinheitlichende Abstraktion von Echtzeitdaten wissen sollte".

Apache Kafka ist ein Publish/Subscribe-System, das sowohl hinsichtlich des Volumens als auch der Lese- und Schreibbandbreite der Clients horizontal skalierbar sein soll. Die zentrale Idee besteht darin, verteilte, sequenzielle Protokolle als Speichermedium für eingehende Nachrichten zu verwenden und es Clients oder Gruppen von Clients zu ermöglichen, Daten von einem bestimmten Punkt aus mit einfachen numerischen Offsets zu konsumieren. Kafka hat sich zu einer wichtigen Technologie entwickelt, die einen stabilen und hochverfügbaren Ingestion-Puffer bereitstellt, der mehrere Upstream-Quellen und Downstream-Sinks integriert. Die Stream-Verarbeitung und zustandsabhängige Abfrage von Streams wird zunehmend im Kafka-Ökosystem selbst unterstützt, wobei Kafka als System of Record fungiert.

Die grundlegende Datenstruktur in Kafka ist das Topic, eine Folge von Nachrichten (oder Datensätzen), die über mehrere Server (oder Broker) verteilt sind. Jedes Topic kann aus mehreren Partitionen bestehen, von denen jede durch ein Log auf der Festplatte gesichert ist. Um die Ausfallsicherheit zu gewährleisten, haben die Partitionen mehrere Replikate, die auf verschiedenen Brokern liegen.

Nachrichten in Kafka sind Schlüssel-Wert-Paare, bei denen der Schlüssel und der Wert beliebige Byte-Arrays sind. Kunden veröffentlichen Nachrichten über Produzenten in Partitionen von Kafka-Themen. Jede Partition eines Topics ist ein geordnetes und unveränderliches Protokoll. Neue Nachrichten werden sequentiell an das Ende des Logs angehängt, was die I/O-Operation sehr effizient macht. Innerhalb der Partition wird jede Nachricht zusammen mit einem Offset geschrieben, der einen immer größer werdenden Index im Log darstellt. Clients können mit Hilfe von Consumern aus Topics lesen. Um die Skalierbarkeit zu erhöhen, können einzelne Konsumenten zu einer Konsumentengruppe zusammengefasst werden. Die Konsumenten können beim Start ihren letzten bekannten Offset abrufen und einfach dort weitermachen, wo sie aufgehört haben.

Kafka kann auf viele Arten genutzt werden. Am häufigsten wird es als skalierbarer Puffer für das Daten-Streaming zu und von Speicher-Engines auf Hadoop verwendet. Es wird auch häufig als Datenaustauschbus in flexiblen Stream-Processing-Ketten verwendet, in denen Systeme wie Kafka Connect, Apache Flume oder Spark Streaming Daten verarbeiten und ihre Ergebnisse in neue Topics schreiben.

Zunehmend werden Architekturen aufgebaut, in denen Kafka als zentrales System der Aufzeichnungen fungiert und temporäre Ansichten in externen Serving-Systemen wie Datenbanken und Key-Value-Stores erstellt werden. Aus diesem Grund haben wir Kafka als Speicher-Engine und nicht als Ingestion-Technologie eingestuft. Wie auch immer es eingesetzt wird, Kafka ist eine wichtige Integrationstechnologie für Big-Data-Plattformen in Unternehmen.

Tiefer gehen

Es gibt eine Fülle von Informationen über den Hintergrund und die Verwendung von Kafka. Einige gute Adressen für den Anfang sind:

Verschlucken

Es gibt eine Vielzahl von Technologien im Bereich Ingestion - zu viele, um sie in dieser Übersicht zu behandeln. Traditionell sind zwei der wichtigsten Ingestion-Technologien Apache Flume, das auf skalierbare Ingestion für Datenströme ausgerichtet ist, und Apache Sqoop, das sich auf den Import und Export von Daten in relationalen Datenbanken konzentriert. Es gibt jedoch noch viele andere Optionen, die den Prozess der Ingestion-Pipelines vereinfachen und den Bedarf an benutzerdefinierter Kodierung beseitigen.

Zwei bemerkenswerte Open-Source-Optionen sind:

Orchestrierung

Batch-Ingestion- und Analyse-Pipelines bestehen oft aus mehreren voneinander abhängigen Phasen, wobei in jeder Phase unterschiedliche Technologien zum Einsatz kommen können. Wir müssen solche Pipelines orchestrieren und planen und in der Lage sein, ihre komplexen Abhängigkeiten zu beschreiben.

Apache Oozie

Apache Oozie ist das Zeitplanungs- und Ausführungsprogramm für Hadoop. Die grundlegenden Ausführungseinheiten innerhalb von Oozie Aufträgen sind Aktionen, die Aufgaben darstellen, die im Hadoop-Ökosystem ausgeführt werden, wie z. B. Hive-Abfragen oder MapReduce-Aufträge. Aktionen werden in Workflows zusammengefasst, die logische Abfolgen oder Reihenfolgen von Aufgaben darstellen, die zusammen ausgeführt werden müssen. Workflows können über Koordinatoren nach einem Zeitplan ausgeführt werden, der wiederum in Bündeln für die logische Gruppierung von Anwendungen zusammengefasst werden kann. Ein Oozie-Auftrag kann sich auf einen Workflow, einen Koordinator oder ein Bundle beziehen.

Oozie-Aufträge werden über XML-Dateien definiert. Jeder Arbeitsablauf enthält einen gerichteten (azyklischen) Graphen von Aktionen, der im Grunde einem Flussdiagramm der Verarbeitung ähnelt. Koordinatoren legen einen Ausführungsplan für Workflows fest, der auf Zeitintervallen und der Verfügbarkeit von Eingabedaten basiert. Bündel definieren Gruppen von zusammenhängenden Koordinatoren mit einer Gesamtstartzeit.

Die Aufträge werden an den Oozie-Server übermittelt, der das bereitgestellte XML validiert und sich um den Lebenszyklus des Auftrags kümmert. Das bedeutet für die verschiedenen Auftragstypen unterschiedliche Dinge. Für Workflows bedeutet es, dass er die Ausführung der einzelnen Aktionen auf dem Hadoop-Cluster startet und verfolgt und den Graphen der Aktionen durchläuft, bis der Workflow erfolgreich abgeschlossen ist oder ein Fehler auftritt. Für Koordinatoren sorgt der Oozie-Server dafür, dass Workflows gemäß dem Zeitplan gestartet werden, und überprüft, ob alle Eingabedatensätze für die jeweilige Instanz der Workflow-Ausführung verfügbar sind, und hält sie möglicherweise zurück, bis die Eingabedaten bereit sind. Der Oozie-Server führt jeden der in einem Bündel definierten Koordinatoren aus.

Es gibt zwei Arten von Workflow-Aktionen: asynchrone und synchrone. Die meisten Aktionen werden asynchron auf YARN über Launcher ausgeführt. Launchers sind reine Map-Jobs, die ihrerseits einen weiteren Hadoop-Job (z. B. Spark, MapReduce oder Hive) starten können. Diese Architektur ermöglicht es dem Oozie-Server, leichtgewichtig zu bleiben und folglich problemlos Hunderte von Aktionen gleichzeitig auszuführen. Da der Status des Auftrags in einer zugrunde liegenden Datenbank gespeichert wird, kann der Oozie-Server nach einem Neustart dort weitermachen, wo er aufgehört hat, ohne dass laufende Aktionen beeinträchtigt werden. Einige Aktionen werden als so leichtgewichtig angesehen, dass sie nicht über YARN, sondern synchron direkt auf dem Oozie-Server ausgeführt werden müssen. Dazu gehören das Versenden von E-Mails und einige HDFS-Befehle. Oozie-Auftragsdefinitionen und alle zugehörigen Dateien und Bibliotheken müssen im HDFS gespeichert werden, normalerweise in einem Verzeichnis pro Anwendung. Oozie stellt eine RESTful HTTP-API zur Verfügung, die von einem Multithreading-Webserver unterstützt wird, über den ein Benutzer Aufträge einreicht, überwacht und steuert.

Wir behandeln Oozie in Bezug auf die hohe Verfügbarkeit in "Oozie" weiter .

Bedenke auch

Oozie ist nicht jedermanns Sache, und es gibt inzwischen eine Reihe sehr leistungsfähiger Konkurrenten. Sie sind flexibler und benutzerfreundlicher und für Neueinführungen durchaus eine Überlegung wert:

Zusammenfassung

Wir haben in dieser Einführung eine ganze Reihe von Themen behandelt, angefangen bei der grundlegenden Definition eines Clusters, auf die wir im nächsten Kapitel näher eingehen werden. Danach haben wir uns die Kernkomponenten von Hadoop-Clustern, Berechnungsframeworks, SQL-Analyseframeworks, Speicher-Engines, Ingestion-Technologien und schließlich Orchestrierungssysteme angesehen. Tabelle 1-2 fasst die behandelten Komponenten kurz zusammen und beschreibt ihre wichtigsten Funktionen.

Tabelle 1-2. Zusammenfassung der Komponenten
Projekt Beschreibung Verwendet für Hängt ab von

ZooKeeper

Verteilter Konfigurationsdienst

Gemeinsame Nutzung von Metadaten zwischen verteilten Prozessen und verteilten Sperren

-

HDFS

Verteilte Speicherung von Dateien

Skalierbare Speicherung von unveränderlichen Daten

ZooKeeper

YARN

Verteiltes Zeitplanungsprogramm und Ausführungsrahmen

Frameworks, die skalierbare, verteilte Rechenressourcen benötigen

ZooKeeper, HDFS

MapReduce

Generischer Rahmen für verteilte Berechnungen

Batch-Computing-Arbeitslasten

YARN, HDFS

Funke

Generischer Rahmen für verteilte Berechnungen

Batch-, analytische SQL- und Streaming-Workloads

Zeitplannungsprogramm (z. B. YARN oder Mesos), Datenquellen (z. B. HDFS, Kudu)

Bienenstock

SQL-Analytik-Abfrage-Framework

Analytische SQL-Workloads

YARN, Datenquellen (z. B. HDFS, Kudu)

Impala

MPP SQL-Analytik-Engine

Analytische, interaktive SQL-Workloads

Datenquellen (HDFS, Kudu, HBase)

HBase

Verteilter, sortierter Speicher für hierarchische Schlüssel-Wert-Daten

Zufälliger, latenzarmer Lese-/Schreibzugriff auf zeilenbasierte Daten mit strukturierten Schlüsseln

HDFS, ZooKeeper

Kudu

Verteilter Speicher für strukturierte Daten

Kombinierter zufälliger Lese-/Schreibzugriff und analytische Workloads

-

Solr

Enterprise Search Framework

Skalierbare Dokumentenindizierung und Abfrage beliebiger Felder

HDFS, ZooKeeper

Kafka

Verteiltes Pub/Sub-Messaging-Framework

Skalierbare Veröffentlichung und Nutzung von Streaming-Daten

ZooKeeper

Oozie

Zeitplanungsprogramm für den Arbeitsablauf

Regelmäßige und bedarfsgesteuerte Datenverarbeitungspipelines

-

Mit diesem Arbeitswissen sollte der Rest des Buches leichter zu verdauen sein. Wenn du einige Details vergessen hast, kannst du diesen Abschnitt nutzen, um dich wieder mit den wichtigsten Technologien vertraut zu machen.

1 Wie die meisten Open-Source-Projekte vermeiden wir den Begriff " Sklave" wo immer möglich.

Get Architektur von modernen Datenplattformen now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.