- typoblog - http://www.typoblog.de -

Lucene/Solr Revolution – Workshop Day 2 – BigData

Big Search

Nachdem uns Ken gestern einleuchtend beigebracht hat, wie man große Datenmengen in Hadoop hoch parallel als Batch-Vorgang abarbeitet, stellen wir uns heute der Problemstellung: Was mache ich, wenn ich auf meiner großen Datenmenge Anfragen ausführen möchte.

Wir haben gestern bereits kennengelernt, welche auf Hadoop basierenden Technologien existieren, die eine Art Anfragesprache zur Verfügung stellen, welche MapReduce-Jobs generiert und uns ein Ergebnis zurückliefert. Aber d.h. dass jedesmal wenn eine neue Anfrage an das System gestellt werden soll, in der spezifischen Anfragesprache die Ausführung formuliert werden muss und anschließend auf dem Cluster ausgeführt wird.

Nun hier kommt Solr ins Spiel. Solr ist prädestiniert dafür, viele Aggregationen über Felder (Facets) auf jedem beliebigen Filter mit effizienter Sortierung auszuführen. Also genau das, was für brauchen um schnell aus unserer großen Datenmenge Schlüsse zu ziehen.

Nun, da wir uns bereits im BigData-Umfeld bewegen bedeutet das, dass auch der Solr-Index vermutlich nicht mehr auf einen Server passen wird. Wenn ja, hat man Glück gehabt, aber meistens ist das nicht der Fall. Aus diesem Grund gibt es seid Version 4 SolrCloud als Teil von Solr.

SolrCloud [1] ist im Prinzip ein verteiltes Suchsystem, dass sich über das ZooKeeper [2]-Framework (in Solr integriert) organisiert und für die Verteilung, Replikation und Ausfallbehandlung von Nodes kümmert.

Nun stellt sich nur noch die Frage: Wie bekommen wir unsere Daten eigentlich von unserem Hadoop-Cluster, naja eigentlich dem HDFS in Solr? Natürlich auf eine SolrCloud-Umgebung und am besten parallel, denn es soll ja auch schnell gehen.

Workflow Design

Nun bevor wir anfangen einfach einen Importer zu entwickeln, welchen wir vielleicht aufgrund einer übersehenen Anforderung verwerfen müssen, sollten wir strukturiert an die Planung gehen:

  1. Das Ausgabeformat spezifieren (Wie brauch ich es in Solr um die richtigen Fragen stellen zu können?)
  2. Das Eingabeformat kennen (Serialisiert, CSV, TSV, YAML, Avro, etc.)
  3. Den Ablauf (Transformation) entwerfen
  4. Coden

Nun, die Schritte 1 und 2 sind stark abhängig von dem Use-Case und man sollte sich hauptsächlich darüber im Klaren sein, dass während man sich die Aus-/Eingabeformate ansieht, diese sich eventuell ändern könnten, bzw. neue Anforderungen auftauchen, die das Ausgabeformat maßgeblich ändern können.

Spannend wird es bei Schritt 3. Hier hat uns Ken einige Ansätze gezeigt, wie man in Lowlevel Hadoop-Code über verschiedene MapReduce-Patterns zu verschiedenen Lösungen kommt. In der Praxis würde man diesen Workflow mit einem Highlevel-Framework wie Cascading [3] implementieren, welches den Ausführungsplan aus generierten MapReduce-Jobs optimiert, aber für das bessere Verständnis lernen wir wie man es auf die Code-Hard-Methode macht.

Daten im Cluster, aber woher?

Wenn man das Eingabeformat kennt, bedeutet das noch lange nicht, dass man seine Daten auch auf seinem HDFS hat, damit Hadoop an die Arbeit gehen kann. Die Daten können von verschiedenen Quellen wie Logfiles, Datenbanken, Sensoren oder Sonstigen stammen und müssen zuerst einmal in HDFS importiert werden, damit Hadoop loslegen kann.

Leichter gesagt, als getan: schließlich sprechen wir hier von großen Datenmengen >100GB und mehr und das von einem einzelnen Server in den Cluster pushen zu lassen ist nicht nur äußert ineffizient, sondern dauert auch sehr sehr lang.

Hierfür gibt es zum Glück Abhilfe, wie z.B. das Sqoop [4]-Project oder Kafka [5], die genau zu diesem Zweck entwickelt wurden, um dem Cluster auf Basis einer Partitionierung zu sagen, dass er sich parallel die Daten von verschiedenen Quellen holen soll. Aber Vorsicht: selten halten das die Quellsysteme (Datenbank, API) aus, denn so ein Cluster kommt erstmal einer DDoS-Attacke gleich.

Hochskaliertes Indizieren

So, wir haben nun also unsere Daten in Hadoop und können Batch-Jobs starten um die Daten zu transformieren, Aggregieren, etc. Aber wir haben ja vor, beliebige Anfragen in kurzer Zeit zu stellen, also die Daten in Solr zu importieren.

Es gibt nun 4 mögliche Lösungsansätze, wie wir die Daten auf unserem Cluster in Solr indizieren können.

  1. Text-Dateien über den CSV-Importer hochladen
  2. Wie man es üblich auf kleinen Systemen macht über den Data-Import-Handler, bzw. einen eigens geschriebenen Importer, der die Daten per HTTP an Solr sendet
  3. Solr als Embedded Library auf dem Cluster laden und den Index direkt in HDFS bauen. Anschließend die Index Files auf die Solr-Server spielen
  4. Parallele Requests an die SolrCloud schicken über HTTP

Die Lösungen 1 und 2 stellen ihre Nachteile bereits offenkundig zur Schau: Einzelner Thread => Bottleneck. Man denkt also nur über die Lösungen 3 und 4 nach. Nun, beide haben ihre Vor- und Nachteile, aber der einfachste Weg sich zu entscheiden ist folgender:

Benutzt man SolrCloud => Lösung 4
Benutzt man manuelle Shards => Lösung 3

Das rührt vor allem daher, dass in einer SolrCloud-Umgebung die Shards von ZooKeeper auf Basis eines internen Hashing-Algorithmus definiert werden und man nicht vorhersagen kann, wo welche Daten landen würden. Man kann also mit Embedded-Solr keine Shards generieren, die sich auf die von ZooKeeper kontrollierte SolrCloud-Umgebung deployen lassen. (Zumindest nicht ohne manuell in ZooKeeper einzugreifen)

Augmented Search

Ein wichtiger Gedanke, wenn man nun den richtigen Weg gefunden hat, seine Daten in Solr zu bekommen ist, ob es nicht sinnvoll ist, den Hadoop-Cluster dazu zu verwenden, einige Ergebnisse bereits vorab berechnen zu lassen und die Aggregatsergebnisse zusätzlich zu indizieren, damit Anfragen, die auch für Solr schwer zu berechnen sind einfach über ein alternatives Query nach einem bekannten Key (Anhand der Anfrage vorbestimmt) auszuführen.

Hier zeigt unser Trainer wiedereinmal seine langjährige Praxiserfahrung und demonstriert mit welchen Optimierungsverfahren er hier Erfolge erzielt hat und welche Interessanten Umwege bei Solr manchmal zum Ziel führen können.

Praxisübungen

Unser 2 tägiger Workshop endet mit einer sehr Anspruchsvollen, aber dennoch gut vorbereiteten Aufgabe eine Analytics-Engine auf Basis von SolrCloud mit in Hadoop berechneten Daten zu befüllen und anschließend die richtigen Fragen an die Engine stellen zu können.

Hier merkt man, dass sich abstraktes Denkvermögen mal wieder sehr bezahlt macht.

Wir beenden unseren Workshop mit einer kleinen Fragerunde, in der wir die Möglichkeit haben noch einmal aus dem umfangreichen Erfahrungsschatz unseres Trainers zu schöpfen und ihn spontan mit Problemstellungen zu konfrontieren, die uns gerade einfallen. Erstaunlich welche Lösungen wer spontan aus dem Hut zaubern kann und wie gut wir hier bereits mitreden können nach diesen 2 umfangreichen Tagen.

Ich hoffe sehr, dass es mehr solcher Trainer wie Ken da draußen gibt.