Transkripte
1. Einführung: Und ich habe über neun Jahre bei Amazon.com und
IMDB.com damit verbracht , ihre massiven Datensätze zu verstehen. Und ich möchte Sie über die leistungsstärkste Technologie informieren, die ich kenne, um Big Data heute in der Cloud zu streiten. Das ist Apache Spark, mit Scala Programmiersprache Funken und laufen in Hadoop-Cluster, um
massive Datenanalysen und maschinelles Lernen Aufgaben in der Cloud zu verbreiten . Und zu wissen, wie man das macht, ist gerade eine sehr heiße Fähigkeit, wir beginnen mit einem Crashkurs in der Programmiersprache Scala. Keine Sorge, es ist ziemlich einfach, so lange Sie einige Programmierung oder Skripterstellung
getan haben . Wir beginnen mit einigen einfachen Beispielen, arbeiten
aber an komplizierteren und interessanteren Beispielen mit echten massiven Datensätzen. Am Ende dieses Kurses werden
Sie mit mehr als 15 echten Beispielen praxisorientiert sein. Und Sie werden mit dem Schreiben,
Debuggen und Ausführen Ihrer eigenen Spark-Anwendungen mit Scala vertraut sein. Und einige von ihnen sind ziemlich lustig. Wir schauen uns ein soziales Netzwerk von Superhelden an und nutzen diese Daten, um herauszufinden, wer der Kevin Bacon des Superhelden-Universums ist. Wir werden uns auch eine Million Filmbewertungen von echten Leuten ansehen und tatsächlich
eine echte Film-Empfehlungs-Engine erstellen , die auf
einem Spark-Cluster in der Cloud mit dem Elastic MapReduce-Dienst von Amazon läuft . Wir werden auch einige große maschinelle Lernaufgaben mit Sparks ML Lib-Bibliothek erledigen. Und wir werden einige Diagrammanalyse mit Spark GraphX-Bibliothek machen. Also versuchen Sie es mit mir. Ich denke, Sie werden überrascht sein, wie nur ein paar Codezeilen
einen massiven komplexen Datenanalyseauftrag in einem Cluster mit Spark starten können . Also lasst uns anfangen. Als erstes müssen wir die Software installieren, die wir brauchen. Also lasst uns das jetzt aus dem Weg bringen.
2. die Kursmaterialien installieren: Lassen Sie uns also alles einrichten, einschließlich Java und Intelligenz und all die Kursmaterialien, die wir für den gesamten Kurs benötigen. Was wir tun werden, ist, indem wir hier auf unsere eigene Website gehen, die Sie zu den Kursmaterialien weiterleitet, wo Sie
alle Projektdateien und die Daten, die Sie für diesen Kurs benötigen, herunterladen können . Wir werden weitermachen und das in Ihrem System installieren. Dann installieren wir ein Java Development Kit, wenn Sie noch kein haben.
Wir müssen nur sicherstellen, dass wir ein JDK zwischen den
Versionen acht und 14 auf Ihrem System installiert haben . Die Chancen sind, wenn Sie ein Entwickler sind, tun Sie es bereits. Danach installieren wir die IntelliJ idea Community Edition. Es ist eine freie Entwicklungsumgebung, die kann, können
wir für Scala und für Spark verwenden. Und das Schöne daran ist, dass es auch etwas namens sbt integriert. Also bekam einen Griff all die schmutzige Arbeit der tatsächlichen Installation von Apache Spark für uns unter Windows, wir haben einen zusätzlichen Schritt. Wir müssen Fenster vortäuschen, um zu denken, dass es
Hadoop läuft und ich werde Ihnen zeigen, wie man das macht. Es ist nicht zu schwer. Und schließlich werden wir unser Projekt in der Intelligenz einrichten. Führen Sie ein kleines einfaches Helloworld-Problem in Apache Spark aus. Stellen Sie sicher, dass alles funktioniert. Lass uns eintauchen und ich führe dich durch alles. Lassen Sie uns damit beginnen, alles einzurichten, was Sie für diesen Kurs benötigen. Kopf auf über Medien Dotson Hund, ein Bindestrich soft.com Schrägstrich Spark scala dot HTML. Achten Sie auf Großbuchstaben und jeder kleine Buchstabe zählt. Und Sie sollten diese Seite hier erreichen, die alles enthält, was Sie brauchen, um loszugehen. Aber am wichtigsten ist, lassen Sie uns die Kursmaterialien installieren, alle Skripte, die Sie benötigen, um diesen Kurs praktisch durchzugehen. Gehen Sie vor und klicken Sie auf diesen Link hier, um sofort Dotson Hund Bindestrich, soft.com Schrägstrich Spark Scala Slash Spark Scala Kurs dot zip. Wenn Sie das aus irgendeinem Grund manuell eingeben, achten Sie
darauf, auf die Großschreibung zu achten. Sobald das heruntergeladen wird. Wir gehen weiter und entpacken es. Und unter Windows kann ich einfach voran gehen und mit der rechten Maustaste darauf klicken und sagen, alle extrahieren. Auf einem Mac oder Linux würden
Sie natürlich einfach zu einer Terminal-Eingabeaufforderung gehen und den Befehl unzip verwenden. Und wir sollten bekommen, ist ein Funke Scala Kursordner in einem Funken Scala Kursordner, Das ist richtig. Das ist es, was wir wollen. Und innerhalb dieser zweiten Ebene des Ordners sind alle Materialien selbst, das
ganze Projekt für diesen Kurs. Also zuerst, lasst uns das irgendwohin bringen, wo wir es nicht verlieren werden. Also nehme ich den
Gala-Kursordner der obersten Ebene , und ich werde ihn an einen sicheren Ort verschieben. Lass es uns auf mein C-Laufwerk setzen. Ordnung, also jetzt in meinem C-Laufwerk habe ich einen Funke Scala Kursordner. Und darin befindet sich ein weiterer sparks Gala-Kursordner. Und auf Mac oder Linux hätten Sie natürlich kein C-Verzeichnis. Sie würden es in Ihr Home-Verzeichnis einfügen, nur an einem Ort, an dem Sie es nicht verlieren werden. Na gut, als nächstes müssen wir hier einige Testdaten holen. Und leider lassen mich die Lizenzbedingungen der Daten, die ich gerne verwende, diese nicht selbst einbeziehen. Also musst du gehen und das selbst herunterladen. Das ist der MoviElens-Datensatz hier. Um dort 100 Tausend Filmbewertungen einzurichten, die wir nutzen werden, um während dieses Kurses zu spielen. So können Sie diese praktische Dandy Link verwenden, um es Dateien doc Grouplens.org Schrägstrich Daten Schrägstrich Movielens Schrägstrich ML dash 100, k dot zip zu bekommen. Gehen Sie weiter und laden Sie das herunter. Und wenn aus irgendeinem Grund die Grouplens.org Website heruntergefahren ist, passiert
das von Zeit zu Zeit. Normalerweise finden Sie die M L dash 100 K Datei auf Kaggle, wenn Sie müssen. Lasst uns das auch dekomprimieren. Rechtsklick auf Alle extrahieren Auch hier verwenden Sie einfach den Befehl unzip auf Mac oder Linux. Und der resultierende MLH1 100 K Ordner sollte dieses Zeug enthalten. Wir werden diese Ebene hier nehmen und das kopieren. Und ich gehe zurück zu meinem Kursmaterialordner, den ich gerade erstellt habe, die für mich Funken Scala Kurs sehen war. Und in den anderen Sparks Gala-Kursverzeichnis darunter gibt es einen Datenordner. Gehen Sie in den Data-Ordner und dort möchte ich meinen AML-Dash 100 K-Ordner ablegen. Alles klar, so sollten die Dinge an diesem Punkt aussehen, ob Sie auf welchem Betriebssystem Sie sind,
Sie wollen einen Funke Scala Kursordner. Darin sollte es einen anderen Spark Scala Kursordner geben. Darin sollte ein Datenordner sein. Und darin sollte ein ML Dash 100 K Ordner sein. Und darin sollten all diese Testdaten sein. Okay, also stellen Sie sicher, dass alles richtig aussieht, sonst werden Sie auf seltsame Probleme
stoßen und Sie werden nicht wissen, was los ist. Sobald Sie sicher sind, dass das in Ordnung ist, gehen
wir zurück zu unseren Anweisungen hier. nächste Schritt ist die Installation von IntelliJ a, die unsere IDE für die Entwicklung in diesem Kurs sein wird. Jetzt habe ich den Leuten tatsächlich gesagt, dass sie Eclipse und die Scala IDE installieren sollen, aber es scheint, als würde intelligent den Kampf gegen Eclipse gewinnen. Also werde ich Sie jetzt IntelliJ j installieren lassen. Um Scala-Code auszuführen, benötigen
Sie zuerst ein JDK und alles zwischen den Versionen hilft und 14 werden wir für diesen Kurs tun. Aber wenn Sie ein JDK bekommen müssen, gibt es hier einen handy-dandy Link, um es zu tun. Sie können einfach auf Oracle.com Slash Java gehen und gehen Sie weiter und gehen Sie zum JDK 14 Download für Ihr Betriebssystem. Für mich wird das Windows 64. Sie müssen ihre Bedingungen akzeptieren. Und warten Sie, bis das heruntergeladen wird. Sieht so aus, als gäbe es hier eine kleine Sicherheitswarnung. Es ist in Ordnung. Ich vertraue ihm. Und lasst uns das runterkommen. Wir werden weitermachen und es installieren. Offensichtlich unter Linux oder Mac, dass Sie wahrscheinlich eine alternative Möglichkeit verwenden, Java zu erhalten. Tatsächlich haben Sie wahrscheinlich bereits Java installiert, wenn Sie unter Linux oder Mac sind. Also, das ist wahrscheinlich jemand, das spezifische Ding. Wir gehen weiter und gehen hier durch den Installer. Und eine Sache unter Windows ist, dass, wenn Sie Linux-Code wie Apache Spark unter Windows ausführen, es
manchmal verwirrt wird, wenn Sie Leerzeichen in Ihrem Pfad haben. So könnte der Abstand zwischen Programm und Dateien tatsächlich ein Problem sein. Lass uns weitermachen und das ändern, nur um sicher zu sein. Und ich werde dies stattdessen in ein C-Doppelpunkt JDK 14-Verzeichnis sagen. Nun, lassen Sie das sein Ding tun. Es sollte nicht zu lange dauern. Und wir sind fertig. Alles klar, wir sind fertig mit dieser Seite, zurück zu unseren Anweisungen. So können wir jetzt die IntelliJ Idee Community Edition installieren. Das wird unser tatsächlicher Ausweis sein. Gehen wir weiter und klicken Sie auf diesen Link. Und wir wollen die Community-Edition, die kostenlose, die Open-Source-Edition. Wir brauchen nicht das ultimative. Also gehen Sie weiter und laden Sie das für Ihr Betriebssystem herunter. Sie sehen das Angebot, das für Windows, Mac und Linux. Und das ist etwa ein halber Auftritt. Und so brauchen wir ein paar Sekunden, um runter zu kommen. Komm zurück, wenn das fertig ist. Richtig, der Installer hat heruntergeladen und lasst uns weitermachen und loslegen. Und ziemlich Standard-Installer hier. Gehen wir weiter und gehen einfach durch. Und wenn Sie Desktop-Verknüpfungen oder Dateizuordnungen wünschen, können
Sie das ganz nach Ihnen tun. Ich werde die einfach so lassen, wie es ist. Und das ist auch in Ordnung. Es dauert ungefähr eine Minute, um zu installieren, also komme ich einfach zurück, wenn das fertig ist. Na gut, gut. Gehen wir weiter und drücken Sie die Schaltfläche Ausführen, um es tatsächlich zu starten. Ich möchte keine vorhandenen Einstellungen importieren. Und persönliche Vorliebe, wenn Sie ein dunkles Thema oder ein helles Thema mögen, mag
ich ein helles Thema. Also wähle ich das aus, tue, was immer du willst. Und jetzt werden wir Plugins installieren. Vielleicht ist das einzige Plugin, das wir wirklich brauchen, das Scala Plugin. Und leider sehe ich es hier nicht angeboten, also werde ich einfach weitermachen. Ich sehe es hier auch nicht. Wenn Sie also das Scala Plug-in sehen,
gehen Sie weiter und nutzen Sie die Gelegenheit, es zu installieren. Aber ich habe es nicht getan. Also habe ich mit dem harten Weg zu tun, was nicht so schwer ist. Ich klicke einfach auf die Schaltfläche Konfigurieren hier im Willkommensbildschirm und wähle Plugins aus . Und von dort kann ich das Scala Plugin finden. Lasst uns weitermachen und das installieren. Gut. Okay, und wir können die IDE neu starten, um das aufzuheben. Und jetzt noch eine Sache, die wir sagen müssen, welches JDK zu verwenden ist. Gehen Sie also zurück zum Konfigurationsmenü hier und gehen Sie zur Struktur für neue Projekte. Und wenn Sie hier ein JDK auswählen müssen, wählen Sie das, das wir gerade installiert haben, das wird 14 für uns sein und klicken Sie auf OK. Jetzt gibt es einen weiteren Schritt, den wir tun müssen, der nur für Windows ist. Also, wenn Sie auf Mac oder Linux sind, können Sie, Sie können diesen nächsten Schritt ignorieren, wir müssen Art von Trick Fenster zu denken, dass Hadoop läuft darauf. Und um das zu tun, ist es ein bisschen klobig. Die Anweisungen finden Sie auf Ihrer Kursmaterialseite hier unter dem Windows-Abschnitt, folgen Sie
einfach den Anweisungen. Gehen Sie weiter und erstellen Sie ein C Hadoop bin Verzeichnis. Also gehe ich zu meinem C-Laufwerk. Ich werde einen neuen Ordner namens Hadoop erstellen. Und in diesem Hadoop-Ordner werde
ich einen anderen Ordner namens bin erstellen. Jetzt gehe ich zurück zu meinem Kursmaterial, das unter Funken-Galakurs steht. Und Sie werden eine wenn utils dot EXE-Datei dort sehen. Ich werde das kopieren und es in C. Hadoop einfügen. Als nächstes muss ich ein paar Umgebungsvariablen einrichten. Der einfachste Weg, dies zu tun, ist, einfach zu
Ihrer Windows-Suchleiste hier unten zu gehen und Umgebungsvariablen einzugeben. Nur ENV ist wahrscheinlich genug. Wählen Sie Bearbeiten Sie die Systemumgebungsvariablen , die Sie in die Systemsteuerung bringen. Von hier aus können Sie auf die Schaltfläche „Umgebungsvariablen“ klicken. Und wir werden eine neue zu schaffen namens Hadoop Unterstrich Home all caps. Und der Wert wird C Doppelpunkt Backslash, Hadoop. Wir müssen auch unsere Pfadumgebungsvariable bearbeiten. Wenn du keins hast, kannst du eins machen, aber du hast wahrscheinlich schon eins. Also werde ich nur das bearbeiten, das ich einen zusätzlichen Pfad dazu habe indem ich hier doppelklicke und das Prozentzeichen eintippe, Hadoop unterstriche Heimprozentzeichen, Das ist Schrägstrich bin. Drücken Sie wieder OK und OK und wieder OK. Alles klar, jetzt sind wir bereit, wirklich zu versuchen das Projekt für den Kurs selbst zu
importieren. Gehen wir zurück zu IntelliJ. Bevor wir dieses Projekt laden, ist
es immer ratsam, Ihre Anwendungen neu zu starten, nachdem Sie Umgebungsvariablen geändert haben. Also, wenn Sie unter Windows sind, gehen Sie vor und schließen Sie die IntelliJ Idee und starten Sie neu. Es sollte in Ihrem Startmenü sein. Und jetzt werden wir auf Öffnen oder Importieren klicken. Und wir wollen zum Kursmaterialordner navigieren, Scala Kurs und den Funke Scala Kursordner darin,
das ist unser eigentliches Projekt für den Kurs selbst. Schlag in Ordnung. Und lass es sein Ding machen. Es wird automatisch versuchen, aus dem, was in diesem Ordner ist, Sinn zu machen. Ich will kein Trinkgeld geben. Und wenn wir Glück haben, wird alles einfach funktionieren. Ok. Sehen Sie etwas zu alarmierend, lassen Sie uns das Build-Symbol drücken, nur um sicherzustellen, dass es erfolgreich erstellt wurde. Das ist diese kleine Hammer-Symbol hier oben. Sie finden es auch im Build-Menü, wenn Sie es bevorzugen. Und es sieht so aus, als hätte es funktioniert. Also lasst uns eine Chance geben. Gehen wir weiter und öffnen Sie den Spark Scala Kursordner hier für das Projekt, und öffnen Sie dann den Quellordner. Und unter, dass öffnen Sie Haupt, und dann Scala und com dot sun dot software dot funken. Dies sind alle Skripte für den Kurs hier. Alles, was wir tun müssen, ist, einen auszuwählen und zu sehen, ob es funktioniert. Ich habe ein sehr einfaches Helloworld Skript eingebaut. Also lassen Sie uns darauf doppelklicken. Und Sie können hier sehen, dass es nicht viel tut, aber es verwendet tatsächlich Apache Spark. Es wird also tatsächlich überprüfen, ob Sie
alles richtig konfiguriert haben und hier den richtigen Weg einrichten. Es wird nur einen SparkContext einrichten und
die Datendatei in unserem Movielens-Dataset laden , das wir früher installiert haben. Dadurch wird auch sichergestellt, dass Sie das auch am richtigen Ort haben. Alles, was es tun wird, ist
einen Apache Spark-Job zu drehen , um die Anzahl der Zeilen in dieser Datei zu zählen. Also eine sehr komplizierte Art, dies zu tun, aber es wird überprüfen, ob es funktioniert. Und wenn es fertig ist, wird es Hello World ausdrucken. Die Datendatei hat hoffentlich 100 Tausend Zeilen, denn das ist der 100 Tausend Datensatz. Mal sehen, ob es funktioniert. Klicken Sie einfach mit der rechten Maustaste auf HelloWorld und sagen Sie laufen Hallo-Welt. Und an diesem Punkt gibt es eine wirklich gute Chance, dass Sie eine Klasse nicht gefunden Fehler
bekommen, wenn Sie es tun, es ist nur ein Fehler und Intelligenz. Wenn Sie intelligent beenden und neu starten, sollte es es klären. Und das sollte Spark starten. Sie werden sehen, dass einige Warnungen sicher ignoriert werden können. Und jetzt läuft es tatsächlich und es hat funktioniert. Also da hast du es. Helloworld, die Datendatei hat 100.000 Zeilen. Also, wenn Sie das sehen, herzlichen Glückwunsch, Sie richten Spark und Scala und Intelligenz in Java alle erfolgreich ein. Und alles funktioniert. Und jetzt müssen wir nur den Rest dieser Skripte
während des gesamten Kurses durchlaufen und darüber reden, was sie tun und lernen. Wenn Sie diese Ausgabe jedoch nicht gesehen haben, gehen Sie zurück, Sie haben wahrscheinlich irgendwo ein wenig Flecken verpasst. Es gibt immer etwas Kleines und fühlen sich frei, in der Q
und ein oder Kommentare dieses Kurses zu posten , um Hilfe zu erhalten, wenn Sie es brauchen. Aber hoffentlich funktioniert das für Sie und wir können weitermachen und anfangen zu lernen.
3. Einführung in Apache Spark: Also lassen Sie mich Ihnen Apache Spark auf einem hohen Niveau vorstellen und nur darüber reden, wie es funktioniert und was es wirklich schnell ist. Die offizielle Beschreibung von Spark ist also, dass es sich eine schnelle und allgemeine Engine für die Verarbeitung großer Datenmengen handelt. Und nun, das ist eine ziemlich gute Beschreibung. Grundsätzlich ist die Idee, dass Sie
möglicherweise ein sehr einfaches Skript schreiben können , das beschreibt, wie Sie eine große Menge an
Daten transformieren oder eine riesige Menge an Daten analysieren und
herausfindenmöchten Daten transformieren oder eine riesige Menge an Daten analysieren und
herausfinden , wie Sie diese Arbeit über eine ganze Cluster von Computern für Sie. Es ist also eine Engine, um herauszufinden, wie Sie die Verarbeitung Ihrer Daten parallelisieren können. Du kannst ihm immer noch sagen, was du willst. Wissen Sie das? Möchte ich eine Reihe von Protokolldateien aufnehmen und einige Informationen
extrahieren und sie woanders ablegen? Gut. Spark wird herausfinden, wie Sie das in
Ihrem gesamten Cluster tun können und dies so schnell wie
möglich mit den Ressourcen von Dutzenden oder sogar Hunderten von einzelnen Maschinen tun, um dies zu tun. Der Schlüssel dazu ist also seine Skalierbarkeit. Also nochmal, Sie schreiben nur ein einzelnes Treiberprogramm, wir nennen es. Es ist genauso einfaches Skript, das entweder in Scala oder Python oder Java geschrieben wurde. Das sagt Spark, was Sie mit Ihren Daten tun möchten. Es ist dann Sparks Problem herauszufinden, wie man das parallelisiert und es fast eine ganze Flotte von Computern skaliert. Die Schlüsseleinsicht hier ist also, dass Sie nicht auf
die Rechenleistung einer Maschine hier mit Apache Spark beschränkt sind. Sie können
einen massiven Datensatz nehmen, den Sie nicht hoffen konnten, auf einem einzigen PC zu verarbeiten und diese Verarbeitung tatsächlich zu
verteilen über eine ganze Computerflotte parallel zur gleichen Zeit. Diese Art von Dividen- und Eroberungsansatz ist, wie wir
massive Datensätze verarbeiten und verarbeiten können , was wir Big Data nennen. Aus architektonischer Sicht ist
Ihr Treiberprogramm nur etwas, das Sie schreiben. Wie ich schon sagte, es ist ein verschiedenes, möglicherweise ein sehr einfaches Skript. Und das wird an einen Cluster-Manager eines Ladens weitergegeben. Sie benötigen ein System, das Ihren gesamten Computercluster orchestriert. Und das könnte ein Hadoop-Cluster sein, in diesem Fall würde Hadoop's Garncluster-Manager dort ins Spiel kommen. Und das wird besorgniserregend sein, wie man die benötigten Ressourcen spinnen
kann, wie man diese Arbeit verteilt und wo man die verschiedenen Jobs am besten findet. Denkt an Dinge wie wie führe ich den Code an der
Stelle aus, an der die Daten am besten zugänglich sind? Also, wenn meine Daten zum Beispiel auf einem verteilten Dateisystem aufgeteilt sind, könnte
der Cluster-Manager sagen, okay, ich werde die Daten ausführen, die
diesen Teil der Daten auf demselben Computer verarbeiten , um es sogar laufen zu lassen
schneller. Sie müssen Hadoop jedoch nicht verwenden. Spark verfügt auch über einen eigenen integrierten Cluster-Manager. Wenn Sie Spark nur in einer eigenständigen Umgebung ausführen möchten, können
Sie das tun, um Spark und
jeden Computer in Ihrem Cluster zu installieren und richtig zu konfigurieren. Und es wird einfach so funktionieren Spark und laufen auf eigene Faust. Es muss nicht unbedingt auf Hadoop laufen, obwohl es möglich ist. Manchmal möchten Sie andere Hadoop-Anwendungen auf
demselben Cluster ausführen und komplexere Pipelines von Vorgängen festlegen. Es kann also Vorteile geben, um tatsächlich auf Hadoop zu laufen, aber Sie müssen es nicht. Also eine einzelne Maschine, es gibt verschiedene Knoten, die wir sie nennen. Und diese werden verschiedene Executoren laufen. Und jeder Führungsprozess, der im gesamten Cluster verteilt werden kann verfügt über einen eigenen Cache und hat eine eigene Aufgabe, die versucht, mit Ihren Daten zu arbeiten. Und Sie können mit all den Pfeilen hier sehen , dass so ziemlich alles miteinander spricht. Ihr Treiberprogramm sendet Befehle an den Cluster-Manager und bei Bedarf auch direkt an die Executoren. Und die Executoren sprechen miteinander und synchronisieren sich untereinander. Und natürlich spricht ein Cluster-Manager auch mit all diesen Executor-Prozessen und versucht zu orchestrieren. Was wird ausgeführt, wo und dann kollidiert diese Ergebnisse wieder zusammen, um Ihr Endergebnis anzuzeigen, wenn alles fertig ist. Das ist also die sparc-Architektur auf einem sehr hohen Niveau. Warum ist Spark so beliebt? Nun, Spark ist so ziemlich ersetzt. Hadoop MapReduce, weil es bis zu 100 Mal
schneller sein kann , wenn es auf der Ausführung im Speicher basiert. Wenn Sie also genügend Speicher in Ihrem Cluster haben, ist
das eine realistische Annäherung. Wenn Sie tatsächlich Daten direkt von der Festplatte lesen, wird
es immer noch etwa 10-mal schneller sein. Warum ist es so viel schneller als MapReduce? Nun, es ist wegen dem, was wir eine gerichtete azyklische Graph-Engine oder einen DAG-Motor nennen. Grundsätzlich wird es sich den Workflow ansehen, den Sie in
Ihrem Treiberskript beschrieben haben , und es wird das automatisch für Sie optimieren. Im Gegensatz dazu sind
Sie in MapReduce irgendwie in eine einzige Denkweise für die Verarbeitung von Daten verkeilt. Sie müssen alle Ihre Daten explizit parallel zuordnen und dann eine Möglichkeit definieren, diese Daten in eine endgültige Antwort zu reduzieren. Mit dem DAG-Motor
kann jedoch ein wenig flexibler sein. Es kann diesen Workflow auf
eine komplexere und potenziell optimalere Art und Weise organisieren . Und weil Spark speicherbasiert ist, bietet
das auch einen sehr großen Vorteil. So ist es schnell und es ist auch sehr einfach zu bedienen. Es ist auch heiß, es ist eine sehr weit verbreitete. Dies ist eigentlich eine sehr alte Liste von Leuten, die Spark verwenden, und es gibt viele,
viele, viele, viele, viele mehr Leute, die es jetzt benutzen. Aber der Sinn dieser Folie ist nur, Ihnen zu zeigen, dass es bewährte Technologie ist. Es wird von sehr großen Konzernen benutzt. Es ist eine sehr ausgereifte Technologie. Es ist schon eine Weile draußen. Wissen Sie, die neuen Funktionen in Spark oder eine Art von Verlangsamung ein wenig, zumindest in der Open-Source-Welt. Und das ist in Ordnung, weil es so ziemlich alles tut, was Sie tun müssen, und es tut es an dieser Stelle ziemlich zuverlässig. Für die verteilte Datenverarbeitung ist
Spark eine ausgereifte Technologie, die sehr weit verbreitet ist. Es ist auch nicht so schwer. Sie haben also Ihre Wahl, Ihren Code in Python oder Java oder Scala zu schreiben. Offensichtlich werden wir uns in diesem Kurs auf
Scala konzentrieren und wir werden in einem Moment darüber sprechen, warum. Aber es ist einfach zu verwenden, wenn Sie SQL Structured Query Language kennen, das ist die gleiche Sprache, die Sie für die Schnittstelle mit jeder relationalen Datenbank verwenden. Sie werden sich wie zu Hause fühlen, weil Spark Funktionen hat, die Spark Datasets und
Spark DataFrame genannt werden, die sehr ähnlich wie SQL-Anweisungen funktionieren. Und Sie können ihm sogar SQL-Befehle direkt über eine Funktion namens Spark SQL geben. Wenn Sie SQL kennen, können Sie Spark verwenden. Es ist einfach so einfach. Aber nicht alles ist ein SQL-Problem. Nicht jede Datenanalyse oder Transformation kann über einen SQL-Befehl definiert werden. Und wenn Sie zu einer niedrigeren API auf niedrigerer Ebene gelangen möchten, die für die ursprüngliche API für
Spark verfügbar ist , heißt Resilient Distributed Dataset oder kurz RDD. Wir werden viel tiefer darüber eingehen, wie das in einem Moment hier funktioniert. Aber mit der RDD-API können
Sie eine niedrigere Ebene erhalten und manchmal kann ich Ihnen noch bessere Leistung geben. Und es gibt Ihnen auch mehr Flexibilität bei dem, was Sie tun können. Aber für die meisten gängigen Datentransformations- oder Analyseaufgaben können
Sie dies wahrscheinlich als SQL-Befehl definieren. Und in den meisten Fällen verwenden
Sie Datasets, Datenrahmen oder die Spark SQL-API. Aus Sicht der Softwarearchitektur ist
dies, wie Spark angelegt ist, und dies geht zurück auf die ursprüngliche Architektur von Sparks. Die Linien sind in den letzten Jahren auf ein paar davon verschwimmen. Aber in seinem Kern ist, naja, Spark Core und das ist, wo RDD's leben in dergleichen, richtig? Also, das ist irgendwie wie die zugrunde liegende Engine von Spark selbst. Und Sie können direkt zu Funken Core gehen. Nun, das werden wir in Aktion sehen. Aber es gibt diese anderen höherwertigen APIs, die auf
Spark Core basieren , um Ihnen das Leben für bestimmte Aufgaben zu erleichtern. Wenn sein Spark Streaming, das heißt,
es ist offensichtlich eine sehr leistungsfähige Technologie für die Erfassung von Daten in Echtzeit oder nahezu in Echtzeit. Sie könnten sich zum Beispiel vorstellen, dass eine Flotte von Servern auf Ihrer Website läuft, die Daten in Spark durch Spark Streaming von ihren Protokolldateien kontinuierlich
einspeisen. Und in Echtzeit kann spark diese Daten überwachen, sich ein Fenster dieser Daten im Laufe der Zeit ansehen, Ihnen Analysen über dieses Zeitfenster
geben und einige darauf basierende Maßnahmen ergreifen. Einfaches Beispiel, sagen wir, Sie möchten
eine Art Alarm auf 500 Fehler auf Ihrer Website haben. Sie können ein Spark-Streamingsystem einrichten ,
so dass die Protokolle in Apache Spark gestreamt werden. Und in Echtzeit zählt es, wie viele 500 Fehler es in der Vergangenheit gibt,
unsere letzte Minute, was auch immer Sie überwachen
und Maßnahmen ergreifen möchten , wenn es einen Schwellenwert überschreitet. Und natürlich sind auch viel komplexere Operationen verfügbar. Vielleicht wäre eine häufigere Anwendung , diese Protokolldaten zu
transformieren und sie woanders zu platzieren. Also könnte ich einen Spark-Streaming-Prozess haben, der Daten aus meinen Protokollen
aufnimmt, sie in ein Format umwandelt, das Elastic Search sehen möchte oder so etwas. Wir haben auch Spark SQL und die existieren, damit Sie mit
Spark SQL-Befehlen integrieren können, damit Sie
Funken wie eine riesige Datenbank behandeln können , die in der Natur verteilt ist. Wenn Sie also Ihre Daten in Form einer Tabellenstruktur definieren können, die Sie normalerweise können, und Sie können das Problem, das Sie lösen möchten, in
Bezug auf einen SQL-Befehl definieren , den Sie wahrscheinlich können. Sie können einfach Spark SQL verwenden, um zu definieren, was Sie tun möchten. Und funkeln Sie, wie Sie das über eine ganze Flotte von Computern parallelisieren können. Das ist also wirklich aufregend, oder? Es gibt Ihnen die ganze Flexibilität einer relationalen Datenbank. Aber du bist nicht mehr auf eine Maschine beschränkt. Sie können diese Datenbank tatsächlich horizontal skalieren. Nun, es war früher, dass Sie zwischen wie NoSQL-Datenbanken wählen mussten, wenn Sie wollen, verteiltes Computing und einer großen monolithischen relationalen Datenbank, wenn Sie es nicht taten. Und es gibt hier noch einige Einschränkungen. Wenn Sie große Joins machen, wird es in einer horizontal partitionierten Serverumgebung immer noch nicht sehr
effizient sein . Aber du kannst es tun, wenn du schreiben willst. Es ist also irgendwie das Beste aus beiden Welten. Nun, wie ich bereits erwähnt habe, sind die Linien hier in einigen Fällen unscharf. Also diese moderneren APIs, die wir später
in Spark mit Datenrahmen und Datasets betrachten werden. Sie sind auch SQL in ihrer Struktur und ihrer Verwendung sehr ähnlich. Also, wissen Sie, tut das, betrachten Sie Datenrahmen und Datasets als Teil von Spark SQL oder Spark Core. Auch hier verschwommen die Zeilen dort irgendwie, aber die SQL-basierten Schnittstellen werden irgendwie zur vorherrschenden Art der Verwendung von Spark. Wir haben auch ML Lib, Sparks Machine Learning Library. Und wenn Sie verteiltes
maschinelles Lernen auf Apache Spark durchführen möchten , können Sie das auch tun. Es ist ein etwas begrenzter Satz von Algorithmen, obwohl es die meisten, die Sie in der Praxis benötigen würden. Also schauen wir uns das auch in einem späteren Abschnitt des Kurses an. Und das ist wirklich aufregend, oder? Denn wenn Sie über maschinelles Lernen verfügen, das Sie auf einem massiven Dataset verarbeiten möchten, sind Sie nicht
mehr auf das beschränkt, was Sie auf einem einzelnen Computer tun können? Es gibt einige Algorithmen,
die bis heute schwer zu skalieren sind, aber Spark hat es für viele
der beliebtesten maschinellen Lernalgorithmen herausgefunden , die Sie vielleicht verwenden möchten. Und schließlich, dieser Graph X, will nicht zu viel darüber reden. Es ist irgendwie am Wegesrand gefallen. Graphx geht es nicht um, du weißt schon, Diagramme und Graphen drucken, du weißt schon, kleine Linien und solche Sachen. Es sind mehr Graphen im Sinne der Informatik. Wir reden also über Netzwerke von Informationen. Ein soziales Netzwerk, in dem Sie
Benutzer haben, die mit anderen Benutzern verbunden sind, ist beispielsweise ein Diagramm in diesem Sinne. Und Grafiken können Dinge wie, Sie wissen, diese Diagramme von Informationen analysieren, Ihnen Attribute darüber
erzählen und Sie diese in einer verteilten Weise durchlaufen lassen. Dieser Graph x ist, wieder irgendwie auf der Strecke gefallen. Es wurde in letzter Zeit nicht wirklich gut gepflegt und es gibt neuere alternative APIs heutzutage, die beliebter sind. Wir werden am Ende des Kurses mehr darüber reden. In diesem Kurs verwenden wir die Programmiersprache Scala. Warum benutzen wir Scala? Das ist irgendwie eine obskure Sprache, nicht wahr? Nun, es gibt ein paar Gründe. Eine davon ist, dass Spark selbst in Scala geschrieben ist. Indem Sie also Ihre Skripte in Scala schreiben, Sie irgendwie näher an, wie Spark selbst optimiert geschrieben wird. Also, Sie wissen,
dass, Das kann potenziell zu einer besseren Leistung führen. Die andere Sache ist, dass Scala ist, was wir eine funktionale Programmiersprache nennen. Und als solches ist es wirklich gut für die verteilte Verarbeitung geeignet. Scala erzwingt wirklich, dass Sie Ihren Code so schreiben , dass Ihre Funktionen über einen gesamten Cluster verteilt werden können. Während andere Sprachen wie Java und Python nicht wirklich versuchen, Sie dazu zu zwingen. also Ihre Spark-Treiberskripte in Scala schreiben, schreiben
Sie wahrscheinlich Code, der sicher und einfach parallelisiert werden kann. Es gibt Ihnen auch eine schnelle Leistung. So skalieren Sie es bis zu Java-Byte-Code kompiliert. Am Ende des Tages läuft es auf der JVM, dem Java-Interpreter, und das ist ziemlich schnell auf den meisten Systemen. Offensichtlich wird Java Ihnen auch eine schnelle Leistung bieten
, da dies auch auf Java-Byte-Codes kompiliert wird. Aber Kontrast dazu, dass Sie Ihre Spark-Skripte in Python schreiben, was Sie tun können. Aber du musst dort eine andere Schicht durchlaufen, richtig? So muss Python-Code am Ende des Tages irgendwie in Java-Bytecode
umgewandelt werden. Also, wenn Sie in Scala schreiben, bringen Sie ein wenig näher an die ultimative niedrigere Ebene, wo Ihr Code tatsächlich läuft. fair zu sein, Python ist heutzutage ziemlich verdammt schnell in Spark. Der Unterschied ist also nicht so groß wie früher, aber es gibt immer noch einen kleinen Unterschied. Der andere Vorteil von Scala, wenn Sie es gegen Java setzen möchten,
ist, dass es einfacher zu bedienen ist. Es wird also viel weniger Code geben. Sie müssen viel weniger Boilerplate-Zeug schreiben, als Sie schreiben
müssten, wenn Sie in Java codieren. Java hat viel Overhead damit verbunden, wie Sie diesen Code tatsächlich kompilieren und verteilt und so etwas. Es ist viel einfacher in Scala stellt sich heraus. Und wie ich sagte, im Vergleich dazu, Python langsamer, ist es nicht so langsam, wie es früher war. Mit Scala wirst du immer noch ein bisschen einen Vorteil bekommen, aber dieser Geschwindigkeitsvergleich hat sich im Laufe der Zeit geschlossen. Aber wo sind die Nachteile von Scala? Nun, eins ist, dass Sie Scala vielleicht noch nicht kennen. Weißt du, es ist keine sehr verbreitete Sprache. Also wirst du gehen müssen, um die Grundlagen des Hauses Gallo zu lernen,
aber es ist nicht so schwer, wie du denkst. Schauen wir uns zum Beispiel diesen kleinen Codeausschnitt an. Wir machen das Gleiche hier in Python und in Scala. Wir werden nur gerne Code schreiben, um die Zahlen in einem Datensatz zu quadrieren. Ziemlich einfaches Zeug. Also in der Python Version und der Scala-Version, wenn Sie es sich ansehen, sind sie nicht so anders, oder? So syntaktisch gibt es kleine Dinge wie, weißt du,
du musst in Scala erklären, dass es eine
unveränderliche Konstante ist , die du verwendest, indem du val sagst. Die Syntax zum Definieren einer Liste von Sachen ist etwas anders. Die Syntax für Lambda-Funktionen ist ein bisschen anders, aber es ist die gleiche Idee, richtig? Scala ist also eine Art seltsame Syntax. Manchmal kann es ein bisschen rückwärts und wir werden darüber reden. Mach dir keine Sorgen darüber. Aber am Ende des Tages sieht es nicht so viel anders aus als Python Code im Kontext eines Spark-Treiber-Skripts. Und damit, lasst uns tatsächlich in einen Crashkurs in Scala eintauchen, wenn du ihn brauchst. In diesem nächsten Abschnitt gehen wir tatsächlich auf die Grundlagen von Scala. Was ist daran anders, was ist seltsam daran? Ich erwarte, dass Sie einige frühere Erfahrungen mit dem Schreiben von Code irgendwo,
einer Skript- oder Programmiersprache haben werden. Ich bin nicht hier, um dir beizubringen, wie man Jungs von
Grund auf programmiert . Das wäre ein anderer Kurs. Aber wenn Sie etwas Python unter Ihrem Gürtel
oder C oder Java oder so haben , denke
ich, Sie können ziemlich schnell aufheben, skalieren. Also in diesem nächsten Abschnitt, wenn Sie es brauchen, haben
wir eine kleine Einführung in Scala, die die Syntax für Sie entmystifizieren wird. Und während wir den Kurs durchlaufen, werden
Sie viele und viele Beispiele für die Verwendung von Scala sehen. Und ich denke, es wird einfach reinsinken, wenn man es genug ansieht und genug Beispiele sieht. Also lasst uns in unseren Scala Crashkurs eintauchen, wenn du ihn brauchst. Wenn Sie nicht das Gefühl haben, den nächsten Abschnitt zu überspringen und wir werden einfach direkt in die Funktionsweise von Spark eintauchen.
4. [Aktivität] Scala: Hi, ich bin Frank Cane und willkommen in meinem Büro. Wir werden damit beginnen, einen kleinen Crashkurs
auf der Scala Programmiersprache selbst zu machen . Nun offensichtlich, wenn Sie bereits mit Scala vertraut sind, können
Sie diesen Abschnitt überspringen und das ist in Ordnung. Aber wenn Sie neu in Scala sind, aber Sie bereits einige Programmiererfahrung hatten, finden
Sie einen Abschnitt, der sehr hilfreich ist, um
den Code zu verstehen , den wir während dieses Kurses betrachten werden. Es ist gerade genug, um gefährlich zu sein, oder? Erwarten Sie also keine umfassende Einführung in den Scala-Kurs hier in diesem Abschnitt, aber es ist genug, um Sie zumindest durch diesen Kurs und durch
die Beispiele zu bekommen , die wir in diesem Abschnitt und die Beispiele später im Kurs durchlaufen werden. Ich denke, Sie werden diesen Kurs mit einem ziemlich guten Verständnis dafür beenden, wie Scala funktioniert und sogar, wie Sie Ihren eigenen Scala-Code schreiben. Wenn Sie jedoch neu in der Programmierung sind, wird
das nicht genug für Sie sein. Ich möchte Sie ermutigen, einen Einführungskurs über
Scala zu finden , der zuerst in die Tiefe geht und dann wieder zu diesem zu kommen. Aber für den Rest von euch, lasst uns weiter pflügen und Scala lernen. Alles klar, lasst uns Scala lernen, nur um Erwartungen zu setzen. Du wirst kein Scala-Experte sein, wenn du mit mir nach Videos schaust. Was ich hier wirklich versuche, ist, Sie mit der Syntax der
Scala Programmiersprache vertraut zu machen und einige
der grundlegenden Konstrukte einzuführen , wie z. B. wie rufe ich eine Funktion in Scala auf? Was sind Flusssteuerungsarbeiten, bei denen einige grundlegende Datenstrukturen, die ich mit Scala verwenden könnte, Ihnen genug Scala-Code
zeigen, dass es Ihnen nicht beängstigend und
einschüchternd aussehen wird , während wir den Rest des Kurses durchlaufen. Lassen Sie uns also zuerst über Skala auf hohem Niveau sprechen. Vor allem, warum lernen Scala? Nun, Sie haben wahrscheinlich noch nie davon gehört. Vielleicht haben Sie das, aber Sie wissen es sicher nicht. Es wird hauptsächlich für Spark-Programmierung verwendet. Aber es ist einzigartig für spar geeignet, weil es wirklich so strukturiert ist, dass es sich für die verteilte Verarbeitung von Daten über einen Cluster eignet. Und Sie werden sehen, warum ein wenig später. Es ist auch, was Spark selbst gebaut ist. Indem Sie Scala lernen, erhalten
Sie Zugriff auf die neuesten und besten Funken-Funktionen, sobald sie herauskommen. Und es kann normalerweise ziemlich lange dauern, bis diese Funktionen durchlaufen,
um Python-Unterstützung in Spark zu sagen. Und es wird auch der effizienteste Weg sein, Spark-Code selbst auszuführen. Mit Scala haben
Sie also die schnellsten und zuverlässigsten Spark-Jobs, die Sie möglicherweise erstellen können. Und ich denke, du wärst ziemlich überrascht, wie viel schneller und zuverlässiger. Derselbe Spark Job, der in Scala geschrieben wurde, wird verglichen mit
dem gleichen Spark Job, der in Python geschrieben wurde. Auch wenn es verlockend sein könnte, zu gehen
und sich an die Sprache zu halten, die Sie bereits kennen. Scala zu lernen ist die Mühe wert und es ist wirklich nicht so schwer. Die Wahrheit ist der gleiche Spark-Code für Scala und Python sehen sich am Ende des Tages sehr ähnlich. Jetzt läuft Schädel selbst auf der virtuellen Java-Maschine. Es kompiliert also nur auf Java-Byte-Code und wird von der JVM ausgeführt. Eine nette Sache daran ist, dass Sie auch Zugriff auf alle Java haben. Wenn es eine Java-Bibliothek gibt, die Sie in Ihren Scala-Code ziehen möchten, können Sie das tun. Sie sind also nicht auf das beschränkt, was in der Scala-Sprache selbst ist. Sie können tatsächlich bis zur Java-Ebene erreichen und hochziehen. Es ist ein Job, den Sie auch verwenden möchten. Und das werden wir später in diesem Kurs tun, zum Beispiel
für den Umgang mit regulären Ausdrücken in ein wenig intuitiver Angelegenheit, als Sie sonst könnten. Ein weiterer wichtiger Punkt über Scala ist, dass es sich um das, was funktionale Programmierung genannt wird, konzentriert. Wo Funktionen der Kern dessen sind, womit wir es zu tun haben. Funktionen werden an andere Funktionen übergeben und auf eine Weise
miteinander verkettet , die Sie möglicherweise nicht gewohnt sind. Aber so funktioniert Spark wirklich auf einer grundlegenden Ebene. Wir nehmen grundsätzlich eine Abstraktion über einen Datenblock und weisen ihm eine Funktion zu, um diese Daten zu verarbeiten. Und funktionale Programmierung in Scala macht das sehr intuitiv aus sprachlicher Sicht zu tun. Alles klar, also springen wir direkt in das tiefe Ende des Pools und sinken oder schwimmen mit Scala, wir werden einfach Code schreiben und sehen, was passiert und deine Hände schmutzig machen. Jetzt habe ich Ihnen nicht wirklich eine Kopie dieses Codes zur Verfügung gestellt, den ich
durchmachen werde , weil es tatsächlich einen Wert gibt und ihn selbst tippt, um eine Art Sinken zu machen. Beginnen wir also mit dem Erstellen eines neuen Scala-Arbeitsblatts. Dies wird uns eine interaktive Umgebung geben, in der wir einfach irgendwie mit Scala-Code
experimentieren und interaktiv ausgewertet werden können . Also gehen Sie zu Ihrem Datei-Menü und Intelligenz und sagen New Scala Arbeitsblatt. Und wir nennen das hier „Scala eins lernen“. Und in diesem ersten Vortrag werden
wir nur über die Syntax und Struktur
der Scala-Sprache sprechen , weil es im Vergleich zu anderen Sprachen etwas seltsam ist. Also zuerst, wenn Sie einen Kommentar wünschen, können
Sie einfach einen doppelten Schrägstrich machen, wie Sie es in vielen anderen Sprachen tun würden. Und zuerst werden wir über Werte sprechen. Werte sind also unveränderliche Konstanten. Das ist also ein Beispiel für eine Kommentarzeile. Jetzt in anderen Sprachen haben wir das Konzept der Variablen. Weißt du, es ist eine sehr universelle Sache und Programmierung, einer benannten Variablen einen Wert
zuzuweisen, oder? Und wie verwenden Sie das in Ihrem Code. Jetzt in Scala gibt es zwei verschiedene Arten, wenn es
Werte genannt wird , die unveränderlich sind und Variablen, die unveränderlich sind. Und in Scala möchten Sie so weit wie möglich bei Werten bleiben. Hier ist ein Beispiel, wie man eine definiert. Wir könnten Val für Wert sagen, Hallo, Doppelpunkt, Zeichenfolge gleich Zitat Ola. Und wenn Sie das tatsächlich ausführen wollen, können
wir hier einfach einen kleinen Play-Button drücken. Oder Sie können sehen, dass es auch eine Tastenkombination von Control Alt W gibt, die ich von nun an verwenden werde. Und es schafft eine Umgebung, um das in jetzt und da haben wir es auszuführen. So können Sie sehen, dass es
diesen Befehl tatsächlich ausgeführt und den Wert o law einer Zeichenfolge namens Hello zugewiesen hat. Also lassen Sie uns einige Zeit damit verbringen, über die Syntax hier zu sprechen weil sie irgendwie rückwärts von vielen anderen Sprachen ist, richtig? Also beginnen wir damit, dass dies ein Wert ist. Das bedeutet, dass wir eine unveränderliche Konstante definieren. Sobald wir definiert haben, was Hallo ist, können
wir es nie wieder ändern. Also werden wir diesen Wert Hallo nennen. Und dann nach dem Doppelpunkt müssen wir erklären, welcher Typ es ist. Also sagen wir, dass hallo ein String-Typ ist. Das ist also rückwärts von den meisten anderen Sprachen, richtig? Normalerweise sehen Sie wie String hallo, aber in Scala ist es hallo, Doppelzeichenfolge. Und dann weisen wir es einem Wert zu. Nichts zu seltsam. Sie sind nur die Zeichenfolge Hola in Anführungszeichen. Okay, also ergibt das Sinn, richtig? Ist ein bisschen rückwärts, aber man gewöhnt sich ziemlich schnell daran. Lassen Sie uns nun über Variablen sprechen. Variablen sind also unveränderlich. Das bedeutet, dass Sie sie tatsächlich ändern können, nachdem Sie sie definiert haben. Um also eine Variable zu definieren, ist es das Gleiche. Sie verwenden einfach eine var anstelle eines Val. So können wir var hallo sagen, was auch eine Zeichenfolge ist, und wir werden das auf Hallo setzen. Wir werden das dem Wert der konstanten Zeichenfolge zuweisen, der
unveränderlichen Konstante hallo. Also werde ich sagen Control Alt, W. Und Sie können dort sehen, dass hallo dort den String-Wert o
law zugewiesen wurde , weil das in unserem unveränderlichen Wert gespeichert wurde. Hallo macht bisher Sinn. Aber hallo, es gibt eine Variable, wir können sie jetzt ändern, es bleibt nicht daran hängen, Hallo zu sein. Also könnten wir sagen, etwas wie hallo gibt es gleich hallo plus Platz dort und Control Alt W. Und Sie können sehen, dass wir tatsächlich geändert haben Hallo gibt auch jetzt die Zeichenfolge Hallo enthalten. Da sind Ola eher. Wie Sie sehen können, können Variablen geändert werden Werte jedoch nicht. Wir könnten auch den Befehl Drucklinie verwenden, um diesen Wert explizit auszudrucken. Drucklinie hallo dort, die genau das tut, was Sie denken würden. Sie würden den Wert dieser Variablen auf einer Zeile Control Alt W dort drüben ausdrucken. In Ordnung, also hast du hier ein paar grundlegende Sachen gesehen. Zunächst einmal ist das Konzept der Werte in Variablen und Werten wieder unveränderlich. Sobald Sie sie definiert haben, können Sie sie nicht mehr ändern. Obwohl Variablen veränderbar sind, können Sie sie nicht ändern, nachdem Sie sie definiert haben. Und beachten Sie auch die Syntax hier der Deklaration von Werten und Variablen. Es ist Tapferkeit var, der Name des Bezeichners, Doppelpunkt, der Typ und dann gleich, was immer Sie wollen, es setzen Sie es. Wieder, das ist rückwärts von vielen anderen Sprachen. Und nur um euch zu zeigen, was passiert und euch zu beweisen, dass Werte nicht verändert werden können. Lassen Sie uns diesen var2 eval ändern und sehen, was passiert, wenn wir versuchen, dies erneut auszuführen, Control Alt W. Sie können sehen, dass wir jetzt einige Fehler hier haben, Neuzuordnung eval, wir können nicht sagen hallo da gleich hallo plus da, weil Sie nicht ändern Sie ein Val. Ein Wert ist unveränderlich. Ändern wir das zurück in var und wieder ausgeführt Control Alt W. Alles klar, so weit so gut, richtig? Warum haben wir nun diese Unterscheidung zwischen Werten und Variablen in Scala? Nun, es ist, weil das, was wir eine
funktionale Programmiersprache nennen , um zu skalieren, ist irgendwie auf die Idee
zentriert, Funktionen
zu übergeben und sie möglicherweise parallel auszuführen. Deshalb passt es so gut zu Apache Spark. Und der Grund, warum wir bei unveränderlichen Konstanten bleiben wollen, wann immer wir können, ist, eine Reihe von Thread-Sicherheits-Problemen zu vermeiden und sie irgendwie am Pass abzuhauen. Stellen Sie sich also vor, Sie haben eine Funktion, die eine Variable enthält, die Sie erhalten, dass sie sich ändern kann und Sie diese Variable in viele, viele Threads übergeben. Was passiert, wenn ein Thread versucht
, diese Variable gleichzeitig zu ändern , dass ein anderer Thread versucht, sie in etwas anderes zu ändern, die Ergebnisse nicht definiert werden, oder? Daher vermeiden wir viele
dieser Race-Bedingungen, indem wir versuchen, unveränderliche Konstanten zu verwenden, wann immer möglich. Wenn unsere Funktionen nur unveränderliche Daten verarbeiten und verarbeiten, müssen
wir uns nicht um all diese Threads,
Sicherheits- und Rennbedingungen kümmern . Das schränkt dich nicht so sehr ein, wie du vielleicht denkst. Sie können immer noch viel tun, nur Werte unveränderliche Konstanten verwenden. Also zum Beispiel, wenn ich die obige Operation machen wollte und die Zeichenfolge o la dort aus dem Wert Hallo konstruieren wollte. Ich kann das immer noch mit Werten tun. Ich könnte sagen, etwas wie Val unveränderlich hallo gibt es gleich hallo plus dort. Richtig? Und ich könnte das Ergebnis ausdrucken. Control Alt W. Und das funktioniert, weil ich
dort unveränderliche Hallo in der gleichen Zeile definiere , nehme ich einen vorher unveränderlichen Wert, füge einen anderen unveränderlichen Wert hinzu und füge diesen einem unveränderlichen Wert zu. Also, das ist in Ordnung mit den Variablen. Wir haben es anders gemacht. Wie wir angefangen haben, indem wir hallo dort auf hallo gesetzt
haben, und dann haben wir bei einer anderen Operation die Zeichenfolge dort hinzugefügt. Solange wir also alles in einer Zeile machen, in einer atomaren Operation, halten
wir uns immer noch an die Regeln der Verwendung von Werten, wann immer möglich. In Ordnung, also haben wir den String-Datentyp hier in Aktion gesehen, richtig? In Scala stehen Ihnen also viele andere Datentypen zur Verfügung. Lassen Sie uns über Datentypen sprechen. So könnten wir zum Beispiel Val Nummer eins sagen. Whoops, wenn ich richtig tippe, Nummer eins Doppelpunkt int. Also ist ein int genau das, was denken Sie, es ist eine Ganzzahl, eine ganze Zahl, eine ganze Zahl. Wir könnten auch Val sagen. Die Wahrheit ist ein Boolean. Und wir werden das auf wahr setzen. Beachten Sie, dass in Scala true und false Konstanten alle Kleinbuchstaben sind. Es gibt Sprachen, in denen Sie die Großbuchstaben „true“ und „false“, aber nicht in Scala. Das ist also nur ein boolescher Wert, true oder false. Wir können auch Charaktere haben. Also können wir Val, Buchstabe a sagen. Als Fahrzeugtyp, ein einzelnes Zeichen, ein einzelner ASCII-Wert. Wir haben auch eine doppelte Genauigkeit Zahlen, natürlich. Also können wir sagen, dass Pi ein Doppelter ist. Und setzen Sie das auf 3.14159265 oder was auch immer es ist. Und wir können auch
einen Gleitkommawert mit einer einzigen Genauigkeit mit foul Pi einfacher Genauigkeit darstellen . Und wir werden das als Gleitkommavariable deklarieren, bei dem es sich um eine Gleitkommavariable mit einfacher Genauigkeit handelt. Und wir werden das auf 3,14159265 F setzen, was eine Gleitkommazahl mit einfacher Genauigkeit bedeutet. Lasst uns Alt W kontrollieren, um zu sehen, dass es so weit funktioniert. So können Sie sehen, dass alle diese Variablen wie erwartet definiert wurden. Lasst uns weitermachen. Es gibt auch einen langen Datentyp, sagen
wir val big number. Wir werden das als lange definieren. Und wir setzen das auf eine große Ganzzahl. 1, 2, 3, 4, 5, 6, 7, 8, 9, auf was immer Sie wollen. Und wir könnten auch eine einzelne Zeichenzahl sagen. Wir können alle kleinen Anzahl speichern. Deklarieren Sie, dass ein Byte gleich 127 ist. Ein Byte ist also im Grunde eine Zahl, die in ein einzelnes Byte vollgestopft ist. Es kann also nur Zahlen von negativem 127 bis positivem 127 darstellen. Oder wenn es von 0 bis 255 ohne Vorzeichen war, steuern Sie Alt W, um diese auszuführen. Ok, sieht gut aus. Lassen Sie uns darüber sprechen, wie Sie Ihre Daten tatsächlich drucken und anzeigen und Ihre Ausgabe formatieren. Das ist immer eine wichtige Sache, oder? Nehmen wir an, wir wollen eine Reihe von Strings
zusammen oder eine Reihe von Werten miteinander verketten und ausdrucken. Natürlich möchten Sie in der Lage sein, die Ergebnisse Ihrer Spark-Programme anzuzeigen. So würdest du das machen. Wir könnten sagen, Drucklinie. Hier ist ein Chaos. Und das Geheimnis hier ist, dass Sie einfach den Plus-Operator verwenden können um Dinge miteinander zu verketten und als große Zeichenfolge auszudrucken. Und es muss auch nicht nur Strings sein. Es kann sich um einen beliebigen Datentyp handeln. Es wird implizit in eine Zeichenfolge konvertieren. Also kann ich sagen, hier ist ein Durcheinander plus Nummer 1 plus Wahrheit, plus Buchstabe a, plus pi, plus große Zahl. Und das sollte funktionieren. Kontrolle Alt W. Da ist es. Krabbe es alles zusammen, weil ich keine Leerzeichen zwischen allem eingefügt habe, aber es funktioniert. Beachten Sie auch übrigens, es gibt kein Semikolon oder irgendetwas am Ende der Zeilen hier. Es geht nur davon aus, dass jede neue Zeile im Grunde ein neuer Befehl ist. Es besteht also keine Notwendigkeit, Ihre Codezeilen in Scala explizit zu beenden. Was möchten Sie wie Druck F-Stil tun, wenn Sie aus einem Hintergrund von wie C oder C plus plus kommen, können Sie mit dem Befehl print f vertraut sein, dem Sie eine Art Formatierungshinweise für die tatsächliche Anzeige numerische Daten oder fügen Sie Strings und andere Daten in eine vorhandene Zeichenfolge ein. So sieht das in Scala aus. Wir können sagen, Drucklinie F, was bedeutet, dass wir drucken Format wollen. Quote Pi ist über Dollarzeichen Pi, einfache Präzision, Prozent 0,3 F. Okay, also lassen Sie uns das ein wenig unterbrechen. Also zuerst, beachten Sie, dass wir das Dollarzeichen dort haben, das anzeigt, dass wir einen Variablennamen oder Wert-Namen haben, in diesem Fall, nach dem Dollarzeichen. So Pi ist einzelne Präzision wird den Wert von Pi einzelne Genauigkeit einfügen. Und Prozent 0,3 f bedeutet, dass es ein Gleitkommawert ist, den wir dort anzeigen werden. Das ist es, was das F bedeutet. Und Prozent 0,3 bedeutet, dass nach dem Dezimalpunkt nur drei Stellen der Genauigkeit angezeigt werden sollen. Also lassen Sie uns weiter gehen und Control Alt W. treffen und Sie können sehen, dass es genau das getan hat, was wir gesagt haben. Pi ist etwa 3.142. Es zeigte also nur die drei Ziffern die dem Dezimalpunkt
folgen, da das alles ist, was wir wollten. Das kann nützlich sein, wenn Sie
eine Zahl mit doppelter Genauigkeit oder sogar eine einzelne Genauigkeit anzeigen , die eine große Anzahl von Ziffern hat mehr Genauigkeit als Sie benötigen. Sie können auch Dinge wie mal sehen, wie das mit ganzen Zahlen funktioniert. So könnten wir zum Beispiel drucken Zeile F sagen, Wieder nur Druck f Format 0, Polsterung auf der linken Seite. Dollarzeichen Nummer 1, Prozent 05 D. In Ordnung. Dieses Mal sagen wir also, dass wir den Wert der Zahl 1
und des Prozentsatzes 05 D einfügen werden. Das D bedeutet nur, dass es
eine Zahl ist, eine ganze Zahl, und Prozent 05 bedeutet, dass ich mindestens fünf Ziffern links von das Dezimalkomma. Mal sehen, was das tut. Kontrolle. Alt W. Und wir bekommen 000 000 001, die die fünf Ziffern Präzision auf der linken Seite
versprechen, die wir wollten. Das kann nützlich sein, wenn Sie versuchen, Ausgabe und Spalten auszurichten, oder? Das ist also manchmal auch ein praktischer Trick. Auch wenn Sie Variablen nur in
eine Zeichenfolge ersetzen möchten , ohne die Formatierung anzugeben. Das ist auch leicht zu machen. Beispielsweise drucken Sie Zeile S für Ersatzangebot. Ich kann das S-Präfix verwenden, um Variablen wie Dollarzeichen Nummer eins ,
Wahrheit
und Buchstabe a , zu verwenden.
Sie können also sehen, dass es eine sehr einfache Möglichkeit ist, nur
Wertnamen in Ihre Zeichenfolge
einzufügen Wertnamen in Ihre Zeichenfolge ohne den Verkettungsoperator unnötig verwenden zu müssen. Also nur eine andere Art, es zu tun. Okay, was können wir sonst noch tun? Wir können Ausdrücke in unsere Druckbefehle aufnehmen. Lassen Sie mich Ihnen zeigen, wie das funktioniert. Druckzeile S. Das S-Präfix ist nicht auf Variablen beschränkt. Ich kann jeden Ausdruck wie Ross,
ein Dollarzeichen, offene geschweifte Klammer, eins plus zwei einschließen . Und es hat automatisch diese Zeile für mich abgeschlossen. Also der Schlüssel hier sind diese geschweiften Klammern. Nachdem Sie eine geschweifte Klammer nach einem Dollarzeichen gesetzt haben, wird
es tatsächlich den Ausdruck
innerhalb dieser geschweiften Klammern auswerten unddas Ergebnis
davon als Teil der Zeichenfolge Control Alt Wausdrucken das Ergebnis
davon als Teil der Zeichenfolge Control Alt W Wir sollten sehen, dass es die Nummer drei ausgedruckt hat. Also, das ist ein netter Trick zu schreiben. Diese geschweiften Klammern nach dem Dollarzeichen könnten also tatsächlich
einen Ausdruck innerhalb eines Druckzeilenbefehls auswerten , wenn Sie das S-Präfix verwenden. Es gibt auch reguläre Ausdrücke. Wenn Sie also mit diesen vertraut sind, ist
das ein leistungsfähiges Werkzeug, um Ihre String-Daten tatsächlich zu mischen. Mal sehen, wie das funktioniert. Beginnen wir also mit einer Zeichenfolge, die Val ist, die ultimative Antwort. Wir definieren das als String. Wieder kamen wir nicht zurück, wie man einen Wert definiert. Und wir werden das Leben erwecken, das Universum. Und alles ist 42. Und wenn Sie diese Referenz erkennen, dann U2, unser Fan von The Tramper's Guide to the Galaxie. Willkommen. Okay, also haben wir diese Zeichenfolge und wir wollen einen regulären Ausdruck
schreiben, der die Antwort auf
die ultimative Frage des Lebens, des Universums und alles extrahiert . Also werden wir einen regulären Ausdruck einrichten, um diese Zahl aus dem Ende dieser Zeichenfolge zu extrahieren. So können wir sagen, val pattern gleich dreifache Anführungszeichen 123. Und dann werden wir es in einem regulären Ausdruck schreiben, um die Informationen zu extrahieren, die wir aus dieser Zeichenfolge wollen. Punktstern, Klammer, eckige Klammer, umgekehrter Schrägstrich d, n eckige Klammer. Plus schließen Paren Punkt Stern, und dann diese drei Anführungszeichen, Punkt r. Okay, also der Punkt R bedeutet, dass dies ein regulärer Ausdruck ist, den wir hier definieren. Und darüber zu gehen, wie reguläre Ausdrücke funktionieren, ist wahrscheinlich außerhalb des Geltungsbereichs für diesen Kurs. Aber es gibt ein sehr nützliches Werkzeug für Dinge wie das Extrahieren von
Informationen aus Protokolldateien und solchen Dingen. Eine schnelle Aufschlüsselung dessen, was hier vor sich geht. Der Punktstern bedeutet, dass alles in dieser Zeichenfolge gefolgt von einem Leerzeichen übereinstimmt. Und dann innerhalb der Klammern ist die Sache, die wir versuchen, aus diesem Muster zu extrahieren. Und die Klammern und der umgekehrte Schrägstrich d bedeutet, dass ich eine Zahl extrahieren möchte. Alles klar, und eine beliebige Anzahl von Zahlen, das ist, was das Pluszeichen bedeutet, gefolgt von irgendwelchen anderen Zeichen. Okay, also indem Sie nach einer Reihe von Zeichen suchen, gefolgt von einem Leerzeichen und dann einer Zahl gefolgt von irgendetwas anderem, das die 42 aus dieser Zeichenfolge ziehen wird. Wir brauchen diese Kontrolle Alt W nicht, nur um sicherzustellen, dass das funktioniert. Alles klar, cool. Also werfen wir einen Blick hier rüber. Also haben wir die Schnur, die wir definiert haben, um das Universum zu leben, und alles ist 42. Und jetzt haben wir ein passendes Objekt mit regulären Ausdrücken definiert , das aus diesem regulären Ausdruck besteht. Okay, also ist das, was mit dieser Leitung hier passiert ist. Nun, um diesen regulären Ausdruck auf die Zeichenfolge anzuwenden, ist es sehr einfach. Wir können einfach Val Muster sagen, Klammern Antworten, String ist die ultimative Antwort. Okay, also die Syntax Es ist ein bisschen seltsam. Es bedeutet, dass wir den regulären Ausdruck nehmen, den wir im Muster definiert haben. Wir werden die Ausgabe davon zuweisen, um String zu beantworten. Also die Syntax hier, es heißt im Grunde, ich möchte nehmen, was in diesen Klammern ist und dieses Ergebnis auf das
übertragen, was in diesen Klammern ist. Okay, das ist eine Art, darüber nachzudenken. Und wir werden diesem Muster die ultimative Antwort zuweisen. Also die Syntax gibt es wieder, ein bisschen rückwärts, wie Sie vielleicht über Dinge in anderen Sprachen denken. Und dann können wir einfach ausdrucken, was diese Antwort ist. Zuerst konvertieren wir es in eine ganze Zahl. Wir können sagen, val, Antwort entspricht Antworten string zu int. Das zeigt Ihnen nur, wie Sie tatsächlich einen Typ in einen anderen konvertieren können. Es würde helfen, wenn ich die Antwortzeichenfolge korrekt eingegeben habe. Und dann kann ich das ausdrucken. Linie drucken, Antwort. In Ordnung, also haben wir eine Zeichenfolge definiert, wir haben einen regulären Ausdruck definiert, um Informationen
aus dieser Zeichenfolge zu extrahieren , wir definieren eine Anweisung. Wenden Sie diesen regulären Ausdruck tatsächlich auf die Zeichenfolge an und speichern Sie das Ergebnis irgendwo. Wir nennen diese Antwortzeichenfolge. Wir haben das von einer Zeichenfolge in eine ganze Zahl konvertiert, und dann drucken wir, dass Kontrolle Alt W verletzt und es hat funktioniert. So können Sie sehen, dass wir die Zeichenfolge 42 extrahiert haben. Wir haben das in eine ganze Zahl 42 konvertiert und es ausgedruckt, als wir fertig waren. Alles klar, weitermachen. Reden wir über Booleans. So wirklich einfach, was sie genau funktionieren, wie Sie es erwarten würden. Also reden wir über Booleans. Zum Beispiel könnten wir sagen, val ist größer und setzen Sie das gleich eins größer als zwei. Was glaubst du, was das herauskommen wird? Ist eins größer als zwei? Nein, die Antwort ist falsch. Das funktioniert so ziemlich, wie Sie es erwarten würden. Wir würden sagen, Val ist weniger gleich, eins, weniger als zwei. Das ist wahr. Wir könnten sagen, val impossible equals ist größer und kleiner. Und Sie können sehen, dass wir dort ein einzelnes kaufmännisches Und-Zeichen verwenden können. Das ist in Ordnung. Aber wir könnten auch ein doppeltes kaufmännisches Und-Zeichen sagen. Mal sehen, was die machen. Kontrollieren Sie Alt W. Also sind die hier nicht dasselbe. So wie in C oder C plus,
plus ein doppeltes kaufmännisches Und-Zeichen ist eigentlich ein logisches Ende, wo es ein einzelnes kaufmännisches Und-Zeichen ist. Und so ist der einzige Grund, warum dies überhaupt funktioniert, weil es größere und kleinere Flügel sind, die auf Nullen und Einsen auswerten können und es am Ende immer noch funktioniert. Und wir konvertieren das implizit in wahr oder falsch. Aber wenn Sie versuchen, eine logische Operation durchzuführen, das ist, was wir hier wirklich versuchen. Sie sollten das doppelte kaufmännische Und-Zeichen verwenden. Das ist der logische oder boolesche Operator. Also geben sie Ihnen in diesem Fall das gleiche Ergebnis, aber es ist wirklich bessere Form, das doppelte kaufmännische Und-Zeichen zu verwenden, funktioniert auf die gleiche Weise mit oder wenn Sie sagen wollen, ist größer oder kleiner, das funktioniert. Das wäre vermutlich wahr, ja. Also bekommst du die Idee. Booleaner funktionieren so ziemlich wie von anderen Sprachen. Lasst uns noch ein bisschen damit spielen. Und wir könnten Val sagen, die Karte, die eine Schnur ist, und setzen Sie das gleich Pickard. Und wir können sagen, Val bester Kapitän. Ein anderer Wert nur mit einem anderen Namen. Auch eine Zeichenfolge ist gleich Pickard. Und wir können sagen, dass Val das Beste ist. Deklarieren Sie das als booleschen Wert. Und wir setzen das auf Picard. Gleich gleich gleich bester Kapitän. Gehen wir also voran und führen Sie das aus und Control Alt W tut, was Sie denken könnten. Also ist es gleich, gleich hier geht tatsächlich innerhalb dieser Strings und vergleicht die Werte der Strings. Das bedeutet also, dass wir
die Werte dieser beiden Dinge vergleichen und sehen wollen , ob sie identisch sind. Es ist also nicht wirklich,
die Objekte selbst oder die Adresse der Objekte selbst zu vergleichen . Es geht tatsächlich in diese Zeichenfolge und vergleicht die Strings miteinander. Wenn Sie also zwei Strings vergleichen möchten, verwenden Sie
einfach den equals equals Operator. Das kann etwas sein, das in manchen Sprachen seltsam ist. Also ist es wichtig, das hier zu verweisen. Und wenn Sie im Q und Wetter debattieren wollen, ist
Picard der beste Kapitän. Ich begrüße diese Diskussion. Ordnung. Wenn ihr eure Hände schmutzig machen wollt, spielt mit diesem Zeug herum, macht noch mehr Sachen, macht weiter, Jungs. Zum Beispiel könnten Sie Code schreiben, der den Wert von pi annimmt und ihn verdoppelt und dann innerhalb
einer Zeichenfolge mit drei Dezimalstellen der Genauigkeit nach rechts druckt . Okay, eigentlich werde ich das hier als
eine kleine Herausforderung für dich einfügen . Und es ist wirklich einfach. Ich werde dir nicht einmal die Antwort geben. Ihr könnt in der Q sprechen und ein, wenn ihr über die eigentliche Lösung sprechen wollt. Aber es gibt meine Herausforderung an dich. Geh und wende das an, was du gerade gelernt hast und tu das. Ja, schreibe einfach ein kleines Code-Snippet, das den Wert von Pi annimmt. Wir definieren, multiplizieren es mit zwei und drucken innerhalb einer Zeichenfolge mit drei Dezimalstellen der Genauigkeit nach rechts aus. Alles, was Sie tun müssen, um das zu erreichen, sollte hier über Ihnen liegen. So wenig einfache Möglichkeit, einige praktische Belichtung zu bekommen. Also machen Sie Ihre Hände schmutzig, spielen Sie ein bisschen mehr herum. Und dann gehen wir zum nächsten Kapitel über Scala zu lernen.
5. [Übung] Flussüberwachung in Scala: Wenn Sie also speichern möchten, was Sie bisher getan haben, können
Sie einfach Control-S sagen,
schließen Sie das aus, um es für zukünftige Referenz zu behalten, wenn Sie möchten. Und lassen Sie uns ein anderes Scala Notizbuch oder Scala Arbeitsblatt eher machen. Und wir nennen dies den kreativen Namen, Scala zu lernen. Und diesmal reden wir über die Durchflusskontrolle. Also lassen Sie uns sehen, wie wenn sonst Anweisungen funktionieren. Sie funktionieren genauso wie in anderen Sprachen. Es ist nichts zu seltsam hier. Zum Beispiel könnten wir sagen, wenn man größer als drei ist, Drucklinie, unmöglich. Sonst drucken Linie. Die Welt macht Sinn. Genau wie jede andere Sprache dort, wenn ein Ausdruck wahr ist, machen
Sie diesen Ausdruck, sonst machen Sie einen anderen Ausdruck. Und wenn Sie alles in einer Zeile machen wollen, sieht das so aus. Also Control Alt W, die Welt macht Sinn, wie es sollte. Nun, wenn Sie das in mehrere Zeilen aufteilen möchten, ist
die Syntax Ihnen wieder ziemlich vertraut. Diejenigen von euch, die vorher programmiert haben, könnten
wir einfach sagen, ob man größer als drei geschweifte Klammer ist. Und das ermöglicht es uns, mehrere Ausdrücke in diesem positiven Fall zu setzen. Wir könnten also sagen, dass Drucklinie unmöglich ist. Und wenn wir wollten, könnten wir noch etwas anderes drucken. Wirklich sonst, mach etwas anderes. Wir können sagen, Drucklinie, die Welt macht Sinn. Und trotzdem, ich weiß es nicht, ich erfinde das. Kontrolle Alt W. Die Welt macht Sinn, immer noch kalt. Also nichts zu überraschend da. Es ist sehr ähnlich zu anderen Sprachen dort. Nun, Sie wissen also, wie wir Switch-Anweisungen in
einigen Sprachen haben können , in denen Sie irgendwie zwischen verschiedenen Fällen übereinstimmen. Nun, wie sieht das in Scala aus? Schauen wir uns ein Beispiel dafür an. So könnten wir sagen, val Zahl gleich 3 SAT die Zahl 32, ein Wert namens Zahl. Und wir können sagen, Zahl entspricht geschweifte Klammer, Fall eins. Kleiner seltsamer Pfeil dort gleich Zeichen größer als Drucklinie 1, Fall 2. Sie können sehen, wohin ich damit hingehe. Zeile 2 drucken, Fall 3, Zeile drei drucken. Und dann können wir sagen, Fall, Unterstrich, Linie drucken, etwas anderes. Wahrscheinlich erraten, was das tut Control Alt W. Wir bekommen den Wert frei ausgedruckt. Was hier los ist, ist, dass wir diese Fallaussage hier
haben, wo wir eine Liste von verschiedenen Fällen haben können , die wir gegen die Wertnummer überprüfen werden. Es ist gleich 1. Wir werden diesen Ausdruck ausführen. Wenn es gleich 2 plus q ist, dieser Ausdruck gleich 3 ist, führen
wir diesen Ausdruck aus, was er sich als sein herausstellt. Und dieser Unterstrich ist irgendwie wie ein Fang. Es ist wie die Standardaussage, wo irgendetwas anderes, jeder andere Fall, den
wir nicht übereinstimmen, wir werden stattdessen das treffen. Zum Beispiel könnten wir das auf
30 setzen und das sollte die letzte Catch-all-Aussage treffen, richtig? Kontrollieren Sie Alt W. Sicher genug, wir bekommen etwas anderes und ändern das in, um zu kommen. So funktioniert eine Match-Anweisung. Das sieht man nicht zu oft in Scala, aber es ist da, wenn man es braucht. Als nächstes sprechen wir über For-Loops. Sehr häufig, was in den meisten Programmiersprachen zu tun ist, oder? Also, wie funktioniert das? Es ist ein wenig seltsam in Bezug auf die Syntax. So. Eine Möglichkeit, es zu tun, ist für x weniger als Bindestrich eins bis vier. Und dann können wir sagen, val quadriert gleich x mal x und drucken Linie quadriert. Was das also tut, ist, dass es die Werte eins bis vier durchläuft. Und zu jeder Zeit durch sie, wenn Zeichen, dass der aktuelle Wert dieser aktuellen Iteration auf den Wert x Und dann berechnen wir einen neuen Wert namens quadriert, x von sich selbst
multipliziert und das Ergebnis ausgibt. Also, was wir sehen sollten, unsere vier Ergebnisse hier, jedes mit dem Quadrat der Zahlen eins bis vier, Kontrolle Alt W. Und da sind sie, 14916, weil das ein Quadrat, zwei Quadrat, drei Quadrat und vier Quadrat ist. So ziemlich funktioniert so, wie Sie es erwarten würden, oder? Wir haben auch while-Schleifen, genau wie Sie es in anderen Sprachen tun würden. So könnten wir auch etwas wie var x gleich 10 tun. Und beachten Sie, dass ich hier eine veränderbare Variable verwende. Dies ist in der Regel keine gute Praxis in Scala. Und ich werde sagen, während x größer als oder gleich 0, geschweifte Klammer, Druckzeile x und dann x minus gleich eins ist. Also werden wir anfangen, x auf 10 zu setzen. Während x größer oder gleich 0 ist, werden
wir den Wert von x ausdrucken und dann einen davon subtrahieren. So können Sie sehen, dass wir
dort x eine Variable machen mussten , um den Wert von x weiter zu ändern also keine Struktur. Sie werden zu oft in Scala sehen, aber Sie können es nicht tun, wenn Sie müssen. wir einfach sicher, dass es funktioniert. Kontrolle Alt W. Und sicher genug zählt es von 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0. Cool. Interessant, wie das Arbeitsblatt formatiert, dass übrigens, es geht aus dem Weg, um zu versuchen, die Dinge kompakt zu halten. Das ist irgendwie cool. Eine weitere Struktur für die Flusssteuerung ist die do while-Schleife. Wieder ähnlich wie andere Sprachen. So könnten wir auch x gleich 0 setzen. Wir verwenden immer noch die gleiche Variable, die wir zuvor definiert haben. Und wir können sagen, Do drucken Zeile x, Semikolon x plus gleich eins, während x kleiner als oder gleich 10. Dieses Mal werden wir also bei 0 beginnen und jeden Wert ausdrucken, der um eins zählt, während x kleiner oder gleich 10 ist. Also machen wir diesen Vergleich am Ende des Blocks statt am Anfang. So funktioniert das To-while. Kontrollieren Sie Alt W und doch funktioniert es 0123, den ganzen Weg bis 10. Okay, das ist es für die Flusssteuerung, lassen Sie uns mehr über Ausdrücke sprechen. Also weiter, Ausdrücke. Eine Sache, die an Scala irgendwie seltsam ist, ist, dass, wenn Sie jemals einen Ausdruck haben, es implizit den Wert
dieses Ausdrucks automatisch innerhalb dieses Blocks zurückgibt . Nehmen wir zum Beispiel an, geschweifte Klammer Val X entspricht 10 Semikolon, x plus 20 Semikolon. Was, was wird hier passieren? Was macht das eigentlich? Control Alt W. Also, was es tat, wurde tatsächlich den Wert 30 zurückgegeben, obwohl wir nicht wirklich gesagt haben, ich möchte das ausdrucken, ich habe nicht explizit gesagt, ich möchte es zurückgeben, nur der Akt, diesen Ausdruck zu haben, ist das letzte, was in Dieser Block bedeutet, dass das ist, was dieser Block als Ergebnis ausgibt. Das ist also eine wichtige Sache, um Ihren Kopf in
Bezug auf funktionale Programmierung und Ausdruck zu wickeln , jeder Code wie dieser kann selbst übergeben
werden, da eine Funktion ihre eigene kleine Entität hat. Und die Sache, die diese Funktion zurückgibt, ist, was auch immer das Letzte ist und dieser Ausdruck ist. Jetzt können Sie explizit Dinge zurückgeben, um eine Kanone andere Sprachen zu mögen. Aber implizit wird das letzte, was in einem
Codeblock passiert, der Rückgabewert dieses Ausdrucks sein. Also dieses kleine Stück Code hier ist eine Funktion in und für sich implizit. Und es gibt in diesem Fall den Wert 30. Okay, das ist irgendwie wichtig. Das könnte ich eigentlich einfach ausdrucken. Und ich kann sagen, Drucklinie. Und drucken Sie diesen Ausdruck aus, val x entspricht zehn, Semikolon x plus 20, genau so. Und das wird tatsächlich den Wert 30 ausdrucken. Okay, sieh mal, wie das funktioniert. Wichtiger Punkt dort, denn das ist wahrscheinlich einer der verwirrenden Punkte von Scala. Wenn Sie das Programmieren in einer anderen Sprache lernen, was für die meisten Menschen der Fall ist. Das letzte kleine Bit innerhalb des Blocks ist der Rückgabewert dieses Ausdrucks. Und Sie können diesen Ausdruck als seine eigene Entität behandeln. Okay, das wird wichtig sein, wenn wir als Nächstes über Funktionen reden. Alles klar, das reicht für diesen kleinen Block hier. Also nochmal, ich werde Ihnen hier eine Herausforderung geben, um das zu üben, was Sie gelernt haben. Lassen Sie mich kopieren und eine kleine Übung, die ich hier zur Seite geschrieben habe. So haben Sie vielleicht von der Fibonacci-Sequenz gehört. Und das ist es, was es ist. Im Grunde ist es eine Sequenz, in der jede Zahl die Summe der beiden Zahlen davor ist. Ihre Ergebnisse sollten also 011235 und so weiter sein. Sehen Sie, was hier los ist. Also haben wir, also beginnen wir mit einem Wert 01, und dann iterieren wir die Werte der beiden Zahlen davor addieren. Also 0 plus 1 ist 1, 1 plus 1 ist 2, 1 plus 2 ist 3. 2 plus 3 ist 5. 3 plus 5 ist 8, und so weiter und so weiter. Ihre Herausforderung besteht also darin, einen kleinen Codeausschnitt in Scala zu schreiben, der das tut. Also müssen Sie anwenden, was Sie über die Flusssteuerung hier gelernt haben und Werte und Variablen, um das abzuziehen, das ist ein bisschen mehr eine anspruchsvolle Übung. Noch einmal, ich werde Ihnen die Antwort nicht geben. Sie können es ziemlich leicht genug nachschlagen, wenn Sie stecken bleiben. Aber das ist eine ziemlich häufige Interview-Frage Menschen zu
zeigen, dass Sie wissen, wie man kodiert und Ihren Kopf um Algorithmen wickeln kann. Also ermutige ich Sie, sich die Zeit zu nehmen, um durch
diese Übung zu bekommen , weil meine in nützlich auf einem Vorstellungsgespräch eines Tages. Und es ist auch eine gute Praxis für die Flusssteuerung innerhalb der Scala-Sprache. Also geh und hab Spaß damit. Und wenn wir zurückkommen, erfahren wir mehr.
6. [Übung ] Funktionen in Scala: Dieser nächste Vortrag ist kürzer, aber er ist sehr wichtig. Wir werden über Funktionen in Scala sprechen. Und angesichts der Tatsache, dass es sich um eine funktionale Programmiersprache
handelt, ist das offensichtlich von großem Import. Lassen Sie uns schließen lernen Skelett und erstellen Sie noch ein anderes Arbeitsblatt, New Scala Arbeitsblatt, und wir werden dies nennen, raten Sie was? Scala drei lernen. Und dieses Mal werden wir über Funktionen sprechen. Das Format einer Funktion in Scala wird also der Tod sein. Funktionsname, Parameter, Name, Doppelpunkt für so viele Parameter wie Sie haben. Und dann Doppelpunkt Rückgabetyp gleich, und dann ein Ausdruck, der definiert, was diese Funktion tut. Dies ist eine wirklich, wirklich seltsame Syntax wenn Sie an andere nicht-funktionale Programmiersprachen gewöhnt sind. Schauen wir uns also einige Beispiele an. Wir können sagen, zum Beispiel, def Quadrat es. X Doppelpunkt int, Doppelpunkt int gleich geschweifte Klammer x x mal x. So würden Sie eine Funktion definieren, die einen Wert annimmt und Quadrate es das Quadrat dieses Wertes zurückgibt. Lasst uns das zusammenbrechen. Also wieder, wir beginnen mit def, um eine Funktion zu definieren, den Namen der Funktion, in diesem Fall, Quadrat sie. Ein Parameter. In diesem Fall haben wir nur einen Parameter namens x, und das ist vom Typ Integer. Also x Doppelpunkt int bedeutet, dass der erste Parameter eine ganze Zahl mit dem Namen x ist
und dann wird der Rückgabewert dieser Funktion eine ganze Zahl selbst sein. Also, dass Doppelpunkt int der Rückgabewert ist, wieder völlig rückwärts von vielen anderen Sprachen. Dann müssen wir gleich sagen, um diese Funktion einem Ausdruck zuzuweisen. Also sagen wir, diese Funktionsdefinition ist gleich diesem Ausdruck in den geschweiften Klammern, x mal x. Vergessen Sie nicht, dass gleich ist, das ist ein sehr häufiger Fehler. Also wieder, wir geben nicht explizit einen Wert zurück. Nur das letzte, was innerhalb
der Funktion ausgewertet wird , ist der implizite Rückgabewert dieser Funktion. Das ist also alles, was es dazu gibt. Ein weiteres Beispiel, sagen wir def cubit x int, Doppelpunkt int gleich x mal x x also könnten wir alles tun, was in einer Zeile dazu einfach für
einen schnellen Einzeiler ist . Lassen Sie uns diese in Aktion sehen. So können wir sagen, Drucklinie, Quadrat es, Übergabe des Parameters zwei. Und wir können sagen, drucken Linie cubit, übergeben in den Parameter drei. Lasst uns Alt W kontrollieren und all das ausführen. Und Sie können sehen, dass wir die Funktion Quadratwurzel zugewiesen und Würfel es. Und wir haben tatsächlich den Wert 2 übergeben, um ihn zu quadrieren und haben den Wert für zurück bekommen. Wir gehen in den Wert drei nach Kuba und bekam 27 zurück. So wie es funktionieren sollte. Also wieder, es konzentriert sich für einen Moment auf diese Syntax. Es dauert einige gewöhnungsbedürftige Funktion Namen, Parameter Doppelpunkt Typ, Doppelpunkt Rückgabewert Typ gleich, und dann den Ausdruck, der die Funktion selbst definiert. Hier wird es komisch. Wenn du nicht denkst, dass das seltsam genug ist. Funktionen können tatsächlich andere Funktionen als Parameter nehmen. Es ist wie Anfänge. Wenn Sie diese Popkulturreferenz nicht bekommen, entschuldige ich mich, aber sagen wir zum Beispiel, Tod transformieren Ints. Und wir nehmen es in X, das ist ein ganzzahliger Parameter. Und auch ein f, das eine Funktion definieren wird, die eine ganze Zahl
annimmt und eine ganze Zahl als Rückgabewert zurückgibt. Und diese Transformationsfunktion selbst wird eine ganze Zahl zurückgeben und wir werden diese
gleich dem folgenden Ausdruck setzen , f von x. Alles klar, das braucht etwas nachzudenken, richtig, also was ist hier los? Wir definieren eine neue Funktion namens transform int. Es nimmt sowohl einen Wert,
einen ganzzahligen Wert namens X. Und es nimmt auch eine Funktion, die eine ganze Zahl annimmt und eine andere Ganzzahl zurückgibt. Das kann also jede Funktion sein, die eine ganze Zahl
annimmt und sie in eine andere Ganzzahl umwandelt. Wir wissen, dass dies wiederum eine ganze Zahl zurückgibt und es auf den Ausdruck f von x gesetzt ist. Also nehmen wir die Funktion, die wir übergeben haben, namens f und übergeben in diese Funktion,
den Parameter x, den wir in übergeben, transformieren sie. Wenn Sie da sitzen und ein wenig darüber nachdenken müssen, wie das funktioniert, Sie keine Angst, Pause zu drücken, denn das ist ein sehr wichtiges Konzept für die funktionale Programmierung. Mal sehen, was es tatsächlich tut, als wir versuchten, es zu benutzen. Wir werden sagen, Val Ergebnis gleich transformieren int, und wir werden in zwei übergeben und die Funktion Würfel es. Also, was denkst du, wird hier passieren? Wir übergeben den Wert zwei in x, die Funktion cubit in F also werden wir am Ende cubit auf den Wert zwei hier in transformieren es. Also transformieren wir dann int. Wir werden die kubische Funktion aufrufen, die wir mit dem Wert X übergeben haben.
Also sollten wir wieder in cubed zurückkehren, richtig? Kontrolle Alt W. Sicher genug, wir haben den Wert acht. In Ordnung, nochmal, Nudeln drauf. Und wenn Sie dieses Ergebnis tatsächlich ausdrucken möchten,
anstatt sich nur auf das zu verlassen, was das ausgewertet hat, könnten
wir sagen, Drucklinie, Ergebnis, Kontrolle Alt W und wieder explizit dort bewerten. Okay, Also noch wichtiger ist das Konzept der Lambda-Funktionen, oder manchmal werden sie anonyme Funktionen genannt sind eine Funktion Literale, wissen
Sie, es ist eine Menge andere Terminologie dafür. Aber im Grunde können Sie eine Funktion inline deklarieren, ohne ihr sogar einen Namen zu geben. Und Sie werden sehen, dass dies viel in Spark-Code passiert. Zum Beispiel könnte ich sagen, transformieren int drei x Gleichheitszeichen größer als x mal x x. Also, was ich getan habe, ist die Notwendigkeit zu umgehen, tatsächlich eine kubische Funktion dort zu definieren. Und ich habe einfach gerne diese Funktion hier im Einklang mit finden, ob
eine Lambda-Funktion oder eine anonyme Funktion oder ein Funktionsliteral aufruft . Wieder, andere Terminologie für die gleiche Sache. Das macht also dasselbe wie 3 Ellen. Aber anstatt tatsächlich eine kubische Funktion zu definieren, definieren
wir nur die Eingeweide dieser kubischen Funktion hier in Zeile als Teil dieser Zeile. Also sagen wir, transformieren Sie int den Wert 3
, der in x übergeben wird
und nun in den f-Parameter übergeht, transformieren Sie ihn. Wir übergeben diesen Ausdruck, Ross sagen, wir werden einen Eingabeparameter x nehmen und x mal x x x zurückgeben. Es ist
also nur eine Abkürzung, wirklich kurze Ausdrücke als Funktionen zu übergeben. Und lassen Sie uns einfach sicherstellen, dass es das tut, was wir denken, es tut. Wenn wir also Control Alt W drücken, gibt uns
das den Wert 27 zurück, weil es drei übergibt, drei in x
übergibt und dann das würfelt. Ok. Schauen wir uns ein anderes Beispiel an. Gleiche Idee, transformieren int 10 x x durch zwei geteilt. Das definiert also eine neue Sache, die wir noch nicht gesehen haben. Und wir werden diese Transformations- und Funktionspassage in zehn in x und in f verwenden. Wir übergeben diese Art von Inline-Lambda-Funktion, die x nimmt und sie durch zwei teilt. Also würden Sie erwarten, dass 1,
5 zurückgibt , oder? Sicher genug. Ein weiteres Beispiel, wir könnten sagen transformieren int in x und das wird gehen, und wir können sagen, wir werden hier komplizierter. Wir könnten sagen, val y gleich x mal 2 Semikolon y mal y. Und schließen Sie das aus. Wir denken, dass es mit diesem passieren wird. Also, was wir hier tun, ist, hier einen mehrzeiligen Ausdruck zu übergeben, anstatt nur eine einzige Zeile Sache, können
Sie das tun, das ist cool. Also hier richten wir einen Wert namens y ein und setzen diesen auf x mal 2. Also wieder, zwei werden in diese Funktion als x übergeben. Also werden wir anfangen, mit 2 mal 2 zu sagen, was 4 ist. Und dann sagen wir y mal y, also 4 mal 4. Also sollten wir 16 bekommen, oder? Kontrolle Alt W. Sicher genug, dass wir 16 bekommen. Sie können also sehen, dass diese Lambda-Funktionen
mehrzeilige Ausdrücke enthalten können , wenn Sie sie nur in geschweifte Klammern setzen, das ist in Ordnung. Es ist also einfach wieder eine Abkürzung, eine kurze kleine Funktion zu
definieren, ohne die Funktion selbst zu definieren. So kommt manchmal praktisch, aber es kann ein wenig verwirrend sein. In Ordnung. Das ist eine Menge, um dir den Kopf zu wickeln. Wie ich schon sagte, es gibt nicht viel Material hier,
aber es ist schwer, in zu sinken, um Ihnen zu helfen, dass es einsinkt. Wieder, ich habe eine Herausforderung für dich. Hier ist Ihre Übung für diese Lektion. Also Strings, es stellt sich heraus, haben die integrierte Punkt-ToupperCase-Methode. Zum Beispiel könnten Sie foo dot
in Großbuchstaben sagen und es wird Ihnen FU in allen Großbuchstaben zurückgeben. Also Wut Tweet-Modus, wenn Sie wollen, Ihre, Ihre Übung, Ihre Herausforderung ist es, eine Funktion zu schreiben, die eine Zeichenfolge in
Großbuchstaben konvertiert und dann diese Funktion für ein paar Testzeichenfolgen verwenden. Und dann möchte ich, dass Sie dasselbe mit einem Funktionsliteral tun. Das sind diese kleinen Inline-Funktionen hier, anstatt eine separate benannte Funktion zu verwenden. Üben Sie also, Großbuchstaben mit
einer traditionellen Funktion zu verwenden und dann ein
Funktionsliteralzu verwenden, indem einer traditionellen Funktion zu verwenden und dann ein
Funktionsliteral Sie stattdessen diese kleinen Inline-Lambda-Funktionen verwenden. Nicht zu schwer, aber es ist eine gute Praxis. Also geh los und kümmerst dich darum. Und wir sehen uns in der nächsten Lektion.
7. [Übung] Datenstrukturen in Scala: Alles klar, machen wir noch ein Scala-Arbeitsblatt. Und wir nennen das hier, du wirst nie erraten, Scala vier zu lernen. Und dieses Mal werden wir über Datenstrukturen sprechen. Sehr wichtiges Konzept in jeder Sprache. Und das wird eine Art lange werden, Jungs, also gebar mit mir. Es gibt also viele verschiedene Arten von Datenstrukturen in Scala. Wir haben Tupel. Das ist sehr häufig, wenn wir es mit dem Spark-Code zu tun haben. Wir haben unveränderliche Listen. Und Sie können sich diese als Datenbankfelder oder Datenspalten vorstellen. Und diese können nützlich sein, um ganze Datenzeilen zusammen zu übergeben, richtig, also lassen Sie uns sehen, wie das aussieht. Wir können Val Captain Zeug sagen. Und wenn Sie nicht mit Star Trek II vertraut sind, entschuldige
ich mich für die Popkultur-Referenzen hier. Picard, Unternehmen D, NCC 17, 0, 1, D, spielt keine Rolle, was diese bedeuten. Es gibt eine Liste von Strings, die in einem, was wir hier ein Tupel nennen, zusammengesetzt werden. Nun, trotz des Namens des Tupels, muss
nicht unbedingt drei Dinge darin haben. Es passiert einfach in diesem Fall. Wir haben also dieses Trio aus verschiedenen Objekten hier, diese drei Saiten, die in diesen Klammern zusammengefasst sind. Und wir können das als eine Einheit behandeln, die wir
Captain Zeug nennen . Lassen Sie uns das ausdrucken. Kontrollieren Sie Alt W. Und Sie können sehen, dass das als Objekt selbst ausgedruckt
wird, die drei Saiten Picard Enterprise D und NCC 17, 100 one-d. Innerhalb dieser Klammern ist es tatsächlich ein einzelnes Objekt, das wir cap und stuff genannt haben, und dieses Objekt enthält diese drei Strings. Nun könnten wir das auseinanderreißen und sich auf diese einzelnen Komponenten individuell beziehen. Und das tun wir, indem wir auf sie basierend auf ihrem einen Index beziehen, der wichtig ist. Beziehen Sie sich auf die einzelnen Felder mit einem einzigen Index. Dies kann verwirrend sein, weil Sie in vielen Programmiersprachen von 0 zu zählen beginnen, richtig? Das ist in diesem speziellen Beispiel nicht der Fall. So zum Beispiel eine Drucklinie, Captain Zeug, Punktunterstrich. Einer ist die Syntax hier. Nehmen wir an, Control Alt W, das druckt eine Karte, das erste Element dieses Tupels. Ebenso können wir sagen, Drucklinie Captain Zeug Unterstrich zwei, und drucken Linie Captain Zeug Unterstrich drei. Und wir bekommen jedes dieser Elemente aus ihrem ursprünglichen Tupel entfernt. So beziehen Sie sich also auf einzelne Elemente eines Tupels, indem Sie dieses Unterstrichformat verwenden, das mit einem beginnt. Okay, was können wir sonst noch tun? Wir können Schlüsselwertpaare erstellen, genau wie wir es in vielen anderen Sprachen mit dem Pfeiloperator tun. Zum Beispiel könnten wir sagen, val cards ship entspricht dem String Picard Strich größer als kleines Pfeilsymbol dort, Enterprise Dash d. Und ich könnte dann auf den Wert Teil davon mit einer ähnlichen Syntax verweisen. Ich könnte sagen, Drucklinie, Picards Schiff, Punkt Unterstrich zwei, das gibt mir diesen Wert zurück. Also kontrollieren Sie Alt W. So können Sie sehen, dass wir diese Zuordnung von Pixar zu Enterprise
D erstellt haben . Und wenn wir diesen bestimmten Wert extrahieren wollen, können
wir einfach Unterstrich zwei verwenden, um es zu bekommen. Und Sie können tatsächlich verschiedene Typen innerhalb eines Tupels mischen. Übrigens können wir sagen, val, ein Haufen Zeug entspricht in Klammern Kirk, was eine Zeichenfolge ist, 1964, die eine Zahl ist. Das Jahr, in dem Star Trek herauskam, natürlich. Und ein Boolean, Lassen Sie uns einen Booleschen laufen, wahr. Ist das eine gültige Sache zu tun? Ist das legal? Ja, ist es. Sie können also ein Tupel haben, das auch verschiedene Datentypen enthält. In diesem Fall eine Zeichenfolge und int und ein boolescher Wert. Das ist in Scala vollkommen okay. Lassen Sie uns als nächstes über Listen sprechen. Listen sind also irgendwie wie ein Tupel, aber sie sind ein tatsächliches Sammlungsobjekt, das mehr Funktionalität hat. Und Listen können keine Elemente unterschiedlicher Typen enthalten. So wie ein Tupel, aber mehr Funktionalität muss vom gleichen Typ sein. In Ordnung, kleine Notiz für sich selbst, zum Beispiel. Es ist tatsächlich eine einzeln verknüpfte Liste unter der Haube, wenn Sie in Datenstrukturen sind. Also können wir sagen, Val, Schiffsliste entspricht einer Liste, Kapital L, Unternehmen, trotzig, Voyager, Deep Space neun. Ich habe Index 01 vergessen, der beste von allen sowieso. Also, was macht das? Kontrolle Alt W. Und doch haben wir ein Listenobjekt, das eine Liste von Strings hat. Auch hier muss die Liste den gleichen Objekttyp enthalten. In diesem Fall handelt es sich um eine Liste von String-Objekten. Und was können wir damit machen? Wie bei einem Tupel können
wir einzelne Elemente aus dieser Liste extrahieren, aber die Syntax wird völlig anders sein. Also sagen wir zum Beispiel, drucken Linie, Schiff, Liste, Klammern, eins, einfach so. Was denkst du, was das tun wird? Geben wir Unternehmen zurück oder bringen mich zurück zu finden, lassen Sie uns herausfinden, Kontrolle Alt W gibt es mir definieren. Im Gegensatz zur Tupel-Syntax sind
wir hier eigentlich nullbasiert. Also, Schiff war 0, würde uns Unternehmen zurückgeben. Lassen Sie mich das nur beweisen. Aber Schiffsliste 1 wird uns geben, es zu definieren. Weil wir anfangen, in diesem Fall von 0 zu zählen, was ein bisschen mehr ist, was Sie erwarten würden. Wir haben auch Kopf- und Heckbediener zur Verfügung. Also könnten wir sagen, Linie drucken, Schiff, Liste, Punktkopf. Und wir können sagen, Drucklinie, Schiff, Liste Dot Tail, Kopf tut wahrscheinlich, was Sie erwarten. Das wird Ihnen das erste Element in der Liste geben, aber Schwanz ist wahrscheinlich nicht. Was erwartest du? Es gibt Ihnen tatsächlich alle verbleibenden Gegenstände zurück. Jenseits des ersten, Mal sehen, Kontrolle Alt W. und wir scrollen nach unten. So Kopf gab uns das erste, was in der Liste Unternehmen, die erwartet wird, aber Schwanz gibt uns alles andere. Das gibt uns also die Liste der definierten Voyager und dSpace neun, eine
Art Unterliste, die das erste Element ausschließt. Kleine komische SQL-Alchemie, manchmal komisch. Angenommen, Sie möchten jedes Element in einer Liste durchlaufen. Das ist eine ziemlich häufige Sache zu tun, oder? Die Syntax dafür ist einfach genug. Wir können für Klammern sagen,
Schiff weniger als, also werfen Sie den linken Pfeilbetreiber ihre Schiffsliste. Und dann ein Ausdruck, der auf dem Schiff operieren wird. Drucken wir es einfach aus. Okay. Dies wird also jedes Element in der Schiffsliste durchlaufen, jede dieser Strings
extrahieren und sie dem Versand zuweisen und dann ausdrucken. Lass uns zuschauen. Ja, es hat funktioniert. Das druckte jeden einzelnen Schiffnamen aus. Und wissen Sie, wenn wir nicht in der Arbeitsblatteinstellung wären, wäre
das
natürlich in separaten Zeilen, aber es versucht, klug zu sein, um Platz für uns zu sparen, was schön ist. Okay, lass uns komisch werden. Lassen Sie uns ein Funktionsliteral auf eine Liste anwenden. Okay, das ist funktionale Programmierung. Wir können so etwas tun. So können wir map verwenden, die Kartenfunktion, um jede Funktion anzuwenden, die wir auf jedes Element in einer Sammlung möchten. Mal sehen, wie das funktioniert. Wir können sagen, zum Beispiel, Val rückwärts Schiffe gleich Schiffsliste Punktkarte. Das bedeutet also,
dass wir jedes Element dieser Liste einer Funktion zuordnen , die wir zur Verfügung stellen werden. Und hier kommt diese Funktion. Wir werden das nur tun, da ein
Funktionsliteral sagen wird, dass wir mit dem Schiff beginnen, das eine Zeichenfolge ist. Und das wird in
geschweifte Klammern umgewandelt werden, um Punkt rückwärts zu versetzen, weil es einen eingebauten Reverse-Operator auf dem String-Operator gibt. Okay, also lasst uns das ein bisschen erweitern. Es lohnt sich, das alles in einem Display zu sehen. Okay, also wickeln Sie Ihren Kopf um das. Nun, das ist irgendwie eine Menge von dem, worüber wir bereits gesprochen haben, zusammenzubinden. Also werden wir eine Liste nehmen. Wir werden die Kartenfunktion verwenden, die in der Welt des verteilten Computing sehr wichtig ist, um jedem Element dieser Liste eine Funktion zuzuordnen. Und diese Funktion wird ein Funktionsliteral sein, bei dem wir nur sagen, dass einige Schiffe String in die Rückseite gemappt werden und das zurückgeben wird. Nachdem wir dies ausgeführt haben, sollten
wir eine neue Liste namens Rückwärtsschiffe haben, die alle Schiffe in umgekehrter Richtung enthält. Also lasst uns weitermachen und diese ausdrucken. Mit vier Schiffen. Wieder rückwärts Schiffe, wir durchlaufen nur alles in dieser Liste, wie wir zuvor gesehen haben. Linienschiff drucken. Okay, also mal sehen, was es tut. Da hast du es. Also Rückwärtsschiffe wurden dieser Liste zugewiesen, wo wir
die umgekehrte Funktion auf jedes einzelne Element dieser Schiffsliste anwenden . Und es machte nur jedes Wort rückwärts. Und dann gingen wir durch ein iteriertes durch jedes
dieser Elemente in dieser rückwärtigen Schiffsliste und druckten sie aus. Also hat es funktioniert. Cool. Nun, es wird reichen. So. Wir haben die Karte gesehen. Sie haben vielleicht von MapReduce gehört. Also lassen Sie uns reduzieren. Gleiches Konzept. So wie wir eine Karte hatten, können
wir reduzieren verwenden, um
alle Elemente in einer Sammlung zu kombinieren , indem wir eine Funktion verwenden, die wir zur Verfügung stellen. Okay? Nehmen wir zum Beispiel an, val number list ist gleich der Liste, die 1, 2, 3, 4, 5. Okay? Einfach genug. Jetzt werden wir sagen, val sum gleich Zahl Liste Punkt reduzieren. Also würde map eine Funktion auf jedes einzelne Element der Liste anwenden. Aber reduzieren wird
jedes Element in der Liste durchlaufen und die gleiche Funktion darauf ausführen, lassen Sie alle Ergebnisse davon akkumulieren. Mit einem Beispiel wird es sinnvoller. So könnten wir sagen, zum Beispiel. Klammern und dann den c x Doppelpunkt int y Doppelpunkt int. Ordnen Sie das X plus Y
zu. Also lasst uns darüber nachdenken, was hier vor sich geht. Also reduziert im Grunde hält eine laufende Summe irgendeiner Art. Es wird also die vorherige Ausgabe der Reduce-Funktion von der vorherigen Iteration nehmen , das in x übergeben. Es wird dann die aktuelle Iteration genommen, die Zahl, die gerade gerade betrachtet, ruft dieses Y auf und wendet eine Operation an
das. Und die Ausgabe dieser Operation wird in
die nächste Stufe eingespeist , wenn wir zum nächsten Element gehen. Also lass mich irgendwie durchlaufen, was hier vor sich geht. Wir fangen mit einem an. Und wir werden sagen, 1 plus 2, das ist 3, wird dann das in die nächste Iteration übergeben. Und wir haben 3 plus 3. Das Ergebnis wird sechs sein. Dann haben wir sechs plus vier. Das Ergebnis davon wird 10 sein, und dann 10 plus 5 sollte 15. In Ordnung, so funktioniert Reduce. Wenn wir fertig sind, drucken wir diesen Wert aus, drucken einige Zeile aus. Lassen Sie es uns ausführen. Sicher genug, ich habe 15. So reduzieren. Es ist nur ein Weg, wie irgendwie alle Ergebnisse in eine endgültige Antwort zusammenzufassen. Und oft wird das verwendet, um wie eine Gesamtsumme oder so etwas zu berechnen. Sie könnten sich einfachere Möglichkeiten vorstellen, dies zu tun. Aber das Schöne an Map- und Reduce-Funktionen ist, dass sie sehr parallelisierbar sind. Es ist also sehr einfach, Kartenfunktionen parallel anzuwenden und dann
die Ergebnisse dieser Kartenfunktionen in einer Art
Reduktionsstufe zu kombinieren die Ergebnisse dieser Kartenfunktionen in einer Art , um die endgültige Antwort zu erhalten, die Sie wollen. Wir werden sehen, dass mehr in Aktion mit Beispielen später im Kurs. Was können wir noch tun, dies eine Filteroperation als auch. Wenn Sie Dinge entfernen möchten, die Sie nicht wollen. Also Filter entfernt Sachen. Zum Beispiel könnten wir eine neue Liste namens Ich hasse fünf machen und übergeben, das dem Nummernlistenpunktfilter
zuweisen, indem wir hier eine weitere Inline-Funktion übergeben. Funktion wörtlich, wenn Sie so wollen. X-Naught gleich fünf. Ordnung? Also, was dies tun wird, ist diese Filterfunktion anzuwenden. Ist x Naught gleich fünf und
gibt das nur in unserer resultierenden Liste zurück, wenn das wahr ist. Mal sehen, was das tut. Das gibt uns wieder eine Liste 1234, weil es den Wert fünf ausgeschlossen. So funktioniert ein Filter. Es kann ungültige Informationen herausfiltern, Ausreißer, was immer Sie wollen. Es ist eine gute Möglichkeit, Daten zu bereinigen. Auch hier auf eine Weise, die parallelisierbar ist. Wir machen das Gleiche. Wir könnten in einer etwas anderen Syntax sagen. Val ich hasse 3s gleich Zahl Liste Punktfilter. Und das ist eine Art Kurzschrift Unterstrich, nicht gleich drei. Anstatt also dieses x
tatsächlich zu schreiben um diesem x-Wert einen Namen zu geben, brauchen wir keinen Namen. Wir wollen nur den Wert nehmen und das gegen drei überprüfen. Das ist also eine Art Kurzschrift Ausdruck, das mit dem Unterstrich zu tun. Mal sehen, was das tut. 12, 45. Also äquivalente Syntax, Sie haben bemerkt, drei statt fünf zu verwenden und ein wenig einfacher zu tippen. Also, wenn Sie diese Syntax sehen, ist
das, was da los ist. Der Unterstrich ist im Grunde ein Platzhalter für jedes Element der Liste. Okay? Okay. Jetzt ist es erwähnenswert, dass Spark über
eigene MapReduce- und Filterfunktionen verfügt , die diese Operationen verteilen. Sie funktionieren genau auf die gleiche Weise. Scala hat also einen eigenen integrierten MapReduce und Filter. Spark hat auch eine eigene MapReduce und Filter. Der Unterschied besteht darin, dass Spark sicher sein wird,
dass dies über alle Maschinen in Ihrem Cluster parallelisiert wird, wenn dies möglich ist. Okay, hey, du verstehst MapReduce jetzt übrigens, das ist das grundlegende Konzept hinter MapReduce. Es ist ziemlich einfach, so wenig Bonus Army für dich. Einige weitere Listenoperationen können Sie durchführen. Wie verkette ich Listen? Syntax dafür? Sagen wir, Val, lassen Sie uns eine andere Liste erstellen. Also haben wir etwas zu spielen. Mehr Zahlen entspricht Liste 678. Und wir können sagen, val, viele Zahlen gleich Zahlenliste plus, plus mehr Zahlen. Um also zwei Listen miteinander zu verketten, verwenden Sie diesen doppelten Plus-Operator. Mal sehen, was das tut. Kontrollieren Sie Alt W. Also da haben Sie es. Wir haben eine neue Liste namens viele Zahlen. Ich kann die Zahlenliste verketten, die 1, 2, 3, 4,
5 und die mehr aufgelisteten Zahlen 678 zu einer einzigen Liste enthalten , 1, 2, 3, 4, 5, 6, 7, 8. Beachten Sie, dass wir kein Tupel von zwei Listen erhalten haben. Es ist eine einzelne Liste, die alle Werte aus diesen beiden Listen enthält. Einige weitere zufällige Dinge, die wir mit Listen tun können. Also kommen wir rückwärts. Was ist in einer Liste mit umgekehrter gleich Zahlenliste Punkt rückwärts, Fünf 4321. Und sie waren eigentlich eine Interview-Frage, die ich den
Leuten bei Amazon geben würde , die Wörter in einer Zeichenfolge
umzukehren oder die Elemente einer Liste umzukehren, das war schwer zu tun und die meisten Programmiersprachen, aber wenn Sie Scala verwenden, können
Sie es in einer Codezeile tun. So wenig zu betrügen. Sie sortieren. Sie können sagen, val sortiert gleich umgekehrter Punkt sortiert. Hoppla, ich hoffe, ich habe rückgängig geschrieben, richtig? Also lasst uns weitermachen und das sortieren. Und das ist wieder in sortierter Reihenfolge. 1, 2, 3, 4, 5. Leicht pfirsig. Was würdest du sonst noch Vokal machen? Viele Duplikate. Gleich Zahlenliste plus plus zahllos. Lassen Sie uns also die beiden Listen miteinander verketten und sehen, was passiert. Wir verketten eine Liste mit sich selbst und Sie sehen, dass wir das tun können. 1234512345. Die Elemente einer Liste müssen also nicht eindeutig sein. Du darfst keine Duplikate drin haben. Das zeige ich dir mit diesem kleinen Beispiel. Aber wenn Sie nichts als eindeutige Werte wollten, können Sie das auch tun. Wir könnten sagen, val unterschiedliche Werte gleich vielen Duplikaten, dot distinct. Und das wird nur diese eindeutigen Werte innerhalb dieser Liste zurückgeben. Und Sie sehen, wir sind zurück zu 12345. Es gibt keine Duplikate in diesem eindeutigen. Ich möchte nur das Maximum erhalten, den Maximalwert in einer Liste Das ist einfach. Der Maximalwert des Vokals entspricht Zahlenliste Punkt x und das ist fünf. Wenn Sie die Summe erhalten wollten, könnten
wir sagen, val total gleich Zahl Liste Punkt. Ein bisschen einfacherer Weg, es zu tun, als eine reduzierte Funktion zu verwenden. Das funktioniert auch. Wir haben den Wert 15. Es gibt viel einfacher. Und wir könnten sagen, wenn Sie überprüfen möchten, ob ein Element in einer Liste existiert, ist
das auch einfach zu tun. Val hat drei Gleiche, ich hasse drei. Punkt enthält drei, also überprüfen wir die „Ich hasse drei“ -Liste, die wir
zuvor gemacht haben , um zu sehen, ob es den Wert drei enthält, sollte es nicht. Sicher genug, dass als falsch zurückkam. Alles klar, wir kommen dorthin, Jungs. Das letzte, worüber ich reden möchte, sind Karten. So können Sie diese als Wörterbücher kennen und andere Sprachen sind ein Schlüsselwert Lookups für verschiedene Schlüssel. Sehr nützliche Datenstruktur in vielen verschiedenen Situationen. Lassen Sie uns darüber reden, wie das funktioniert. Lassen Sie uns eine Karte einrichten, die Schiffskarte genannt wird. Kleiner Kommentar hier drin. Wir wissen also, dass wir über Apps sprechen, die sie wichtig sind. eval shit map wird also gleich
einem Kartenkapital M sein , das die folgenden Schlüsselwertpaare enthält. So zum Beispiel, Kirk,
Pfeil, Unternehmen, Komma Picard,
Pfeil Unternehmen D, Cisco, Deep Space Nine, Janeway, Voyager. Ich könnte weitermachen, Archer und so weiter. Aber ich erspar dir das Tippen. Also, was wir hier getan haben, ist, ein Kartenobjekt zu erstellen. Stellen Sie sicher, dass ich das richtig abschließe. Und Sie können sehen, dass wir dort ein Kartenobjekt zurückbekommen haben, das Strings Strings an Strings abbildet. Auch hier müssen die Datentypen gleich sein. Also kartieren wir Captain benannte Strings zu ihrem Schiff namens Strings. Und Sie können Strings zu Ints oder so etwas zuordnen, aber Sie müssen
mindestens einen konsistenten Typ innerhalb jedes Schlüsselwert-Paares haben. Das macht Sinn. Also, wenn wir diese Karte benutzen wollten, könnten
wir etwas sagen wie Drucklinie, verschickte Karte, Janeway in Klammern und Control Alt W, das gibt uns wieder Voyager. So können Sie sehen, dass wir eine kurze kleine Nachschlagetabelle dort haben, die wir mit einer Karte definiert haben, die uns den Wert Voyager mit dem Schlüsselnamen Janeway
zurückgibt. Sehr nützliche Sache in vielen Situationen. Was ist mit fehlenden Schlüsseln? Also habe ich absichtlich einen der Kapitäne des Schiffes weggelassen. Nehmen wir an, Linie drucken. Schiff, Karte Punkt enthält Bogenschütze. Archer ist nicht in meiner Liste auf meiner Karte. Das kommt als falsch zurück. Wie gehe ich damit um? Was passiert, wenn ich versuche, suchen Sie nach oben Bogenschütze, wo er nicht in der Karte existiert. Probieren wir es aus. Val Bogenschützen Schiff gleich util dot versuchen. Also machen wir hier einen Versuchsblock, Schiffskarte, Archer, oder sonst Unbekannt. In Ordnung, also machen wir hier eine Ausnahmebehandlung. Und dann drucken wir Linie oder Touristenschiff. Ups, Drucklinie, Bogenschützen, Schiff, Kontrolle, Alt W. Also im Grunde tun wir hier wie eine kleine Ausnahmebehandlung. Also versuchen wir, unseren anderen Block hier zu bekommen. Indem wir also Scheißkarte Archer in diesen Versuchsblock einpacken, bedeutet das, dass es nicht gerne ballistisch gehen wird, weil unser wahres nicht existiert. Wir erhalten in diesem Fall einen undefinierten Wert zurück. So wird die Ausnahmeausnahme dort ausgelöst. Und es ist stattdessen diese Getter else Klausel und gibt eine Zeichenfolge zurück, die in diesem Fall unbekannt ist. Das ist also eine Möglichkeit fehlende Werte in einer Karte zu behandeln oder mit der Möglichkeit zu umgehen, Werte in einer Karte zu fehlen. Okay, das ist definitiv genug. Und wir sind fertig mit den Grundlagen von Scala. Also, weißt du, gerade genug, um hier gefährlich zu sein. Jetzt werden wir viel mehr Übung bekommen, während wir den Kurs
durchlaufen , indem wir uns viele verschiedene Beispiele ansehen. Und so wirst du es wirklich lernen. Aber ich hoffe, dass dies zumindest einige der Syntax für Sie entmystifiziert. Eine letzte Übung für Sie. Lassen Sie mich das in einer letzten Herausforderung kopieren. Also hier ist es für Sie. Ihre Herausforderung, wenn Sie es akzeptieren, erstellen Sie eine Liste der Zahlen eins bis 20. Und ich möchte, dass Sie die Zahlen ausdrucken, die gleichmäßig durch drei teilbar sind. Und es gibt ein paar Hinweise hier im Text, die Sie führen könnten. Auch hier ist dies eine sehr häufige Interview-Frage, die ich verwendet habe um Menschen während Telefonbildschirme und Amazon zu geben, Sie würden erstaunt sein, wie viele Leute dies nicht erfolgreich in
einer Sprache tun konnten , die sie versuchen wollten, und es in Scala zu tun. Es gibt einen Modulo-Operator, wie in anderen Sprachen, über die ich hier spreche, der Ihnen den Rest nach der Division gibt. Alles, was durch drei teilbar ist, sollte ein modulo 3 haben, das als 0 zurückkommt. Das ist also dein erster Hinweis. Also durchlaufen Sie einfach alle Elemente in den Listentests. Dieser Modulo-Test ist, dass Sie gehen und Sie können es
dann wieder tun, indem Sie stattdessen eine Filterfunktion auf der Liste verwenden. Also ein paar Möglichkeiten, wie Sie es machen können. Gehen Sie weiter und üben Sie dort. Und danach, denke ich, du wirst wissen, dass genug Skelett gefährlich ist. Und wir werden weitermachen und tatsächlich in die Eingeweide von Apache Spark selbst kommen.
8. Der standhaft verteilte Datensatz: Lassen Sie uns also in Spark selbst eintauchen und wir beginnen mit einem Überblick über Spark und auch seine ursprüngliche API, die RDD. Wir werden in Kürze darüber reden, was das bedeutet. Das war die erste API, die Funken in Spark eins herauskam. Und obwohl es in
nachfolgenden Versionen weitgehend durch neuere APIs ersetzt wurde , ist es immer noch da draußen. Sie werden es immer noch von Zeit zu Zeit verwenden müssen. Und es gibt einige Probleme, wie wir sehen werden, wo RDDs immer noch die effizienteste Lösung sind. Sie müssen auch immer noch auf
einige Drittanbieter-Bibliotheken stoßen , die Sie möglicherweise verwenden möchten RDDs und Sie müssen möglicherweise auch einen Legacy-Code betrachten, der zwei verwendet,
so dass es sich immer noch lohnt, zu lernen. Nach diesem Abschnitt werden
wir uns jedoch auf modernere APIs wie Datenrahmen und Datasets konzentrieren. Aber jetzt fangen wir mit den Grundlagen an und lernen den Kern Spark selbst, die RDD. Lassen Sie uns also beginnen, indem wir über Funkenwurzeln sprechen und das ist die RDD-Schnittstelle. Rdd steht für Resilient Distributed Dataset, nicht zu verwechseln mit Datensätzen in Spark, das ist eine andere Sache. Datensätze sind eher verwirrend auf RDDs aufgebaut. Es ist eine übergeordnete API. Aber in seinem Kern sich
Spark alles um RDDs. Und was ist das? Nun, im Grunde ist eine RDD eine Reihe von Datenzeilen irgendeiner Art. Und weil es in Zeilen unterteilt ist, können
diese Zeilen auf
verschiedene Computer verteilt und parallel auf diesen verschiedenen Computern verarbeitet werden. Deshalb ist es verteilt. Es ist also ein Dataset, weil es eine Reihe von Zeilen von Informationen verteilt wird weil wir diese Zeilen möglicherweise auf mehrere Computer aufteilen können. Und es ist widerstandsfähig, weil, naja, Funke stellt sicher, dass die Verarbeitung, die Sie auf
der RDD machen , auf die eine oder andere Weise durchgeführt wird, oder? Es ist also Funkenproblem herauszufinden, was passiert, wenn ein Knoten in der Mitte
Ihrer Operation heruntergeht , um einen neuen zu drehen, um seinen Platz einzunehmen. Das erste, was Sie tun müssen, bevor Sie
eine RDD und Spark erstellen , ist ein Spark-Kontext zu erstellen. Und Ihr Treiberprogramm wird dies als eines der ersten Dinge tun, die es tut. Das Spark-Kontextobjekt ist also dafür verantwortlich, diese RDDs robust und verteilt zu machen. Sie müssen den Code nicht schreiben, um sicherzustellen, dass Sie keine Fehler oder Hardwarefehler
behandeln können . Sie müssen den Code nicht schreiben, um herauszufinden, wie diese Daten über Ihren gesamten Cluster
verteilen. Die RDD selbst im Spark-Kontext findet heraus, wie Sie das für Sie tun können. Alles, worüber Sie sich Gedanken machen müssen, ist, wie Sie Ihre Daten transformieren können. Ihr Spark-Kontext erstellt also die von Ihnen angeforderten RDDs. Und wenn Sie die Spark-Shell interaktiv verwenden, wird automatisch ein Objekt für Sie erstellt, das ist Ihr Spark-Kontext. Sie müssen es explizit erstellen, es ist bereits da. Dies wird mehr Sinn machen, wenn wir uns einen Code ansehen. Wie erstelle ich eine RDD? Normalerweise ist es ziemlich einfach. Eine Möglichkeit besteht darin, ihm einfach eine explizite Liste von Sachen zu geben. Also das erste Beispiel gab es sagen, val nums gleich parallelize Liste 1, 2, 3, 4. Das wird eine RDD namens nums erstellen, die nur in jeder Zeile 1, 2, 3 und 4 enthält. Offensichtlich ist das in der realen Welt nicht schrecklich nützlich, denn wenn Sie in der Lage sind, aufzuschreiben und fest zu codieren, was in Ihrer RDD ist. Es sind wahrscheinlich keine Big Data und es sind wahrscheinlich auch keine echten Daten. wissen
Sie, zum Testen von Dingen, Testfällen manchmal ist das hilfreich. Häufiger werden Sie Daten aus einer Textdatei irgendwo laden. Und dazu können Sie einfach SC sagen,
vorausgesetzt, das ist Ihre Spark-Kontextobjekt-Punkt-TXT-Datei und übergeben Sie es
den, den Pfad zu Ihrer riesigen Textdatei und so. Und das wird eine RDD erstellen, in der jede Zeile dieses Textes ihre eigene Zeile in der RDD ablegt. Und es muss nicht aus dem lokalen Dateisystem kommen. Jetzt besiegen Sie den Zweck von Big Data, richtig? So kann es auch von verteilten Dateisystemen einschließlich HDFS lesen, das Hadoop Distributed File System ist, oder sogar Amazon
S3, S3 und n wäre das Präfix dafür. Es gibt also immer Erweiterungen zum Laden von Daten in eine Spark RDD aus verschiedenen verteilten Datenquellen, weil Funken alles über Big Data, richtig? Daher ist seine Fähigkeit, Daten aus
verteilten Datenspeichern zu laden , eine Art von grundlegender Bedeutung für das, was Sie tun. Es muss jedoch keine Textdatei sein. Sie könnten sogar eine,
eine RDD aus einem, aus einem Bienenkontext erstellen. Zum Beispiel, wenn Sie Hive verwenden, und Sie können dann umdrehen und einfach
SQL-Befehle auf diesem hohen Kontext ausführen , wenn Sie es auch möchten. Das ist also eine Möglichkeit, SQL in der Hadoop-Umgebung zu tun. Sie können RDDs auch direkt aus JDBC erstellen. Wenn Sie also irgendwo eine Datenbank haben, können
Sie diese ziemlich einfach in eine RDD und Spark umwandeln. Sie können keine SQL-Datenbanken wie Cassandra oder Hbase sprechen. Sie können es auch in Elastic Search integrieren, wenn Sie möchten. Und es muss keine Textdatei sein, entweder können Sie strukturierte Daten wie
JSON- oder CSV-Dateien oder Sequenzdateien oder Objektdateien verwenden . Und es unterstützt auch verschiedene komprimierte Formate. Auch bei Big Data werden manchmal Daten komprimiert. Und solange es sich um ein verlustfreies Format handelt, das parallelisiert werden kann, können
Sie auch eine RDD daraus erstellen. Wenn Sie eine RDD haben, was machen Sie damit? Nun, Sie möchten es wahrscheinlich in
irgendeiner Weise transformieren und es gibt verschiedene Operationen dafür. Karte, zum Beispiel, funktioniert genau wie MapReduce wirklich. Es ermöglicht Ihnen, eine Funktion auf jede Zeile Ihrer RDD parallel anzuwenden. Und wir werden in Kürze ein Beispiel dafür sehen. Flatmap ist ähnlich. Der einzige Unterschied zwischen Karte und FlatMap besteht darin, dass die Karte eine Eins-zu-Eins-Beziehung hat. Also Karte wird eine Zeile Ihrer RDD nehmen und diese in eine Zeile einer anderen RDD verwandeln. Flatmap, wer auch immer die Dinge aufteilen kann. FlatMap könnte also eine Zeile einer RDD nehmen und mehrere Zeilen in einer anderen RDD erstellen. Wenn Sie zum Beispiel eine Liste von Sachen in jeder Zeile hätten, könnte
FlatMap das in einzelne Zeilen für jedes Ding aufteilen. Und das werden wir in einem Beispiel in Kürze sehen. Sie können auch Filter durchführen. Wenn Sie also Daten entfernen, Daten
bereinigen möchten , können Sie das auch tun. Sie können eine Filterfunktion definieren, mit der jede Zeile getestet wird. Und wenn diese Funktion false zurückgibt, wird
sie in der resultierenden RDD wegwerfen. Das ist also eine gute Möglichkeit,
Ihre Daten zu säubern und fehlende Daten loszuwerden, Dinge wie diese. Sie können auch unterschiedlich darauf laufen. Wenn Sie doppelte Werte in Ihren RDDs entfernen möchten, können Sie sie abtasten. Und wenn Sie nur eine kleine Probe einer RDD
für Experimentierzwecke oder was auch immer nehmen möchten. Und Sie können auch ausgefallene boolesche Operationen zwischen RDDs durchführen, wie die Vereinigung von zwei RDDs, die Schnittmenge von zwei RDDs, Sie können eine RDD von einem anderen subtrahieren oder ein kartesisches Produkt zwischen zwei RDDs durchführen. Dies sind fortgeschrittenere Anwendungsfälle. Sehen wir es in Aktion. Also sagen wir, ich möchte nur alles in meiner RDD quadrat. Nehmen wir an, Sie haben eine RDD, die ich RDD wirklich kreativen Namen nenne, richtig? Und wir haben das gemacht, indem wir diesen parallelisierten Trick wieder machen, wir haben nur eine RDD von vier Zeilen, in denen jede Zeile jeweils 1234 enthält. In der nächsten Zeile erstellen wir eine neue RDD namens Quadrate,
indem wir nur RDD dot map x auf x mal x aufrufen. Also, was dies tut, ist die Übergabe der Funktion, nehmen Sie X und transformieren Sie diese in x mal x und wenden Sie sie auf jede Zeile in der RDD, RDD, wird die resultierende RDD Quadrate genannt. Wenn wir also sind, nachdem wir diese Kartenoperation ausgeführt haben, enthalten
Quadrate die folgenden Zeilen, 1, 4, 9 und 16, richtig? Also folgen wir, folgen mir dorthin. Und die Schönheit davon ist, dass, Das kann verteilt werden. Wenn also bereits D wirklich massiv war, könnte
es diese Verarbeitung tatsächlich aufteilen und diese
Quadratur auf verschiedenen Blöcken dieser RDD auf verschiedenen,
verschiedenen Knoten innerhalb Ihres Clustersverarbeiten Quadratur auf verschiedenen Blöcken dieser RDD auf verschiedenen, verschiedenen Knoten innerhalb Ihres Clusters und dann alle diese Ergebnisse zurück zu Ihrem Treiberskript, um die endgültigen Antworten zu erhalten, die Sie möchten. Also, das ist ein bisschen seltsame Syntax dort. hättest du vielleicht noch nicht gesehen. Das x bis x mal x Ding von dem, was da los ist? Nun, das ist es, worüber wir reden, wenn wir funktionale Programmierung sagen. So werden viele RDD-Methoden eine Funktion als Parameter und nicht nur als Wert
akzeptieren. Und das ist es, was hier los ist. Also syntaktisch x und dann ist der flippige Pfeil zu x mal x genau das gleiche wie das Definieren einer Funktion, um etwas zu quadrieren. Wir nennen es quadratisch. Und diese Folie, die eine ganze Zahl namens x nimmt und x mal x zurückgibt. Eigentlich wäre das Rückgabe-Schlüsselwort optional und Scala, Sie können einfach x mal x sagen und es würde einfach funktionieren. Und dann, indem Sie RDD-Punktkarte sagen, die in der Quadratwurzel-Funktion übergeben
wird, würde es diese Quadratwurzel-Funktion auf alles in dieser RDD anwenden. Aber syntaktisch ist es genau das gleiche, wie RDD Punkt Karte x, funky Pfeil x mal x. Also neigen Sie dazu, diese Abkürzung zu sehen. Wenn Sie eine sehr einfache Transformation haben, die Sie tun
, können Sie dort in eine Zeile gelangen. Aber das ist alles, was es ist. Als ob wir diese Funktion weitergeben. In diesem Beispiel definieren
wir eine Funktion zum Quadrat von Zahlen. Und wir übergeben diese Funktion über den Kartenoperator dort in die RDD. Und das ist es, dass Sie die funktionale Programmierung verstehen. Nun, das ist das Schlüsselkonzept. Wir übergeben nur Funktionen. Und die größere Einsicht hier ist, dass, wissen Sie, die Sprache der Skalierung selbst Sie irgendwie dazu zwingt, diese Funktionen zu schreiben, die verteilt werden können. Also die Funktionen der Skalierung und machen es einfacher, dies etwas zu tun, aber das ist, das ist es. Das ist alles, was wir mit funktionaler Programmierung meinen. Wissen Sie, wir denken parallel und wenden Funktionen an, zwei große Mengen von Daten an, indem diese Funktionen an Dinge wie RDDs darüber weitergeben, Das ist es. Es sind nicht so harte Kerle. Alles klar, sobald Sie tatsächlich alles in Ihrem RDD so transformiert haben, wie Sie es wollen. Was machst du damit? Wie erhalten Sie Ihre Ergebnisse zurück? Nun, darum geht es bei einer RDD-Aktion. Eine Aktion ist also im Grunde etwas, das dazu führt, dass Ihre RDD zusammenbricht und Ihnen ein Ergebnis zurück zu Ihrem Treiberskript gibt. Eine Sache, die Sie tun könnten, ist Call sammeln auf der RDD, die Ihnen
alles in dieser RDD als eine riesige Datenstruktur in Scala zurückgeben wird. Wissen Sie, wenn es sich um einen großen Datensatz handelt, der nicht viel Sinn werden
Sie versuchen, mehr von einer reduzierten Operation aus ihm herauszuholen. Zum Beispiel könnten wir sagen zählen, wenn wir nur zählen wollen, wie viel Zeug in der RDD ist, können
wir sagen, zählen nach Wert. Wenn Sie eine Anzahl davon erhalten möchten, wie viele Zeilen für jeden bestimmten eindeutigen Wert in einem Schlüssel-Wert-Paar
vorhanden sind. Sie könnten nur eine bestimmte Anzahl von Zeilen von der RDD oben nehmen, um
die ersten paar Zeilen zu nehmen oder zu reduzieren, um eine Art
Gesamtsumme aus allen Zeilen in Ihrer RDD zu erhalten . Und es gibt auch noch mehr Aktionen. Aber die Grundidee ist, dass eine RDD-Aktion Ihnen eine Antwort auf Ihr Treiberskript gibt. Also hat es eine Kraft, Spark auszugehen und zu sagen, Okay, ich werde Sie Executor Prozesse fertig haben, was Sie tun, und geben Sie mir eine Antwort. Und wir werden diese Antwort an mein Treiberskript zurückgeben. Das ist also, was eine Aktion tut. Und die Art und Weise, die funktioniert, ist irgendwie interessant. Also musst du dich daran erinnern, in Spark. Nichts passiert wirklich in Ihrem Treiberprogramm, bis Sie eine Aktion aufrufen. Es ist eine Art faule Evaluierungsstrategie hier. Und dafür gibt es einen sehr guten Grund. Also, bis Spark weiß, was Sie durch die Aktion erreichen wollen, die Sie am Ende versuchen, es weiß nicht, wie Sie alle Operationen, die Sie getan haben, zu optimieren. Denken Sie also daran, dass der Schlüssel oder ein Schlüssel zu Spark Leistung ist, dass es
diesen gerichteten azyklischen Graphen konstruieren kann , der sehr für das Endergebnis
optimiert ist , das Sie erreichen möchten. Dies kann also ein wenig verwirrend sein, wenn Sie Ihre Spark-Treiberskripte
debuggen, da Sie wissen, eine Kartenoperation oder eine Art Transformation auf Ihrer RDD aufrufen können. Und es wird so aussehen, als wäre nichts in deinem Code passiert. Erst wenn Sie tatsächlich
eine Aktion aufrufen , wird alles tatsächlich ausgeführt und an die verschiedenen Knoten in Ihrem Cluster gesendet, und Sie erhalten tatsächlich ein Ergebnis. Das kann also das Debuggen ein wenig schwierig machen, oder? Manchmal müssen Sie
ein wenig vorübergehende Aktion dort stecken , um zurück und Zwischenergebnis in zu bekommen. Stellen Sie sicher, dass es das ist, was Sie erwarten, wenn Sie die Spark-Treiberskripts debuggen. Also etwas, das Sie sich bewusst sein müssen, besonders während Sie diese Dinge debuggen. Und damit lasst uns als nächstes in einige weitere Besonderheiten eintauchen.
9. Ratings: Also ist es im Allgemeinen am besten, Dinge durch ein Beispiel zu verstehen, oder? Also lasst uns das machen. Lassen Sie uns über RDDs lernen, indem Sie sich ein wirklich einfaches Beispiel für ihre Verwendung ansehen. Wir werden also in einem einfachen Beispiel in unseren Kursmaterialien eintauchen, das nur die Anzahl einer bestimmten Bewertung innerhalb unseres MoviElens-Datensatzes
zählt. Wie Sie sich erinnern, ist
das Movielens-Dataset ein Datensatz von 100 Tausend Filmbewertungen, bei denen Leute eine Reihe von Filmen von einem bis fünf Sternen bewertet haben. Und sagen wir, wir wollen nur herausfinden, wie viele Ein-Sterne-Bewertungen es gibt, wie viele Zwei-Sterne-Bewertungen, wie viele Drei-Sterne-Bewertungen, et cetera? Nun, das können wir mit Apache Spark machen. Bevor ich also in den Code eintauche und was er tut, lassen Sie uns ihn einfach ausführen und sich mit dem vertraut machen, was er tut und sich irgendwie mit dem Code selbst vertraut machen. Also lasst uns das machen. Also, wenn Sie Intelligenz öffnen und hier zur Rating-Zählerdatei gehen, das ist die, mit der wir hier spielen und in ein
sehr einfaches Beispiel für ein Apache Spark-Treiberskript hier eintauchen werden. Und wir werden über jede Zeile sprechen und darüber, was sie tut. Aber auf einem hohen Niveau, was wir tun, ist das Laden des MoviElens-Datensatzes über jeden CPU-Kern unserer Maschine hier. Und wir werden zählen, wie oft jeder einzelne Bewertungswert innerhalb dieses Datensatzes auftritt. Also werden wir jede Zeile laden, die jede Bewertung in diesem Datensatz darstellt. Und wir werden das in eine eigene RDD aufteilen. Wir werden zählen, wie oft jede Bewertung tatsächlich erscheint, sortieren die Ergebnisse und drucken sie aus. Und lassen Sie uns einfach laufen und
uns davon überzeugen , dass es funktioniert und etwas Interessantes macht, richtig? Also lasst uns mit der rechten Maustaste auf Bewertungen Zähler und sagen Run. Und wenn wir auf klicken, gehen wir. Und das sollte in Spin up Spark gehen. Und da sind unsere Antworten. Was uns das sagt, ist, dass wir 61101 Sternebewertungen, 11.372 Sternebewertungen, 27.145, Drei-Sterne-Bewertungen und so weiter und so weiter hatten. Und diese Daten selbst sind irgendwie aufschlussreich, oder? Wie es uns sagt, dass die häufigste Bewertung für einen Film vier Sterne ist. Und es gibt eine Menge von drei Sternen und fünf Sterne sind nicht auch da. Aber die Leute neigen dazu, dass schien
eine vernünftige Skala zu haben , wie sie diese Filme lesen. Und sie scheinen zu reservieren, ein Stern ist für das Schlimmste des Schlimmsten. Von 100 Tausend Bewertungen, nur 6000 und einige Änderungen, sind
wir tatsächlich mit einem Stern bewertet. Das gibt uns also einige Zuversicht, dass diese Daten nur in diesem sehr einfachen Skript hier
sinnvoll sind, sogar. Also, gehen wir zurück und sprechen über mehr darüber, was dieser Code tut. Lassen Sie uns also durch, was dieser Code bei jedem Schritt hier macht. Also fangen wir an, indem wir importieren, was wir brauchen. Und wir sagen nur, wir erklären dies innerhalb des Pakets , das wir com Dotson Hunde Software genannt haben, dot spark. Wissen Sie, das ist eine Art Konvention in der Java-Welt wie Sie Ihren Paketen einen eindeutigen Namen geben. In diesem Fall verwende ich einen Domainnamen, den ich besitze. Und dann importieren wir die Pakete, die wir brauchen. Wir importieren nur alles aus Spark und alles aus log für J, weil wir ein Protokoll für J
verwenden, um unseren Fehlergrad in unserer Protokollierung anzupassen. Das ist alles, was ist. Als Nächstes richten wir einen Spark-Kontext ein, wie wir zuvor gesprochen haben. Also setzen wir SC auf einen neuen Spark-Kontext. Die lokalen Klammern Stern bedeutet, dass wir nur auf unserer lokalen Maschine laufen werden. Also haben wir hier nicht wirklich einen Cluster in unserem Wohnzimmer laufen, oder? So. Zum Zweck des Experimentierens und Lernens werden
wir nur auf unserer eigenen Maschine laufen. Aber dieser Stern bedeutet, dass ich ihn selbst parallelisieren lasse, zumindest in den mehreren CPU-Kernen, die auf meinem Rechner existieren könnten. Obwohl es auf einem System ist, könnte
es tatsächlich mehr als einen Prozess hochlaufen und die verschiedenen CPU-Kerne
nutzen , die ich habe. Und Bewertungen Zähler ist genau das, was wir diese Anwendung nennen. Als nächstes laden wir die Daten und wir erstellen nur eine Zeile RDD durch den
Aufruf von SC dot txt Datei mit einem relativen Pfad, wo diese Daten sind. In unserem Code ist dieser Pfad expliziter, wo er sich tatsächlich in unseren Kursmaterialien befindet, aber Sie bekommen die Idee. Es hat also einen Pfad zur u dot Datendatei, die die Datendatei ist, die alle Messinformationen und das Format davon enthält. Ein Beispiel dafür ist in der oberen linken Ecke hier. Jede Reihe sieht also so aus. Es beginnt mit einer Benutzer-ID und dann einer Film-ID und dann einer Bewertung und dann einem Zeitstempel. Also ist hier alles in eine Art numerische ID codiert. Ich meine, ich weiß nicht, was User-User 196 ist oder was Film-ID 242 ist. Es gibt eine separate Datei, um diese zu suchen. Aber Benutzer-ID 106 bewertet Film 2423 Sterne. Und sie taten es zu dieser Zeit, was in ein paar, wissen Sie,
ein Datum übersetzt und dass wir menschlich Gier, aber Computer wie Epoch Sekunden. Das ist also nur das Format dieser Daten. Das erste, was wir tun werden, ist,
alle 100.000 Zeilen dieser Datei in die RDD einer Zeile zu laden , wobei jede Zeile eine Zeile dieser Datendatei darstellt. Ok? Und wieder, wir fangen hier mit RDDs an. Wir werden im nächsten Abschnitt darüber sprechen, wie man all diese Dinge mit Datensätzen statt, die die modernere API ist. Aber wieder, sie sind beide nützliches Werkzeug. Manchmal sind RDDs schneller als Datasets. Manchmal können Sie mit RDDs mehr tun. Wir beginnen also mit den Grundlagen, der niedrigeren API hier von RDDs. Und Sie werden feststellen, dass die Verwendung von Datasets nicht wirklich sehr unterschiedlich ist. Aber fangen wir mit RDDs hier an. Also im Moment haben wir eine Linie RDD. Als nächstes mussten wir etwas mit diesen Daten tun. Das erste, was wir tun wollen, ist, die Informationen zu extrahieren , die uns wirklich wichtig sind, aus dieser RDD. Also werden wir die Karte auf den Linien RDD aufrufen und es in einer Funktion
übergeben, wie wir jede Zeile dieser RDD transformieren wollen. Und in diesem Fall nimmt die Funktion jede Zeile und ruft sie x auf. Und dann in dieser Zeile, diese Zeichenfolge, werden
wir sie explizit in eine Zeichenfolge konvertieren und Split darauf aufrufen, indem wir das Tab-Zeichen aufteilen, weil dies tabulatorgetrennte Daten und Extrahieren passen Sie die Feldnummer 2. Denken Sie nun daran, in der Informatik beginnen wir oft mit 0 zu zählen. Also zwei ist eigentlich die dritte Datenspalte. Also, was das tut, ist die Extraktion dieser dritten Spalte, die die Bewertung selbst ist, und nichts anderes. Es extrahiert also diese Bewertung aus jeder Zeile und fügt sie in eine neue RDD namens Ratings ein. Folgen Sie mir. Also beginnen wir mit einer Linie RDD, das sind die in der oberen linken Ecke dort. Wir rufen eine Kartenfunktion auf, um diese Funktion auf jede einzelne Zeile
der Zeilen RDD anzuwenden , um diese dritte Spalte von Daten, die Bewertung selbst zu extrahieren. Und das geht in eine neue RDD namens Ratings, die in diesem Beispiel nur 33 eins
zu eins in jeder Zeile der Ratings RDD enthalten würde . Das ist, was Mapping für
dort verwendet wird , es ist nur, um die Daten zu extrahieren, die uns wichtig sind. Und Sie wissen, in einigen Fällen könnten Sie Dinge neu formatieren oder in ein anderes Format
einfügen, das von einem nachgelagerten Prozess gewünscht wird. Aber im Allgemeinen ist das, worum es bei Mapping geht. Also, jetzt müssen wir etwas mit all diesen Informationen tun. Also in diesem Fall werden wir eine Aktion ausführen und unsere Aktion in diesem Fall ist Zählung für Wert. Das wird dazu führen, dass unsere Daten zusammenbrechen und uns eine Antwort geben. Also, dass das Mapping, das wir in der vorherigen Folie gemacht haben, auf viele Executor Knoten verteilt worden sein
könnte, richtig? Aber indem wir sagen,
dass wir die Werte zählen wollen, wird uns eine explizite Antwort geben
und ein Ergebnis als Scala-Objekt an unser Skript zurückgeben. Also in diesem Fall sagen wir Bewertungen Punktzahl um einen Wert. Das wird tun, was es sagt. Geben Sie eine Zählung an, wie oft jeder einzelne Wert angezeigt wird. In diesem Beispiel haben
wir 23 Bewertungen. Also bekommen wir den Wert drei Komma zwei zurück,
was bedeutet, dass es für die Bewertung 3 zwei von ihnen gibt. Für die Bewertung eins gibt es auch zwei von ihnen. Und für die Bewertung zwei gibt es nur einen von ihnen. Das ist also, was die Anzahl nach Wert zurückgibt. Und in diesem Fall gibt es uns keine neue RDD zurück. Es gibt das an unsere Treiberskripte zurück, die in
einen neuen Wert namens Ergebnisse auf der Scala-Ebene gehen . Indem wir diese Aktion aufrufen, haben
wir diese Ergebnisse aus
dem Cluster zurückgenommen und in unser lokales Laufwerk oder Skript zurückgesetzt. Und an diesem Punkt sind wir nicht mehr in Spark Land waren wieder in Scala Linie. Wir sind wieder in unserem Fahrerskript. Dort lebt der Staat an dieser Stelle. Und an diesem Punkt wollen wir es einfach sortieren und anzeigen. Also haben wir hier einen kleinen einfachen Scala-Code, um diesen Satz von Ergebnissen zu nehmen, sie in eine Sequenz zu
konvertieren und sie nach dem zweiten Feld zu sortieren. Und dann drucken wir sie einfach aus, indem wir
die Druckzeilenfunktion auf jede Zeile dieses Endergebnisses anwenden , auf jede Zeile dieser Sequenz, die wir definiert haben, richtig? Also wieder, das ist nur Scala-Syntax hier. Wir nehmen die Ergebnisse, konvertieren sie in eine Sequenzdatenstruktur sortieren sie nach dieser zweiten Spalte. Und dann wenden
wir für jede Zeile dieser Sequenz in Scala die Druckzeilenfunktion an, um den Inhalt davon auszudrucken. Und so sehen wir hier unser Endergebnis. Wo wir gesehen hatten, dass wir zu 1 Sterne-Bewertungen, 12 Sterne Bewertung, und zwei Drei-Sterne-Bewertungen. Also ist es einfach. Wieder. Lassen Sie uns es laufen und überzeugen Sie uns einfach wieder, dass es jetzt
funktioniert, wo wir mehr eine Wertschätzung dafür haben, was der Code tut. Jetzt, da wir über diesen Code ausführlicher gesprochen haben, sollte es ein wenig mehr Sinn machen,
wenn wir uns das noch einmal ansehen. Also einige Dinge, über die wir nicht gesprochen haben. Also zuerst haben wir all diesen Code eingewickelt und die Integration ist Gegenobjekt. Das ist also einfach so, wie die Dinge für ein Treiberskript und in Scala strukturiert werden müssen. In diesem Radiuszählerobjekt definieren
wir also eine Hauptfunktion. Dies ist im Grunde die Struktur, die jedes Treiberskript für Apache Spark entsprechen muss . Und das erste, was wir getan haben, worüber wir nicht wirklich mit
der Einstellung der Fehlerstufe in unseren Protokollen auf Fehler gesprochen haben. Und leider, wie Sie hier gesehen haben, schlüpften einige Warnungen durch, bevor dieser Code tatsächlich von Spark ausgeführt wurde. Aber sobald das Treiberskript tatsächlich ausgeführt wird, wird das verhindern, dass Protokollmeldungen, die etwas weniger als ein Fehler
sind, angezeigt werden. Und das ist nur, um unsere Spannweite zu reduzieren und uns die Ergebnisse sehen zu lassen. Also wollen wir mehr sehen als eine Reihe von Warnungen, gegen die wir nichts tun können. Danach kommen wir in den Code, über den wir in den Folien gesprochen haben. So erstellen wir unseren neuen Spark-Kontext. Wir nennen es als C. Es ist so eingerichtet, dass jeder Kern auf
unserem lokalen Rechner verwendet wird und wir rufen den App-Namen oder Ratings Zähler. Wir laden aus den Daten ML dash 100 K Verzeichnis ru dot Datendatei, die jede Zeile jeder einzelnen Bewertung in diesem Datensatz enthält. Das ist das Fleisch von allem hier. Dies ist, wo wir die Map-Funktion auf den Zeilen
RDD aufrufen und diese Funktion anwenden, die aufteilt und jede Zeile in ihre einzelnen Felder basierend auf
dem Tab-Trennzeichen und extrahiert das dritte Feld. Wieder beginnen wir mit 0 zu zählen. Das ist zufällig der tatsächliche Ratingwert selbst. Das wird in eine neue RDD namens Ratings geworfen, die jede einzelne Bewertung enthält. Wir rufen dann die Aktionszählung um einen Wert an für Spark an und geben uns eine Antwort und finden den optimalen Weg, es zu bekommen. Sobald das ausgeführt wird, haben wir hier
eine Ergebnisstruktur, die gerade in unserem Treiberskript lebt. Also haben wir unsere Daten nicht mehr auf dem Cluster. Wir haben das wieder zu einigen Ergebnissen innerhalb des Skripts zusammengebrochen. Und jetzt können wir die resultierende Jakobsmuschel-Datenstruktur nehmen,
die in eine Sequenz umgewandelt wird, die nach seinem tatsächlichen zweiten Feld dort sortiert ist, was der tatsächliche Bewertungswert ist. Und dann wenden Sie die Drucklinie auf jedes sortierte Ergebnis an, um die endgültige Antwort auszudrucken. Und lassen Sie es noch einmal laufen, nur zum Spaß. Also wieder, wir können einfach auf 3D-Scanner klicken und mit der rechten Maustaste und laufen. Aber da wir es schon einmal gemacht haben, wird
es auch hier oben in einer Abkürzung sein, wir können einfach den Play-Button drücken und es wieder tun. Und da ist es wieder. So cool. In Ordnung, also haben wir über den Code gesprochen und wie er funktioniert, und Sie haben eine grobe Vorstellung davon, wie Sie RDDs verwenden und üben können. Wieder, wir werden später über Datensätze sprechen, sehr bald, keine Sorge, wir kommen dorthin. Aber zuerst reden wir über mehr darüber, was
unter der Haube passiert ist , als wir all das in unserem Cluster liefen.
10. Spark Internus: Was ist eigentlich unter der Haube passiert, als das alles lief? Lassen Sie uns darüber in ein wenig tiefer reden. Als unser Treiberskript zu dieser Aktion kam, der Befehl count by value und wurde
der Befehl count by value undder
Ausführungsplan aus den RDDs erstellt, die wir definiert haben. Also ist es irgendwie herauszufinden, was ich tun muss, um tatsächlich diese endgültige Antwort zu bekommen. In diesem Fall sieht es so aus, oder? Also beginnen wir mit dieser Textdatei, den Rohdaten aus unserer RDD. Und wir werden eine Mapping-Operation aufrufen, die parallel über
mehrere Prozesse oder mehrere Computer angewendet werden kann , sogar um die Bewertungen zu extrahieren, die wir dort wollen. Und dann schließlich werden wir eine Zählung nach Wert Aktion durchführen, um sie alle hinzuzufügen. Also der Ausführungsplan, es wird sagen, hey, ich kann all das erste Mapping-Zeug komplett parallel machen. Aber diese Aktion wird Sie diese Notizen erfordern, die miteinander
in irgendeiner Weise sprechen und eine Art von Kommunikation und Coli, ihre Ergebnisse. Was passiert, ist, dass der Job in
Phasen aufgeschlüsselt wird , je nachdem, wann Daten neu organisiert werden müssen. So dass parallele Mapping alle eine Phase sein kann , die keine Art von Reorganisation der Daten selbst erfordert. Aber die Zählung nach Wert mischt die Dinge ein wenig herum, oder? Das muss also eine eigene separate Phase im Prozess sein. Und dann wird jede Phase in
Aufgaben aufgeteilt , die über den Cluster verteilt werden können. Vielleicht diese violetten Pfeile verarbeiten
diese violetten PfeileTeile der Daten und das geht an einen Executoren. Executor, vielleicht gehen die grünen zu einem anderen Executor und der blaue geht zu einem dritten Executor, oder? Es denkt also darüber nach, wie ich diese Daten
effektiv verteilen und diese Anzahl nach Wertbetrieb, na ja, das ist nicht leicht parallelisierbar. So wird das dort zu einer anderen Strategie. Und schließlich werden die Aufgaben in
Ihrem gesamten Cluster geplant und ausgeführt, und Sie erhalten Ihre Antwort. Also unter der Haube, Das ist, was passiert ist, um tatsächlich
unsere endgültige Antwort zu bekommen , wie viele von jedem Rating-Typ in unserem Datensatz existierten. Es sind nicht so harte Kerle, aber unter der Haube passiert das irgendwie.
11. Schlüssel/Wert RDDs und die Durchschnittspreise: So sahen wir einige sehr einfache RED diese in Verwendung mit unseren Bewertungen Gegenbeispiel zuvor. Aber es gibt auch eine spezielle Art von RDD, genannt den Schlüsselwert RDD. Und mit diesen RDDs
gibt es einige zusätzliche Operationen, die Sie ausführen können, die nützlich sein können. Und wir werden uns das mit einem Beispiel mit unseren Freunden nach Alter Skript hier ansehen. Was wir am Ende des Tages hier
oder am Ende dieser Lektion versuchen werden,
ist herauszufinden, wie man die durchschnittliche Anzahl der Freunde nach Alter berechnet. Also beginnen wir mit einem Datensatz, der eine Reihe von einzelnen Personen,
ihre Namen, ihr Alter
und wie viele Freunde sie sich vorgestellt haben, dass wir das irgendwo von einem sozialen Netzwerk bekommen haben, richtig? In diesem Fall werden wir unsere Daten in Schlüsselwertpaare strukturieren. Rdds kann diese Dinger halten. In unserem Fall. In diesem Fall wird der Schlüssel das Alter sein und der Wert wird die Anzahl der Freunde sein. Weil wir die Dinge nach dem Alter suchen, schreiben, Dinge
konsolidieren und sie um dieses Alter reduzieren wollen . Also statt nur eine Liste von Altersgruppen oder Liste der Anzahl von Freunden und eine RDD. Wir können dies in einer strukturierteren Weise speichern, wo jeder Rover RDD besteht aus einem Tupel eines bestimmten Alters, einer Anzahl von Freunden für eine Person, dem Alter und der Anzahl der Freunde für eine andere Person,
et cetera, et cetera, et cetera. Also haben wir jetzt diese Schlüsselwertpaare in jeder Zeile unserer RDD. Wie erstellen Sie diese syntaktisch? Es ist wirklich nichts Besonderes in Scala. Alles, was Sie tun müssen, ist, Paare Ihrer Daten in die RDD mit Tupeln zuzuordnen. Also zum Beispiel, wenn ich nur eine RDD nehmen wollte, die eine Sache darin hatte, und ein Schlüsselwertpaar dieses Dings als Schlüssel
erstellen wollte und die Zahl 1 der Wert ist. Ich könnte einfach eine Kartenoperation aufrufen, die sagt, nimm die Zeile, der
gesamte Text ist x und transformiere das in das Tupel x Komma eins. Und das wird zu einem Schlüsselwertpaar, bei dem der Schlüssel x ist und der Wert eins ist. Das ist alles, was es dazu gibt. Sie haben jetzt einen Schlüsselwert, RDD, und Sie sind nicht darauf beschränkt, eine Sache zu haben, und der Schlüssel ist eine Sache und der Wert entweder könnten Sie Tupel oder andere Arten von Objekten als Werte haben. Also anstelle eines könnte
ich ein anderes Tupel darin eingebettet haben. Also kann ich einen Doppelpunkt haben, das Meer drucken , weißt
du, etwas Komma etwas anderes. Schließen Sie Klammern, wenn ich auch wollte. Sie können also nicht komplexere Datentypen als Teil Ihres Wertes
eingebettet haben , um das manchmal nützlich zu sein. Sobald Sie also diese Schlüsselwertpaare in Ihren RDDs haben, kann
Spark einige besondere Dinge mit ihnen machen. Es gibt einige neue Funktionen, die Ihnen zur Verfügung stehen. Einer wird durch den Schlüssel reduziert, und das ist nützlich, um alle Werte für den gleichen Schlüssel irgendwie zusammen zu kombinieren. Also haben Sie im Grunde eine Funktion bereitgestellt, die definiert, wie
kombiniere ich alle Werte für einen bestimmten Schlüssel? In diesem Fall übergeben wir diese kleine Funktion, die x,
y, flippiger Pfeil x plus y sagt . Das bedeutet
also, dass
ich, um eine Art von Werten in diesen Werten zu kombinieren, den Additionsoperator verwenden werde, um sie miteinander zu kombinieren. Und das ist ein bisschen verwirrend, was hier unter der Haube passiert. Es könnte also eine laufende Summe behalten, da es jeden Wert für einen eindeutigen Schlüssel unter der Haube
durchläuft . Also könnte x unsere aktuelle laufende Gesamtsumme darstellen. Und warum repräsentiere ich den neuen
Wert , den es aus einer neuen Zeile sieht und füge ihn hinzu. Was hier wichtig ist, ist der Operator auf der rechten Seite hier. In diesem Fall sagen wir explizit, wir wollen alles in allen Werten
für diese RDD addieren und uns eine Antwort für jeden eindeutigen Schlüssel geben. Was ist die Summe? Alle Werte, die mit diesem Schlüssel verknüpft sind, sind sinnvoll. Wenn dies nicht der Fall ist, haben wir ein Beispiel, das mehr Sinn macht, wenn Sie es in Aktion sehen. Wir können auch sagen, Gruppe für Schlüssel. Das wird Ihnen einfach eine Gruppe aller Werte für einen bestimmten beliebigen Schlüssel zurückgeben. Nicht unbedingt reduzieren die Dinge, aber es ermöglicht Ihnen nur, Ihre Daten besser zu organisieren und vielleicht auf eine andere Operation zu übergeben . Später. Wir können auch nach Schlüssel sortieren. Wenn Sie also Schlüsselwertpaare haben, können
Sie diese Sortierung innerhalb Ihres Clusters durchführen. Denken Sie daran, in unserem vorherigen Beispiel für den Ratingzähler, wir haben unsere Ergebnisse tatsächlich wieder auf der Scala-Ebene innerhalb unseres Treiberskripts erhalten und dort sortiert. Das ist wirklich nicht die skalierbarste Art, Dinge zu tun, oder? Es wäre vorzuziehen, wenn wir auf dem Cluster sortieren könnten. Und wenn wir stattdessen ein Schlüssel-Wert-Paar hätten, hätten wir das tun können. Außerdem haben wir Schlüssel und Werte, so dass wir alle Schlüssel extrahieren oder alle Werte aus einem Schlüssel-Wert-Paar extrahieren können. Wenn Sie in die andere Richtung zurückgehen und eine RDD nur der Schlüssel oder
eine RDD nur der Werte erstellen müssen, mit denen Sie sie aus einem Schlüssel-Wert-Paar wieder trennen können. Außerdem ist es möglich, SQL-Stil Joins zu tun, wenn Sie zwei Schlüssel-Wert-RDDs haben und wir werden später ein Beispiel dafür haben. Ich meine, das kommt in den Bereich, in dem Sie sich
fragen könnten , warum Sie RDDs verwenden, wenn Sie SQL-Operationen ausführen. Also werde ich nur bemerken, dass du es schaffst. Aber in der Praxis, offensichtlich werden Sie wahrscheinlich Datasets verwenden sind DataFrame sind
die Spark SQL-API, um diese Arten von Operationen in modernen Funken durchzuführen. Außerdem, wenn Sie eine Art Mapping-Operation für einen Schlüsselwert
RDD ausführen müssen und Sie nur den Wertteil transformieren. Ein kleiner Trick besteht darin, MapValues oder FlatMap-Werte zu verwenden. Auf diese Weise können Sie Ihre Transformation nur auf
den Wertteil anwenden , der effizienter sein wird, als
herauszufinden , wie Sie den Schlüssel zur Seite halten und nur den Wertteil beeinflussen können. Es ist also eine, sowohl eine effizientere in einer einfacheren Weise,
eine Mapping-Operation nur auf die Werte eines Schlüsselwerts RDD anzuwenden . Also denken Sie daran. Also lasst uns ein bisschen mehr in unser Beispiel eintauchen. Also wieder, was wir versuchen zu tun, ist herauszufinden die durchschnittliche Anzahl von Freunden für ein bestimmtes Alter, angesichts eines kleinen gefälschten Datensatzes hier. Stellen Sie sich vor, wir haben ein soziales Netzwerk, in dem wir eine Menge Leute haben, die in unserem sozialen Netzwerk sind. Und für jede Person kennen
wir ihr Alter seit Jahren, und wir wissen, wie viele Freunde sie in unserem sozialen Netzwerk haben. So könnte zum Beispiel jede Zeile so aussehen. Eine Art Benutzer-ID gefolgt von ihrem Namen, gefolgt von ihrem Alter, gefolgt von der Anzahl von Freunden. So ist Will 33 Jahre alt und hat 385 Freunde. John Luke ist 33 Jahre alt und hat zwei Freunde. Er war 55 und hat 221 Freunde und so weiter und so weiter. Das erste, was wir tun müssen, ist, die
Eingabedaten abzubilden und sie in eine Art Struktur aufzuteilen. Und hier definieren wir eine Parsezeilenfunktion, die
jede einzelne Zeile dieser RDD einnimmt und sie basierend auf dem Komma aufteilt. Trennzeichen, extrahiert das H-Feld und ruft im Alter, extrahiert das Feld des Num Freundes und nennt es num friends. Und dann geben wir ein Tupel zurück, ein Schlüssel-Wert-Paar von Altersgruppen. Also ist das Alter in diesem Fall der Schlüssel und der Wert ist taub Freunde. Und wir sehen hier in der nächsten Zeile, dass wir die Zeilen RDD
durch Laden der gefälschten Freunde dot-dot-dot CSVs Rohdaten erstellen . Wir rufen dann map mit dieser Parse-Line-Funktion auf, um
diese Rohdaten in eine neue RDD namens RDD zu transformieren , die Schlüssel-Wert-Paare enthält. Die Ausgabe hier von RDD wird also unten so aussehen. Ein Schlüssel-Wert-Paare. Zum Beispiel ist
33 der Schlüssel, das Jahr, das Alter und 385 die Anzahl von Frankreich. Also wieder, Alterszahl von Frankreich. Der Schlüssel ist Alter, die Werte Anzahl von Frankreich und andere 33 jährige hatte zwei Freunde. Ein 55-Jähriger hatte 221 Freunde, so weiter und so weiter. Und Sie können sehen, dass wir hier doppelte Werte für Schlüssel haben können, oder? Schlüssel müssen also in diesem Zusammenhang nicht eindeutig sein, nicht bis wir die Dinge reduzieren. Als nächstes wollen wir jedoch beginnen, diese Daten zu reduzieren. Um den Durchschnitt zu berechnen, müssen
wir zwei Dinge haben, oder? Wir müssen die Gesamtsumme davon haben, wie viele Freunde
für ein bestimmtes Alter existierten und wie viele Menschen es repräsentieren. Um den Durchschnitt zu berechnen, werden
wir die Gesamtzahl der Freunde essen, die Alter haben, und die Anzahl der Menschen, die für dieses Alter existierten. Und durch die Teilung dieser beiden wird der Durchschnitt erhalten, den wir am Ende des Tages wollten. Der nächste Schritt besteht also darin, diese Summen zu berechnen. Und das ist es, was hier los ist. Jetzt werden Sie oft in Spark-Treiberskripten sehen, dass
Menschen Dinge in
einer großen langen Linie zusammenmischen . So können Sie sich genauso gut daran gewöhnen. Lass uns jetzt darüber reden,
was hier drin passiert, oder? Also lassen Sie uns das in seine zwei Komponenten aufteilen. Wir beginnen mit RDD-Punkt-Map-Werten X bis X Komma eins. Also, was dies tun wird, ist, jeden Wert zu nehmen und diesen in sein eigenes Tupel dieses Wertes und dann eins zu
verwandeln. Nun ist die Methode zu diesem Wahnsinn aber, dass ich, indem einen mit jedem einzelnen Wert dort
verknüpfe, icheinen mit jedem einzelnen Wert dort
verknüpfe,all diese einzelnen Einträge addieren und
die Gesamtsumme davon erhalten kann , wie viele für dieses Alter existierten. Ok. Also, dass man nur sagt, dass ich jede einzelne Zeile als eine zähle, und ich werde das später zusammenfassen, um dort eine Gesamtsumme, ein bisschen ein Trick zu bekommen. Nach diesem Punkt, wenn wir diese MapValues-Operation ausführen, wird das unser RDD aussehen. So zum Beispiel 33,
35, was uns sagte, dass ein 33-Jähriger zukünftige 95 hatte. Frankreich wird sich in dasselbe verwandeln. Der Schlüssel ist immer noch 33, aber der neue Wert ist ein Tupel von 385 Komma eins. Und wir tun dies für jede einzelne Zeile in dieser RDD. Und als nächstes sagen wir Punkt ReduceByKey. Also haben wir das Ergebnis davon nicht explizit einer neuen namens RDD zugewiesen. Wir wollten gerade diese neue RDD direkt in eine andere Operation hier übergeben, in diesem Fall die ReduceByKey-Aktion. Diese Operation hier wird also beide Elemente dieses Tupels im Wert addieren, richtig? Was hier passiert ist, ist, dass wir hier
22 Eingänge von unserer RDD nehmen , die wir reduzieren, nennen sie x und y. Wir werden das erste Element beider Tupel und das zweite Element
beider Tupel zusammenfügen , und fügen Sie sie alle für jeden eindeutigen Schlüssel hinzu. Ok? Also sieh mal, wo wir damit hingehen. An diesem Punkt, was wir hier haben, ist für alle 33-Jährigen da draußen, wir haben diese Daten auf die Gesamtsumme aller Freunde reduziert, die die 33-Jährigen hatten und die Gesamtzahl der 33-Jährigen existierte. Also denken Sie eine Minute darüber nach. Es ist ein bisschen knifflig. Unsere Strategie hier war, hierher zurückzugehen, okay, wir haben alles auf diese Tupel von 433 Jährigen für jeden Einzelnen abgebildet, wir hatten ein Tupel der Anzahl der Freunde, die eine Person in der Nummer eins hatte. Und dieser Trick hier ist, dass, indem Sie dies tun und sie alle zusammen hinzufügen. Wenn wir das erste Element dieses Tupels zusammenfügen, wie viele Freunde
jeder 33 Jährige hatte, erhalten
wir die Gesamtsumme, wie viele Freunde 33 Jährige hatten. Und dann, indem wir es zusammenfügen, all diese, bekommen
wir eine Zählung, wie viele 33-Jährige es gab. Und das gibt uns die beiden Dinge, die wir brauchen, um den Durchschnitt zu berechnen, den wir wollten. Und das machen wir im nächsten Schritt. Wir sagen Kartenwerte und alles, was wir tun, ist, jeden Wert,
jedes Tupel, das wir am Ende hatten, zudurchlaufen jedes Tupel, das wir am Ende hatten, zu und sie durch einander zu teilen, um
die endgültige durchschnittliche Zahl zu erhalten , die wir im Endergebnis wollen. Ok? An diesem Punkt können wir nur sammeln und die Ergebnisse anzeigen. Also werden wir sagen, sammeln, um zurück, dass reduzierte gemittelte Werte. Und wir werden sie sortieren und Drucklinie
aufrufen und jede, um das Endergebnis anzuzeigen. Also lassen Sie uns weitermachen und es tatsächlich in unserer nächsten Vorlesung ausführen.
12. [Aktivität] Durchlauf der Durchschnittliche Freunde von Alter: Alles klar, Lassen Sie uns in den Code eintauchen und sehen, wie alles in Aktion
funktioniert, und wir werden es ausführen und sehen, ob es funktioniert. Das ist also all das Zeug, über das wir in den vorherigen Folien gesprochen haben. In Ordnung, also lasst uns den Code hier eine Zeile nach dem anderen durchlaufen. Also beginnen wir damit, zu deklarieren, welches Paket wir
in dieser Art einer Standardsache für jedes Scala-Skript leben . Und dann importieren wir die Pakete, auf die wir angewiesen sind. In unserem Fall sind wir ein bisschen faul und importieren einfach alles aus Apache Spark und auch aus log für J. Wir definieren dann die Objekte, in denen unser Skript lebt. Wir werden es Freunde nach Alter nennen, was mit dem Namen der Datei übereinstimmen sollte. Ich werde die Flurstückslinienfunktion vorerst überspringen und zur Hauptfunktion gehen , weil dort
die Ausführung beginnt, damit wir
sagen, dass wir es wieder tun, die Log-Level auf Fehler setzen
, so dass wir keine Reihe von Protokollen Spam über erhalten Warnungen, gegen die wir nichts tun können. Es wird ein paar geben, die durchgerutscht sind, bevor das hingerichtet wird, aber wir werden die meisten davon fangen, zumindest. Als nächstes erstellen wir unseren Spark-Kontext, wieder eingerichtet, um auf unserer lokalen Maschine mit jedem CPU-Kern laufen zu lassen. Und wir geben unserer Anwendung Namen Freunde nach Alter. Das nächste, was wir tun, ist Laden Sie unsere Rohdaten und es gibt einen gefälschten Freunde Bindestrich, keine Heterodox CSV-Datei. Das ist eine Version der Daten, die keine Kopfzeile hat, die Sie durcheinander bringen kann. Also seien Sie sich dessen bewusst. Und wir werden das in die RDD
einer Zeile laden , wo jede Zeile eine Zeile dieser Daten darstellt. Also, wie sehen diese Daten aus? Werfen wir einen kurzen Blick darauf, nur um uns daran zu erinnern. Es sieht also so aus. Denken Sie daran, dass die erste Spalte die Benutzer-ID ist, die zweite ist der Name und das Alter und die Anzahl der Freunde und alles, was wir für unser Problem
interessieren, sind die letzten beiden Spalten, richtig? mir egal, ob die Benutzer-ID ist, es ist mir egal, ob ihr Name war. Ich versuche nur, die durchschnittliche Anzahl von Freunden für jeden
gegebenen ein herauszufinden , damit ich die ersten beiden Spalten wegwerfen kann. Und das ist, was wir in der Parse-Line-Funktion hier tun. Also werden wir die Parse-Line-Funktion nehmen, das jeder dieser Eingabezeilen
zuordnen und eine neue RDD namens RDD erhalten. Mal sehen, was Flurstückslinie tut. Also, was das tut, ist, jede Zeile durch
ein Komma aufzuteilen , weil es sich um eine durch Komma getrennte Wertedatei handelt. Und wir extrahieren die Felder 2 und 3. Das sind die letzten beiden Spalten in unseren Daten. Es wird sie Alter und NAM-Freunde nennen und ein Tupel von Alter und NAM-Freunde zurückgeben. Und wieder wird dieses Tupel unser Schlüssel-Wert-Paar in unserer RDD, RDD. Jetzt wird das Alter unser Schlüssel sein und NAM-Freunde werden unser Wert für jede einzelne Person sein, die wir in unserem Datensatz haben. Da sind wir also. Und jetzt haben wir diese wirklich komplizierte Linie, über die wir viel Zeit mit dem Reden verbracht haben.
13. RDDs und das the filtern: Lassen Sie uns als nächstes über Filtern sprechen. Deine RDDs. Filterung ist eine sehr einfache Operation, mit der Sie nur Daten aus Ihren RDDs bereinigen können und
Sie werden feststellen, dass das gleiche Konzept auch auf die anderen APIs bei Spark-Angeboten übertragen wird. Wir werden dies mit ein paar Beispielen anhand von Wetterdaten veranschaulichen. Dies sind reale Daten von zwei verschiedenen Wetterstationen in Europa. Und was wir tun werden, ist Filterung zu verwenden, um diese Daten zu säubern, bevor wir sie für die minimale und maximale Temperatur innerhalb eines bestimmten Jahres an diesen Wetterstationen
aufgezeichnet werden. Die Verwendung eines Filters ist ziemlich einfach. Alles, was Sie tun, ist eine Funktion bereitzustellen, die einen booleschen Wert zurückgibt. Und wenn dieser boolesche Wert true zurückgibt, behalten wir diese Zeile, andernfalls entfernen wir sie aus der RDD. Wenn wir zum Beispiel Einträge herausfiltern wollten, die nicht T min als zweites Element im Tupel der Daten haben, könnten
wir sagen, geparste Zeilen Punktfilter,
vorausgesetzt, dass Parse-Zeilen die RDD ist, die diese Tupel enthält. Und die Übergabe an die Funktion, in der jede Datenzeile x aufgerufen wird und wir prüfen, ob das zweite Element von x gleich dem Team in ist. Wenn es so ist, behalten wir es. Wenn dies nicht der Fall ist, dann entfernen wir es in der resultierenden Min versucht RDD. Min Terme enthalten also die gefilterten Ergebnisse der geparsten Zeilen. Hier ist ein Beispiel für die Rohdaten, die in unseren Quelldaten für dieses Beispiel enthalten sind. Wir werden also versuchen, hier
die Mindesttemperatur innerhalb eines Jahres für eine bestimmte Wetterstation zu finden . Und diese erste Kennung, die erste Spalte mit Informationen in unseren Eingabedaten ist die Stationskennung. Das stellt also nur dar, wo diese Temperaturmessung genommen wurde. Danach ist das tatsächliche Jahr und das Datum, an dem diese Messung durchgeführt wurde. Sie können also sehen, dass dies ein ziemlich alter Datensatz ist, der bis ins Jahr 1800 zurückgeht. Und Sie können sehen, dass wir viele verschiedene Arten von Daten in diesem Datensatz aufgezeichnet haben. Tmax zeigt die maximale Temperatur an, die an diesem Tag an dieser Wetterstation aufgezeichnet wurde. T min ist die
aufgezeichnete Mindesttemperatur und Genauigkeit ist die Menge des Niederschlags aufgezeichnet. Und das Format dieser Temperaturdaten ist etwas seltsam. Es ist Grad Celsius multipliziert mit 10. Also negativ 75 ist eigentlich negativ 7,5 Grad Celsius müssen damit umgehen, wie wir Daten analysieren und importieren. Hier ist, wie dieser Code aussieht, der diese Daten analysiert. Also für jede Zeile, die wir erhalten, die wir für diese 8800 Punkt CSV-Textdatei einlesen, werden
wir diese Parse-Line-Funktion verwenden, um tatsächlich Sinn daraus zu machen. Sie können sehen, dass es zuerst basierend auf dem Komma Trennzeichen aufteilt. Es extrahiert die Station-ID, die das erste Feld ist, und den Eingabetyp, bei dem es sich um ein zweites Feld handelt. Und schließlich die Temperaturnummer selbst. Und Sie können hier sehen, dass wir beginnen, indem wir
das mit 0,1 multiplizieren , um zwei Grad Celsius zu erhalten. Und dann wandeln wir das in Grad Fahrenheit um, weil ich in den Vereinigten Staaten lebe, was meines Erachtens eines der letzten Länder ist, das immer noch die Fahrenheit Skala nutzt. Aber wie auch immer, wenn Sie diesen Teil abhalten und ihn in Celsius halten wollen, in Ordnung von mir, werde
ich niemandem sagen, was wir zurückgeben, ist ein Tupel, das die Station-ID enthält, den Eintragstyp, der in diesem Fall Team in T max oder Niederschlag und die Temperatur, die mit diesem Eintrag verbunden ist. Als nächstes müssen wir die Informationen herausfiltern, die wir nicht wollen. Wir interessieren uns also nur für T-Min-Einträge, denn die Frage, die ich beantworte, ist, was die Mindesttemperatur
während des ganzen Jahres für jede Wetterstation war . Ich kümmere mich also nicht um die maximalen Temperaturen, die aufgezeichnet wurden. Der Niederschlag ist mir egal. Ich werde all diese Informationen rauswerfen. Indem Sie also nur Parse-Linien Punktfilter sagen, prüfen Sie, ob dieses zweite Feld gleich T min ist. Ich kann alle Daten wegwerfen, wo das nicht stimmt, oder? Also, wenn x Punkt Unterstrich zwei gleich
Team ist und ich werde diese Zeile und die resultierenden Min Temps RDD beibehalten. Sonst werde ich es herausfiltern. Das wird also all die anderen Sachen außer Team in Einträgen loswerden. Also, das ist Filter in Aktion. Danach können wir die
Temperatur-Schlüsselwertpaare der Station ID erstellen , da wir einige Tricks mit Schlüsselwert-RDDs machen möchten, indem wir auf unserer vorherigen Lektion zurückgreifen. Also werden wir diese Mindesttemperatur einem neuen Tupel
zuordnen , das nur aus der Stations-ID und der Temperatur besteht. Wir brauchen das Team nicht mehr im Eingabetypfeld, weil wir wissen, dass alles ein Team ist, also ist das nur verschwendeter Platz, richtig? Also werden wir das in nur eine Station ID und
die Temperatur der minimalen Temperatur für jede einzelne Zeile umwandeln , die qualifiziert ist. Und wir werden diese neue resultierende RDD-Station Temps nennen. Und dann definieren Sie das Minimum. Alles, was wir tun können, ist ReduceByKey zu sagen. Also wieder verwenden wir hier eine Art Schlüssel-Wert-Trick und machen eine Reduce-Operation darauf. Also im Grunde wollen wir
jede laufende Summe nehmen , die wir für die aktuelle Mindesttemperatur haben, vergleichen Sie das mit einer neuen Zeile. Das wird also x und y sein,
und wir werden die minimalen Operationsmänner ausführen, um nur den minimalen Wert zu erhalten. Also im Grunde geht es immer wieder
durch alle minimalen Temperaturen für einen bestimmten Schlüssel, wobei jeder Schlüssel eine Wetterstation darstellt. Und es wird halten, versuchen, die minimale Temperatur im Auge zu behalten. Also wird es auf die erste Reihe schauen. Schauen Sie sich die zweite Zeile ist eine sekundäre oder kleiner als die erste Zeile. Okay, toll, das ist das neue Minimum. Ist der dritte Nachwuchs groß, weniger als die zweite Reihe? Nein. Ok. Der zweite bleibt immer noch das Minimum, so dass er immer den Überblick über
die empfangene Mindesttemperatur hält . Und was wir am Ende mit ist eine viel kleinere RDD genannt eine Minute Versuche von Station, die nur alle einzigartigen Schlüssel enthält. In diesem Fall nur zwei verschiedene Wetterstationen-IDs und die Minimaltemperatur-Szene für jede Station. An diesem Punkt müssen wir nur die Ergebnisse sammeln. Also nennen wir die Sammelaktion zu gehen und erzwingen RDDs zu gehen und tatsächlich etwas auf unserem Cluster zu tun. Und dann werden wir jedes Ergebnis durchlaufen, nachdem wir
sie sortiert haben und die Stations-ID und die Temperatur extrahieren, wir werden die Temperatur mit einem Ausdruckformat formatieren, wie wir bereits in der Einführung zu Scala Lektionen über gesprochen haben. Und drucken Sie es erneut mit dem Substitutionsformat aus, über das wir auch gesprochen haben. Also etwas von diesem
String-Formatierungsmaterial, das wir früher im Kurs gelernt haben, hier in die Tat umzusetzen. Also werden wir nur die Stations-ID,
die Wörter Minimaltemperatur-Doppelpunkt
und dann die formatierte Temperatur mit
zwei Dezimalstellen der Genauigkeit nach dem Dezimalpunkt ausdrucken die Wörter Minimaltemperatur-Doppelpunkt und dann die formatierte Temperatur mit . Also lass uns gehen und es tun und sehen, ob es funktioniert.
14. [Aktivität] Durchführen des Minimum und die Änderung für das Maximum: Wenn Sie also das Min temperatur-Skript in Intelligenz hier öffnen, sollten
Sie dieses Skript hier sehen. Lasst uns Zeile für Zeile durchlaufen. Und da du vielleicht neu in der Skalierung bist, werde
ich ein bisschen mehr Zeit damit verbringen, hier die Syntax zu durchlaufen. Es ist ein ziemlich einfaches Beispiel, also sollte nicht zu lange dauern. Also lassen Sie uns diesen Importblock hier öffnen nur um sicherzustellen, dass wir alles mit dem sehen, was wir verwenden. Wie immer beginnen wir damit, das Paket zu deklarieren, in dem wir uns befinden. Calm Dotson Hunde Software dot Spark, und wir importieren all das Zeug, auf das wir angewiesen sind. Was wir alles aus Apache Spark importieren, von log für J. Und auch brauchen wir Scala dot Math.min, um diese Min-Funktion zu verwenden, um die minimalen Temperaturen zu verfolgen, die wir treffen. Also deklarieren wir ihn bei Temperaturen. Objekt, um den Namen unserer Datei hier übereinzustimmen. Und wieder werde ich die Parse-Line-Funktion vorerst überspringen und
direkt zur Hauptfunktion gehen , weil dort die Ausführung beginnt. Das erste, was wir tun, ist die Log-Level auf Fehler zu setzen, um
all diese Warnmeldungen loszuwerden , die unsere Ergebnisse überladen. Wir erstellen dann einen Spark-Kontext. Und hier sagen wir, der Master wird lokaler Star sein,
sagen, dass wir es oder lokale Maschine mit
allen verfügbaren CPU-Kernen ausführen und der App-Name ist Min-Temperaturen. Lassen Sie uns jetzt ein wenig über die Syntax hier sprechen. So Master gleich und App-Name gleich oder nur kleine Notationen, die intelligent für uns für Anzeigezwecke eingefügt. Im Allgemeinen müssen Sie nicht wirklich
sagen, dass Master gleich Ihrem App-Namen ist, den Sie einfach die Parameter
übergeben können und es wird es an die erwarteten Parameter für diese Funktion
ausrichten . Wir wissen also, dass ein SparkContext-Konstruktor mit dem Master und dann dem App-Namen für die ersten beiden Parameter
beginnt. Aber wenn Sie sie expliziter benennen möchten, können
Sie es auch auf diese Weise tun. Das ist die Syntax ist auch gültig und das kann zu lesbareren Code führen. Wenn ich das also außerhalb von Intel J betrachtete, weiß
ich vielleicht nicht wirklich, was Min-Temperaturen bedeutet oder lokaler Stern bedeutet, indem ich diese Parameternamen explizit einfüge, es macht den Code ein wenig lesbarer und einfacher zu verstehen . Wir sahen das Gleiche hier oben auf Logger, bekommen Lagername gleich Org. Wir mussten nicht sagen, Name gleich 0, wir können einfach 4D sagen, aber das macht es klarer, dass der Name dieses Parameters, den wir setzen, Name ist, und das sagt uns, was es ist. Nachdem wir den Logger für den Organisationsnamen erhalten
haben, setzen wir den Punktfehler der Stufe 2 ein, um zu sagen, dass wir nur Fehlermeldungen und keine Warnungen oder Informationsmeldungen
wollen. weitermachen, laden wir zuerst unsere Eingabedaten auf. Also sagen wir Val Lines. Also machen wir einen unveränderlichen Wert hier genannt Zeilen , die auf die Textdatei von Datenschrägstrich 1800 Punkt CSV gesetzt ist. Das wird also jede Zeile dieses CSV-Formats nehmen und einfach den Rohtext jeder Zeile in die RDD der Zeile einfügen. Werfen wir einen kurzen Blick darauf, wie diese Daten aussehen. Dies ist also eine Visualisierung dieser CSV-Datei in Microsoft Excel. Sie können sehen, dass die erste Spalte die Stations-ID ist, und es gibt nur ein paar von ihnen hier, gefolgt von dem Datum, das im Jahr, Monat Datumsformat ist. Also 8800, 1. Januar. Und diese ganze Datei enthält alle Daten für das Jahr 1800er. Also müssen wir nichts Besonderes tun, um zu sagen. Wir wollen nur Daten aus dem Jahr 1800. Das ist alles, was wir haben. Diese dritte Spalte gibt an, welche Art von Messung in dieser Datenzeile aufgezeichnet wird. So maximale Temperatur, Mindesttemperatur oder Niederschlag. Und der nächste ist der Wert, der mit dieser Messung verbunden ist. Und wieder, es ist irgendwie ein seltsames Format. Also denke ich, das technische Wort ist wie Deci Centi Grad oder so. Ich weiß es nicht. Grundsätzlich ist es auf Grad Celsius mal 10 eingestellt. Also wieder, negativ 75 bedeutet nur negativ 7,5 Grad Celsius. Die restlichen Spalten werden für unsere Zwecke ungenutzt, so können wir einfach so tun, als ob sie nicht existieren. Also, das ist, was wir in unsere Zeilen RDD lesen. Wir verwenden dann unsere Parse-Lines-Funktion und wenden diese an, um
jede Zeile der Zeilen RDD zuzuordnen , um eine neue RDD namens geparste Zeilen zu erzeugen. Lassen Sie uns also einen Blick darauf werfen, was Parse-Zeile tut. Also wieder, wir werden ein wenig verlangsamen hier auf dem Format. Denken Sie daran, die Art und Weise, wie wir Funktionen in Scala deklarieren, ist, dass wir mit def,
dem Namen der Funktion und allen Parametern beginnen . Und denken Sie daran, dass wir Parameter ein wenig rückwärts von anderen Sprachen deklarieren. Also beginnen wir mit dem Namen Doppelpunkt und dann dem Typ. Viele andere Sprachen oder geben Sie den Namen in Scala, sein Name geben Sie dann ein. Der Parameter heißt also line und es wird erwartet, dass er von einer Zeichenfolge ist. Und dann haben wir einen Doppelpunkt, und das wird es von der Funktion ausgegeben. Also wieder, das ist rückwärts von allen anderen Sprachen. Viele Male setzen Sie den Rückgabetyp vor den Namen der Funktion in Scala, es ist danach. Also geh Figur. Was wir zurückgeben, ist ein Tupel, das eine Zeichenfolge,
eine Zeichenfolge und eine Gleitkommazahl enthält . Und wir setzen diese Funktion gleich dem folgenden Codeblock. Zuerst beginnen wir mit dem Wert eines Feldes, der diese Zeile mit dem Komma Trennzeichen aufteilen wird. Und wieder wird der Regex-Name dieses Parameters hier für unsere Bequemlichkeit eingefügt. Wir extrahieren dann das erste Feld. Wir fangen an, von 0 hier zu zählen. Also Fields 0 extrahiert das erste Mitglied davon und ruft es Station-ID. Extrahieren Sie das dritte Feld und rufen Sie diesen Eingabetyp und das vierte Feld auf, und wir nennen diese Temperatur nach der Umwandlung in Fahrenheit. Also, was ist hier los? Wir nehmen dieses vierte Feld, dem es sich um eine Zeichenfolge handelt, mit der wir anfangen müssen, weil wir das aus einer String-Daten aufteilen. Also müssen wir das explizit in
eine Gleitkommazahl konvertieren , bevor wir numerische Operationen darauf ausführen können. Also sagen wir, zu schweben, um das zu einer Gleitkommazahl zu machen, wir werden das mit 0,1 multiplizieren, weil, wie Sie sich erinnern,
alles wurde mit zehn multipliziert und die Quelldaten. Also an dieser Stelle haben wir tatsächlich Grad Celsius. Wir machen dann die Umwandlung in Grad Fahrenheit indem wir mit neun Fünfteln multiplizieren und 32 hinzufügen. Wenn du in Celsius bleiben wolltest, ist das cool. Nimm einfach den Teil raus und du wirst in Celsius sein. Was wir zurückgeben, ist das letzte, was in dieser Funktion ist, also müssen wir es nicht explizit zurückgeben. Und nur das Letzte, was da drin ist, wird implizit von dieser Funktion zurückgegeben. Und das wird ein neues Tupel sein, das aus der Station-ID besteht, die wiederum eine Zeichenfolge ist, der Eingabetyp, der wiederum eine Zeichenfolge ist. Und das kann Team und T sein, max oder priciple. Und die Temperatur, die wir als Gleitkommawert berechnet haben. Das ist also, was die, jede einzelne Zeile
unserer resultierenden geparsten Zeilen RDD an dieser Stelle enthalten wird. Als nächstes wollen wir alles außer dem Team in Einträgen herausfiltern, denn alles, was wir zu berechnen
versuchen, ist die Mindesttemperatur für das ganze Jahr für jede Station, richtig? So können wir alle diese TMax-Einträge auswerfen. Wir können all diese Niederschlagseinträge wegwerfen. Und das machen wir mit dieser Linie hier. Also sagen wir Filter, was der ganze Sinn dieser Übung ist, indem wir hier diese kleine Inline-Funktion übergeben. Also werden wir jede eingehende Zeile der Flurstückslinien aufrufen, die bereits dx sind. Wir werden dann das zweite Feld aus x nehmen und daran erinnern, dass der Eingabetyp sein wird. Wenn man sich hier oben anschaut, ist
das zweite Feld der Eingabetyp. Und wir werden überprüfen, ob dieser Eintragstyp t Min entspricht. Wenn dies true zurückgibt, dann wird diese Zeile an die Min temps übergeben, die RDD sonst Filter haben, die Eintrag aus und geht nicht in MiniTab. Die resultierenden Mintues RDD
enthält also nur die Zeilen, die t min und diesem zweiten Feld entsprechen. Als nächstes werden wir das Team in
diesem Eingabetypfeld wegwerfen , weil wir es nicht mehr brauchen. Wir wissen, dass jede Reihe und Mindesttemperatur an dieser Stelle. So können wir dies wieder zuordnen, um nur das erste Feld zu extrahieren, das die Stations-ID und das dritte Feld sein wird. Und nur um sicher zu sein, werden wir explizit sagen, dass das eine Gleitkommazahl ist. Also unsere neue Station, temps RDD wird nur Stations-IDs enthalten, die eine Zeichenfolge und eine Temperatur ist, die eine Gleitkommazahl in Fahrenheit ist. Jetzt können wir ReduceByKey sagen, indem wir
nur den Minimalwert verfolgen, den wir treffen, wenn wir durch jede Zeilenstation versuchen. Wenn wir also durch Station Versuchungen gehen, werden
wir weiterhin das aktuelle Minimum mit
jeder eingehenden Zeile vergleichen und das Minimum zwischen diesen beiden zurückgeben, den Effekt
haben,
den niedrigsten aufgezeichneten Überblick zu behalten Temperatur für jeden Schlüssel, da wir nach Schlüssel reduzieren. Denken Sie daran, dass jeder Schlüssel eine Stations-ID ist. Was Männer Zelte von Station endet mit ist eine viel kleinere RDD, die nur eine Zeile für jeden eindeutigen Schlüssel enthält, der diesen Schlüsselnamen und die minimale Temperatur mit dieser Wetterstation-ID verknüpft. Wir sammeln dann die Ergebnisse zurück zu unserem Skript und setzen das in das Ergebnisobjekt. Wir sortieren es dann mit Ergebnissen dot sortiert und durchlaufen es mit dieser for-Schleife. Also für das Ergebnis, Ergebnisse sortiert, das durchläuft jede Zeile von Ergebnissen sortiert jeden Eintrag, und extrahiert jeden als Ergebnis. Für jeden extrahieren wir das erste Feld dieses Tupels namens Station. Das zweite Feld ist Temperatur. Wir formatieren diese Temperatur. Das F bedeutet, dass wir ein Druck-f-Format verwenden. Und das Prozent 0,2 F bedeutet, dass wir
zwei Dezimalstellen der Genauigkeit auf der rechten Seite des Dezimalkommas wollen . Und wir stecken ein F am Ende, um anzuzeigen, dass es Fahrenheit ist. Dann müssen wir es nur mit Drucklinie ausdrucken. Und wir werden mit
Dollarzeichenstation für den Stationswert, die Mindesttemperaturersetzen Dollarzeichenstation für den Stationswert, die Mindesttemperatur und dann eine Temp formatieren, das Dollarzeichen wieder anzeigt, dass wir in diesem unveränderlichen Wert namens formatierte Temp. Also lassen Sie es uns laufen und sehen, was passiert. Klicken Sie mit der rechten Maustaste auf Min. Temperaturen und Betrieb min. Ab geht es. Und da haben wir es. So können wir sehen, dass für die beiden Wetterstationen, die minimale Temperaturen mit ihnen verbunden waren, die erste Easy Ease etwas oder anderes genannt wurde. Und die dort aufgezeichnete Mindesttemperatur war 7,7 Grad Fahrenheit. Und für ITE, was auch immer es ist, war
die Mindesttemperatur 5,36 Grad Fahrenheit. So scheint es sehr cool geklappt zu haben. Wenn du deine Hände schmutzig machen willst, ermutige
ich dich immer, hier mitzumachen. Hier ist eine wirklich schnelle Herausforderung für Sie. Was wäre, wenn Sie
die maximale Temperatur für jede Wetterstation im Auge behalten wollten , anstatt die Mindesttemperatur. Nun, die, die Veränderungen, die damit verbunden sind, sollten ziemlich einfach sein. Wenn Sie ein bisschen eine Herausforderung wollen, drücken Sie jetzt Pause und gehen Sie und versuchen Sie es selbst. Prüfen Sie, ob Sie dieses Skript ändern können, um
die maximalen Temperaturen anstelle der Mindesttemperaturen auszudrucken . Und es pausiert, wenn du das machen willst. Wenn nicht, zeige ich dir, wie ich es gemacht habe. Es ist also ziemlich einfach, aber du musst dich ändern, oder? Zunächst einmal möchten Sie den Namen des Objekts und der Datei auf maximale Temperaturen für
die Konsistenz ändern , das Parsen der Daten wird gleich sein, oder? Das wird sich nicht ändern. Das Datenformat hat sich bei uns nicht geändert. Aber was wir extrahieren, wird anders sein, oder? Min. Temperaturen wollen sich ändern. Das Geschehen der maximalen Temperatur ist wahrscheinlich das, was wir tun werden, obwohl, filtern Sie alles mit TMax statt t min. Das wird uns alles geben, außer den T max Einträgen. Und dann hier unten, wenn wir unsere Reduktions- oder ReduceByKey-Operation machen, wollen
wir sie nur in ein Maximum ändern. Und das sollte so ziemlich geändert werden, wie wir die Ergebnisse anzeigen, um zu sagen, dass es eine maximale Temperatur ist. Ich denke, wir müssen auch skelett math.max importieren, oder? So ziemlich unkompliziert, aber es ist gut, Ihre Hände zu bekommen und irgendwie Vertrauen in
Änderungen an Scala-Code und Spark-Code vorzunehmen und zu sehen, dass Sie es tun können,
Es geht mehr um Ihr Vertrauen in irgendetwas. Wenn Sie sehen möchten, wie ich es gemacht habe, doppelklicken Sie
einfach auf das Maximaltemperatur-Skript hier. Und es tut alles, was ich gerade gesagt habe. Also importieren wir scala dot math.max. Ich habe den Namen geändert, den Dateinamen ändern. Wir nennen es jetzt Maximaltemperaturen. Wir filtern nach TMax und reduzieren basierend auf der maximalen Funktion und drucken die maximale Temperatur aus. Das ist so ziemlich es. Lass uns weitermachen und das laufen und sehen, was es tut. Und da hast du, es. Es stellte sich heraus, dass sie beide dasselbe haben. Das ist irgendwie neugierig, nicht wahr? Also für beide Stationen war
die maximale Temperatur 90 Punkt 104 Grad Fahrenheit. Und ich vermute, das entspricht einer netten Runde Nummer und Anreiznote, die für beide Stationen einfach gleich ist. Also nicht zu weit voneinander entfernt. Es ist also keine allzu große Überraschung. Und dort haben Sie es Filter in Aktion. Und auch ein weiteres Beispiel für das Schreiben eines einfachen Apache Spark-Skripts mit RDDs. Sie werden feststellen, dass dies nicht viel anders ist. Wir werden über verschiedene APIs sprechen, aber wieder, sie sind bald.
15. [Aktivität] Word mit Flatmap(): So haben wir einige Beispiele für die Verwendung der Kartenoperation in Spark bisher gesehen, Lassen Sie uns über FlatMap sprechen, die ein wenig anders ist. Und wir haben ein einfaches Beispiel, um es zu veranschaulichen, wo wir die Anzahl jedes Wortes in einem Buch aufzählen, um zu zeigen, wie es funktioniert. Lassen Sie uns also überprüfen, was die Karte tut. Also zum Beispiel, wenn wir eine Eingabetextdatei hatten, die das schnelle Lesen in
einer Zeile enthielt und Fox sprang auf eine andere Zeile und über die Faulen auf einer anderen Zeile und braune Hunde in der letzten Zeile. Wir könnten das in eine RDD lesen, die Zeilen genannt wird, wo jede Textzeile einer Zeile dieser RDD entspricht. Und dann in diesem Fall rufen
wir Map auf den Zeilen RDD und
übergeben ihm eine Funktion, um jede Zeile in Großbuchstaben zu konvertieren. Also, was wir bekommen, ist eine neue Wut Caps RDD, die nur
jede einzelne Zeile oder jede einzelne Zeile anstatt dieser Eingabe RDD Großschreibung . Also die Sache, die hier zu beachten ist, ist, dass es eine Eins-zu-Eins-Beziehung zwischen der Eingangs-RDD und der Ausgabe-RDD gibt. Und wenn Sie map aufrufen, nimmt map jede Eingabezeile und wandelt sie in irgendeiner Weise in eine und nur eine Ausgabezeile um. Also begannen wir mit vier Zeilen und der RDD der Linie, und wir enden mit vier Zeilen und die Ausgabe Wut Caps RDD, Karte hat immer diese Eins-zu-Eins-Beziehung. Eine Reihe kommt rein, eine Reihe erlischt. Flatmap entfernt diese Einschränkung jedoch. Mit FlatMap können Sie also eine beliebige Anzahl von Zeilen für eine Eingabezeile zurückgeben, es könnte 0 sein, es könnte 20 sein, es könnte 200 sein, alles, was Sie wollen. Also in diesem anderen Beispiel hier beginnen
wir mit der gleichen Eingabe. Rdd werden Zeilen genannt, aber jetzt nennen wir FlatMap. Und wir übergeben als Funktion dort, um jede Zeile aufzunehmen, es x zu
nennen und dann basierend auf dem Leerzeichen aufzuteilen. Dies hat also den Effekt, jede Zeile in ihre einzelnen Wörter aufzuteilen. Und weil wir FlatMap aufrufen, landet
jedes einzelne Wort in seiner eigenen neuen Zeile in den resultierenden Wörtern RDD. Also mit FlatMap hier begannen
wir mit vier Zeilen, aber wir landeten mit vielen weiteren Zeilen, die in der Ausgabe RDD Wörter, wo wir eine Zeile für jedes Wort haben, im Gegensatz zu einer Zeile für jede Zeile. Und wieder kann FlatMap eine beliebige Anzahl von Zeilen ausgeben, die Sie wollen, einschließlich 0. Um dies in Aktion zu sehen, lassen Sie uns ein kleines einfaches Codebeispiel machen, bei dem wir zählen, wie oft jedes Wort in einem ganzen Buch vorkommt. Und ich versuche nicht, dir dieses Buch zu verkaufen, obwohl ich es geschrieben habe,
es hat nichts mit Apache Spark zu tun, aber es ist ein Buch, in dem ich die Rechte habe, damit ich es als Beispiel verwenden
kann, ohne Tantiemen zu zahlen. Also lasst uns voran gehen und eintauchen und sehen, wie oft jedes einzelne Wort in meinem Buch erscheint. So haben wir hier ein sehr einfaches Skript, um die Verwendung von FlatMap zu veranschaulichen. Es nennt man Wortzahlen. Also gehen Sie voran und öffnen Sie Word Count und intelligent, wenn Sie entlang wirklich einfaches Skript folgen
möchten . Und das wird oft als eine Art HelloWorld-Beispiel für Spark-Programme verwendet. Wir beginnen wie immer unser Paket zu deklarieren,
importieren, was wir für Abhängigkeiten benötigen, und deklarieren das Objekt, in dem wir leben. Unsere Hauptfunktion beginnt damit, dass die Log-Level immer ist und einen neuen SparkContext deklariert, der auf unserem lokalen PC läuft. Jetzt kommen wir in das Fleisch davon. Also nennen wir es SparkContext Textdatei mit einem Pfad zum gesamten Inhalt des Textes dieses gesamten Buches, das in der Datenschrägstrich Book dot txt Datei lebt. Und wir nennen diese resultierende RDD unsere Eingabe, wobei jede Zeile dieser Eingabe RDD entspricht einer Textzeile aus dem Buch. Und jetzt, wie wir in den Folien gesehen
haben, nennen wir FlatMap auf dieser Aufteilung jede Zeile durch das Leerzeichen, was uns mehr oder weniger die einzelnen Wörter innerhalb dieses Buches gibt. So hat FlatMap jetzt ein neues Wort RDD generiert, wobei jede Zeile des Wortes RDD
ein Wort im Buch ist und es kann Wiederholungsworte sein. Es ist jedes einzelne Wort, auch wenn es mehr als einmal vorkommt, wird eine Zeile in dieser RDD und Sequenz sein. Und jetzt werden wir die Zählung nach Wert Aktion verwenden, um
zu zählen , wie oft jedes einzelne Wort in den Wörtern RDD erscheint. Das ist also eine einzeilige Art zu tun, was
sonst eine ziemlich komplizierte Operation wäre , richtig? Und das Schöne an Spark ist, dass es tatsächlich das über einen ganzen Cluster
parallelisieren kann , wenn Sie möchten, oder in unserem Fall, jeden Kern unserer CPU. Alles, was wir dann tun, ist durch
jedes Ergebnis in diesem Wort-Zählobjekt zu iterieren , das wir von Spark zurückbekommen haben. Und wir nennen Drucklinie auf jedem dieser Ergebnisse, um jedes Ergebnis auf seiner eigenen Linie auszudrucken. Also lasst uns weitermachen und es laufen und sehen, was passiert. Wir werden mit der rechten Maustaste auf Wortzahl zählen, sagen wir ausführen WordCount, aus geht es. Und obwohl dies ein ganzes Buch ist, sollte
es kurze Arbeit daraus machen. Da haben wir es. Interessant. Wenn Sie also durch diese blättern, können
Sie sehen, wie oft jedes Wort in meinem Buch erscheint. Das Wort Bargeld erscheint 18 Mal, nur 77 Mal. Selbständige, nur 10 Mal. Irgendwie überraschend, weil es ein Buch über Selbständigkeit ist. Aber es gibt auch hier eine Art einzigartiger Wörter, wie die Idee nur einmal auftaucht. Dropversand wird nur einmal angezeigt. So cooles Zeug. So an unserem hat es funktioniert. Das ist ein Beispiel für Flatmap in Aktion. Aber wenn Sie sich diese Ergebnisse ansehen, können
Sie sehen, dass es hier einige Probleme gibt, an denen wir vielleicht arbeiten möchten. Lassen Sie uns das also in nachfolgenden Vorträgen hier untersuchen, zum Beispiel, je nach
Großbuchstabe, könnte ich diese als verschiedene Worte behandeln. Wurde das Wort Produkte wirklich nur einmal enthalten? Wir werden alles, was wirklich bedeutet, ist, dass Produkte nur einmal mit einem großen P erschienen sind, vielleicht am Anfang eines Satzes oder so, richtig? Es gibt also Möglichkeiten, diese Ergebnisse zu verbessern, um interessanter zu sein. Und es ist auch wie seltsame Dinge wie offene Strich beendet ein oder zwei Wort. Was ist mit Satzzeichen? Sollte ich diese Fragezeichen und Kommas und Perioden abziehen, richtig? Also Besitzer Komma erscheinen zwei Mal, aber das ist nicht wirklich reden über das Wort Besitzer. Es gibt also etwas Raum für Verbesserungen und wie wir diese Daten analysieren. Also lasst uns das erkunden.
16. [Aktivität] Die the mit regulären Ausdrücken verbessern: Okay, um in unserer vorherigen Lektion zu überprüfen, haben
wir ein einfaches Beispiel für die Verwendung von FlatMap gemacht, um
zu zählen , wie oft jedes Wort in meinem Buch erscheint. Und wir analysieren diese Daten sehr naiv, indem sie basierend auf Leerzeichen
aufteilen, um einzelne Wörter zu bekommen,
die zuerst erröten würden, würden Sie denken, dass sie funktionieren würden. Aber wie Sie in den Ergebnissen hier sehen können, tut es das nicht. Wir bekommen am Ende Satzzeichen da drin. So zum Beispiel, Zitat, y zählt als ein individuelles eindeutiges Wort. Auch hier spielt die Kapitalisierung eine Rolle. Also würde Kapital Y als ein anderes Wort gezählt werden als Kleinbuchstaben y. Wir haben Dinge wie Kommas, Satzzeichen und Großschreibung, die unsere Ergebnisse beeinflussen. Also lasst uns das reparieren. Also lassen Sie uns aus WordCount Punkt Scala schließen und stattdessen Word Count besser öffnen. Und hier werden wir stattdessen einen regulären Ausdruck verwenden, um bessere Ergebnisse zu erzielen. Clv, nichts wirklich anderes ist hier,
dass anstatt diese Funktion zu haben, die sich basierend auf einem Leerzeichen aufteilt, wenn wir die Eingabedaten aufteilen, stattdessen einen regulären Ausdruck verwenden werden. Also in diesem Fall sagen wir x dot split und setzen den regulären Ausdruck auf dieses reguläre Ausdrucksformat, Backslash, Backslash Großbuchstaben W plus. Und im regulären Ausdrucksland bedeutet
das nur, dass ich die Dinge aufbrechen möchte, basierend auf ganzen Wörtern. Das Großbuchstabe W bedeutet Wort. Reguläre Ausdrücke wissen also, was ein Wort ist. Es wird alle Satzzeichen und
all diese Sonderzeichen herausfiltern und uns einfach
mit Wörtern überlassen , die die tatsächlichen Zeichen enthalten. Das muss also all die Probleme loswerden, die Satzzeichen unsere Ergebnisse vermasselt. Aber wir haben immer noch das Problem der Kapitalisierung, oder? Also Kapital R Und denken Sie daran, wird ein anderes Wort als Kleinbuchstaben r. Und denken Sie daran, auch nach dem Ausziehen jeder Interpunktion, die dort existieren könnte. Also, um dieses Problem zu kümmern, werden
wir darüber hinaus eine Karte unsere Ergebnisse auf Kleinbuchstaben. So sehen wir hier beginnen wir mit der flachen Zuordnung unserer Eingabedaten in einzelne Wörter. Aber in diesem Fall teilen wir Wörter mit
regulären Ausdrücken auf, im Gegensatz zu Leerzeichen, was robuster ist. Und dann machen wir eine reguläre Karte, um
jedes einzelne Wort zu nehmen und das auf einer Eins-zu-Eins-Basis seiner Kleinbuchstaben abzuspielen. Indem wir also alles auf Kleinbuchstaben normalisieren, können
wir sicher sein, dass wir alle Wörter gleich zählen, unabhängig von der Großschreibung. Und dann gehen wir los und zählen nach Wert auf die resultierenden Kleinbuchstaben Wörter RDD und drucken diese Ergebnisse. Mal sehen, ob uns das etwas Besseres gibt. Lasst uns mit der rechten Maustaste auf Wortzahl besser klicken und das ausführen. Und okay, das sieht ein bisschen besser aus, oder? Also, das ist cool. Also, jetzt haben wir hier keine seltsame Satzzeichen vor sich. Alles ist Kleinbuchstaben, also erhalten wir Ergebnisse, die hoffentlich ein wenig mehr Sinn machen. So erscheint zum Beispiel das Wort Werbung 41 Mal in dem Buch, das glaubwürdig erscheint. Religiös nur ein Cache 19 mal. Lassen Sie uns hier
jedoch nach einem wirklich populären Wort suchen, das 1292 mal erscheint. Also nicht zu überraschend,
das ist ein sehr häufiges Wort. Cool. Also scheint es so geklappt zu haben, als ob ich denke, wir bekommen hier gültige Wörter. Alles scheint normalisiert zu sein. Wir werden nicht vermasselt. Ich Satzzeichen, so Mission erfüllt, aber das ist noch nicht schrecklich nützlich, um es zu benutzen, richtig? Ich muss hier nach gemeinsamen Worten angeln gehen. Das sollte ich nicht tun müssen. Wäre es nicht besser, wenn ich diese Ergebnisse sortieren könnte, wie oft jedes Wort erscheint. Es wird also nützlicher sein. Ich kann sehr leicht die häufigsten Wörter und die am wenigsten gebräuchlichen Wörter in dem Buch finden. Und das könnte mir sogar einen Einblick darüber geben, worum es im Buch geht. Oder vielleicht Worte, die ich übermäßig verwende oder so etwas, das ist gut. Ich habe tatsächlich eine praktische Anwendung für Schriftsteller. Lassen Sie uns also weitermachen und dieses Skript in unserem nächsten Vortrag noch besser machen und diese Ergebnisse
sortieren, damit wir mehr Bedeutung daraus gewinnen können.
17. [Aktivität] die Word: Okay, in unserer vorherigen Lektion
haben wir unser Beispiel
für die Wortzählung so verfeinert dass es ein bisschen intelligenter ist, Wörter zu identifizieren. So haben wir hier eine wirklich gute Ausgabe
der Zählungen jedes einzelnen Wortes in unserem gesamten Buch. Aber es ist nicht schrecklich nützlich, weil es nicht danach sortiert ist, wie oft jedes Wort vorkommt. Also muss ich angeln gehen, um herauszufinden was die häufigsten und am wenigsten gebräuchlichsten Wörter in meinem Buch sind. Das ist also nicht sehr hilfreich, oder? Also lasst uns das reparieren. Wir möchten die Ergebnisse nach der Häufigkeit jedes Wortes sortieren. Wir können schnell die am häufigsten verwendeten Wörter in meinem Buch sehen. In früheren Vorlesungen in diesem Kurs hätten
wir das getan, indem wir einfach die Endergebnisse sortieren, die wir von
Spark zurückbekommen haben , die in unser Treiberskript zurückgegeben wurden und sie einfach in Scala sortieren. Aber das ist nicht wirklich die Big Data-Art, Dinge zu tun, oder? Es wäre besser, wenn wir diese auf dem Cluster sortieren könnten, wenn wir
so viele Worte hätten , dass wir nicht wirklich alles auf einer Maschine verarbeiten könnten. Das müsstest du tun, oder? Ich meine, das ist ein verwirrtes Beispiel. ist unwahrscheinlich, dass Sie so viele Worte in einem Buch haben, aber Sie bekommen die Idee. Es wird vorzuziehen sein, diese Sortierung auf dem Cluster verteilt zu machen, wenn wir können. Also lass es uns so machen und sehen, wie das funktionieren könnte. Also lassen Sie uns das Wort zählen besser sortiertes Beispiel hier öffnen. Nur eine kleine Verfeinerung auf das vorherige Wort zählen besseres Skript hier, es ist ziemlich dasselbe, außer für den Namen des Skripts
den ganzen Weg bis zu diesem Punkt hier. Also haben wir unser Buch in eine Eingabe-RDD geladen. Wir teilen es mit FlatMap in Wörter auf. Also jetzt haben wir ein Wort RDD, das jedes Wort im Buch enthält, und dann ordnen wir das in Kleinbuchstaben zu, um diese Daten zu normalisieren. Also jetzt, vorher hätten wir Zählung nach Werten verwendet, oder? Wenn wir zu unserem früheren Beispiel hier zurückkehren, verwenden wir Anzahl nach Wert, um schnell die Anzahl der Male jedes Wort tritt in dieser RDD zu erhalten. Aber wir wollen es gleichzeitig sortieren. Also müssen wir es irgendwie auf die harte Art machen. Also lassen Sie uns aufschlüsseln, was in dieser Art komplizierter Linie hier vor sich geht. Also zuerst werden wir dieses Ergebnis auf x r1 abbilden. Nehmen Sie jede Zeile, jedes einzelne Wort und ordnen Sie das einem Tupel des Wortes und der Zahl 1 zu. Jetzt haben wir diesen Trick schon mal gesehen, oder? Also, was wir sagen, ist, dass jedes einzelne Tupel dieses Wort
hat und repräsentieren, dass es einmal in dieser Zeile aufgetreten ist. Und das ist ein kleiner Trick, den wir verwenden können, weil das uns
erlaubt, alles zusammenzufassen, richtig, und die Anzahl der Male, die jedes einzelne Wort auftritt, wenn wir eine Reduce-Operation durchführen. Und das ist es, was wir hier tun. Wir sagen, reduzieren Sie nach Schlüssel, addieren Sie all diese Summen. Also lasst uns das nochmal durchmachen. Wir verwandeln jedes Wort in ein Tupel des Wortes und die Nummer eins. Und weil dies ein Tupel mit zwei Dingen ist, die als Schlüsselwert betrachtet werden könnten, RDD, wobei der Schlüssel das Wort ist und der Wert die Nummer eins ist. Also, jetzt können wir ReduceByKey sagen, weil wir im Grunde
einen Schlüssel-Wert-RDD haben , der alle Werte summiert, okay? Also für jedes einzelne Wort werden
wir alle Werte zählen, was nur die Zahl 1 ist. Wenn wir also alle Zahlen für jedes Wortvorkommen addieren, erhalten wir eine Zählung davon, wie oft dieses Wort aufgetreten ist. Okay, das nächste, was wir tun wollen, ist es zu sortieren. Also an diesem Punkt hat die ReduceByKey-Operation uns mit einem Wort zählt
RDD verlassen , das Schlüssel-Wert-Paare enthält, wieder, wobei der Schlüssel das Wort ist und der Wert die Anzahl der Male, die das Wort auftritt. Jetzt Spark bietet eine Sortierung nach Schlüsselfunktion hier, die wir verwenden können, aber es wird nach dem Schlüssel und dem Wert, den wir nach der sortieren möchten, sortieren, wie oft jedes Wort auftritt. Also müssen wir das zuerst umdrehen. Das ist alles, was wir in dieser Kartenoperation tun. Wir nehmen die Wortzahl RDD und drehen es so , dass der Schlüsselwert RDD um Wert Schlüssel gedreht wird, wenn Sie so wollen. Und so nehmen wir die Eingabe-RDD, die Wortanzahl enthält, und drehen sie um, um Wort zu zählen, indem wir es in x dot t2 und x-dot eins transformieren. Das zweite Feld im ersten Feld. Sobald wir das haben, können
wir sortieren nach Schlüssel verwenden, um die Ergebnisse nach der Anzahl der Male jedes Wort eintritt zu sortieren. Also, mit mir hier, lasst uns es noch einmal schnell durchlaufen. All dies ist das Gleiche von vorher. Aber in diesem Fall werden wir unsere Kleinbuchstaben RDD nehmen, die jedes einzelne Wort in seiner eigenen Zeile hat. Wir werden das einem Schlüssel-Wert-Paar zuordnen, bei
dem der Schlüssel das Wort ist und der Wert die Nummer eins ist. Wir führen eine ReduceByKey-Operation, um zu addieren, wie oft jeder einzelne Schlüssel, jedes einzelne Wort auftritt. Und dann müssen wir das resultierende Schlüssel-Wert-Paar auf seinem Kopf drehen, so dass wir tatsächlich sortieren nach Schlüssel verwenden
können, um nach der Anzahl der Male jedes Wort zu sortieren. Dann gehen wir durch und drucken die Ergebnisse aus, wie wir es vorher getan haben. Und wir sollten etwas Nützlicheres bekommen. Also lasst uns weitermachen und es versuchen. Klicken Sie mit der rechten Maustaste auf die Wortzahl, besser sortiert und sagen, ausführen. Und da haben wir es. Und es ist in aufsteigender Reihenfolge sortiert. So werden die beliebtesten Wörter am Ende sein. Und das ist interessant. Also meine häufigsten Worte waren auch und Sie nicht in einem Brunnen, ich bin froh, dass ich die Worte, die Sie in Ihrem mehr als ich und ich verwendet. Das ist eine bessere Art zu schreiben. Sie möchte sich mit Ihrem Leser verbinden und nicht viel über sich selbst reden. Also werde ich das einen Sieg nennen. Aber ja, ein in der flachen Auftauchen ziemlich häufig. Und von all den üblichen Worten, die Sie erwarten würden, dort zu sehen, gibt es dh, ein Geschäft taucht viel auf. Wenn Sie also ins Licht drängen, können
die interessanteren Worte sagen, worum es im Buch geht, genau anhand der häufigsten Wörter, richtig? Also das erste Wort, das irgendwie eine Bedeutung hat, gibt es Geschäft, und es ist ein Blick über das Geschäft. Scrollen Sie Zeit nach oben. Wissen Sie, wir reden viel über Zeitmanagement wegen Produkt zu tun. Ok. Ja, wir haben viel darüber gesprochen, wie man wählt, welches Produkt zu verkaufen ist. Also ja, Sie können tatsächlich einige Einblicke darüber bekommen, worum es im Buch
geht , nur wenn Sie sich diese Daten jetzt ansehen. Und wenn wir zu den am wenigsten verbreiteten Wörtern scrollen, sollten
wir hier keine ziemlich obskuren Sachen bekommen. Schaum nur benutzte ich waren Telefon. Ich frage mich, woher das kommt. Swoot zitiert. Also, ja, interessante Sachen. So können Sie wirklich sagen, worum es im Buch geht, nur indem Sie sich diese Daten ansehen. Also haben wir irgendwie gerne die Entwicklung des Drehbuchs zu sehen. Und auf dem Weg, dieses Skript nützlicher zu machen, haben
wir nicht nur über die Verwendung von FlatMap gelernt, sondern auch, wie man reguläre Ausdrücke verwendet und wie man ReduceByKey
kreativ nutzt und nach Schlüssel sortiert, um die Ergebnisse zu erhalten wollen. Nun werden wir feststellen, dass dies bei der Verwendung von Datasets in SQL etwas
einfacher ist. Aber wir kommen dorthin. Wir wollen einfach nur mögen, beginnen mit den Grundlagen hier und den Grundlagen von Spark, die auf RDDs basieren. Und in Fällen, in denen Sie RDDs verwenden müssen, ist
es gut, diese Tricks zu kennen.
18. [Übung ] den Gesamtbetrag vom Kunden: Okay, ich denke, du hast genug über RDDs gelernt und an diesem Punkt
genug Scala-Code gesehen , um etwas alleine zu tun. Es ist also eine kleine Herausforderung, eine kleine praktische Aktivität. Ich werde Sie ein sehr einfaches Spark-Programm in
Scala erstellen lassen, das nur den Gesamtbetrag des
Geldes zählt, der von jeder einzelnen Kunden-ID
und einer kleinen gefälschten Datenbank mit E-Commerce-Daten bestelltwird Geldes zählt, der von jeder einzelnen Kunden-ID
und einer kleinen gefälschten Datenbank mit E-Commerce-Daten bestellt . Also werde ich Ihnen eine CSV-Datei zur Verfügung stellen, die Dinge in diesem Format enthält. Und dies stellt eine Kunden-ID und
auch eine Artikel-ID und den Betrag dar , der für diesen Artikel ausgegeben wurde. Also jede Zeile dieser gefälschten Daten stellt einige Transaktionen dar, einige Einkäufe bei einer fiktiven Person gemacht. Sie werden Code schreiben und die Gesamtsumme
ausgeben , wie viel von jeder eindeutigen Kunden-ID ausgegeben wurde. In diesem speziellen Beispiel können
Sie sehen, dass Benutzer-ID 44 etwas für 37,
19 und etwas anderes für 4064 gekauft hat. Die Gesamtsumme für unseren Benutzer 44 ist also 77, 83. Und das wollen wir für jeden einzelnen Kunden in unserer Datenbank tun. Also werde ich das für dich ein wenig buchstabieren, wenn du ein bisschen ängstlich darüber bist, nein,
nicht, spähe nicht, wenn du das alleine ausprobieren willst, aber eine allgemeine Anleitung für die Strategie, dies zu tun. Ich möchte beginnen, indem ich jede durch Komma getrennte Zeile in ihre eindeutigen Felder aufteile. Und wie gesagt, wird das Benutzer-ID,
Artikel-ID und ausgegebener Betrag sein . Anschließend ordnen Sie jede Zeile einem Schlüssel-Wert-Paar von Kunden-ID und Dollar-Betrag zu. Verwenden Sie den Vorgang ReduceByKey, um den Gesamtbetrag, der nach Kunden-ID ausgegeben wurde, zu addieren. Wenn Sie fertig sind, sammeln Sie die Ergebnisse und drucken Sie sie aus. Ziemlich unkompliziert. Und Sie sollten in der Lage sein, dies herauszufinden, indem die vorherigen Beispiele in diesem Kurs
studieren. Sie sind ziemlich ähnlich. Ein paar nützliche Code-Snippets, wenn Sie neu in Scala sind, die nützlich sein könnten, wenn Sie
ein kommagetrennte Feld in seine einzelnen Felderaufteilen möchten ein kommagetrennte Feld in seine einzelnen Felder Diese Zeile würde es für Sie tun, Val Felder gleich Zeilenpunktteilkomma. Und Sie müssen auch irgendwann sicherstellen, dass Sie Feld
0 eine Ganzzahl behandeln und sich als Gleitkommazahl fühlen. Also ist dieses kleine Code-Snippet wichtig, sich auch zu merken. Sie müssen diese explizit in
ihre tatsächliche numerische Darstellung umwandeln und nicht nur Strings wie sie aus dem Dateirock kommen. So viel Glück. Und bevor ich Sie
loslasse, werde ich Ihnen kurz zeigen, wo Sie die Daten dafür finden und wie Sie
ein neues Objekt in unseren Projekten erstellen können, damit Sie tatsächlich damit spielen und loslegen können. Also lass mich dir das sehr schnell zeigen und dann lasse ich dich los. Lassen Sie mich zunächst Ihre Aufmerksamkeit darauf lenken, wo die Daten für diese Übung leben. also in Ihrem Kursmaterialordner Gehen Siealso in Ihrem Kursmaterialordnerin Spark Scala Kurs und dann in den Datenordner. Und es ist die Kunden-Dash Orders Datei, die wir uns hier ansehen werden. Lass uns das aufmachen und sehen, wie es aussieht. Denken Sie nun daran, dass dies durch Kommas getrennte Werte sind. Obwohl Excel es als Tabellenkalkulation anzeigt, es wirklich einzelne Spalten, die durch Kommas getrennt sind, die wir hier lesen. Und diese Daten werden komplett zufällig generiert. Sie können sehen, dass es ziemlich viel davon gibt, zehntausend Datenzeilen hier, aber es ist alles gefälscht. Die erste Spalte stellt die Benutzer-ID dar, gefolgt von einer Artikel-ID und dem Betrag, der für diesen Artikel ausgegeben wurde. Jede Zeile stellt also einen einzigen Einkauf dar. Und ja, Sie könnten feststellen,
dass diese zweite Spalte nicht wirklich für das benötigt wird, was wir tun, oder? Wir brauchen nur den Betrag, der vom Kunden ausgegeben wird. Die Item-ID kommt nicht wirklich ins Spiel, also viel Zeit, also wird das Bereinigen Ihrer Daten ein großer Teil des Auftrags sein und das ist der Fall und diese kleine einfache Übung auch. Nun, um Sie damit zu beginnen, lassen Sie mich Ihnen zeigen, wie Sie tatsächlich über das Erstellen eines neuen Objekts in einem tele j gehen. Also klicke ich auf Calm dot sundown Software dot Spark und sagen New Scala Klasse und geben Sie ihm einen eindeutigen Namen. Kleben Sie Ihren Namen da rein, nur um sicher zu sein, um sicherzustellen, dass es einzigartig ist. So etwas wie die Gesamtsumme, die für mich ausgegeben wurde, auch immer dein Name für dich ist. Und doppelklicken Sie auf Objekt, weil wir ein Objekt und keine Klasse wollen. Alles klar, jetzt haben Sie hier den Boilerplate
eines neuen Objekts, es hat den richtigen Paketnamen, weil wir es an der richtigen Stelle setzen. Und Ihr Objekt ist alles eingerichtet. Und jetzt musst du nur etwas Code schreiben und ihn ausprobieren. Wenn Sie also bereit sind, das auszuprobieren, können
Sie einfach mit der rechten Maustaste auf diese Klasse klicken und Sie können sie erstellen. Und danach können Sie tatsächlich versuchen, es auszuführen und zu sehen, was passiert. Und ja, das war's. Also geh mal dran. Kein sehr schwieriges Beispiel, keine harte Übung mit irgendwelchen Mitteln, aber ich möchte, dass Sie Ihre Hände schmutzig machen und etwas Komfort beim Schreiben von Scala-Code bekommen. Wir werden später im Kurs natürlich einige schwierigere haben , also fangen wir einfach an. Also geh es mal versuchen. Und wenn Sie bereit sind, kommen Sie zurück zum nächsten Vortrag und ich zeige Ihnen meine Lösung, die hier in den Kursmaterialien ist. Du hättest es vielleicht schon gesehen, also widerstehen Sie der Versuchung, es anzuschauen. Probieren Sie das zuerst selbst aus.
19. [Übung ] Prüfe deine Ergebnisse und Sorge sie nach der Sort: Hast du deine Hausaufgaben gemacht? Ich hoffe es. Nun, wenn Sie Ihre Ergebnisse mit meinen vergleichen und Ihren Code mit meinem vergleichen möchten, habe ich meine Lösung auch in Ihre Kursmaterialien aufgenommen. Also hoffentlich hast du sie noch nicht ausgesucht. Öffnen Sie hier einfach die Summe, die von der Kundenklasse ausgegeben wurde. Und hier ist, wie ich es gemacht habe. Also lasst uns diesen Code hier durchlaufen. Beginnen Sie mit der Paketdeklaration, die Sie bereits haben
sollten, und importieren Sie, was wir brauchen. Wir brauchen alles von Spark und Protokoll für J. Ich hoffe, du wurdest nicht mit denen gestolpert. Und wir nannten unser Objekt hier insgesamt vom Kunden ausgegeben. Dies ist meine Lösungsdatei hier. Und lasst uns zur Hauptfunktion springen und dort anfangen. Also beginnen wir, indem wir unseren Log-Level auf Fehler setzen, wie wir es zuvor getan haben. Und wir haben einen neuen SparkContext eingerichtet. Und das Einzige, was daran einzigartig ist, ist, dass wir
einen App-Namen gesagt haben , der sich von den anderen Beispielen unterscheidet. In diesem Fall wird die Summe vom Kunden ausgegeben. Jetzt kommen wir in das Fleisch von allem. Wir laden unsere Textdatei, die die Kunden-Dash-Bestellungen Punkt CSV-Datei, die ich Sie früher geleitet. Und wir werden das einfach in eine RDD benannte Eingabe laden. Jetzt müssen wir diese Daten analysieren. Deshalb haben wir diesen Extrakt Kundenpreispaare geschrieben, die hier oben funktionieren. Natürlich hättest du es benennen können, was du willst. Es wird eine ganze Zeile von Komma Separated Values nehmen und wir werden einfach
diese String-Zeile aufrufen und ein Tupel einer Ganzzahl und eines Floats zurückgeben. Das sind also unsere Schlüsselwertpaare, die wir später haben, wobei der Schlüssel die Kunden-ID sein wird, die das erste Feld ist, und ein Gleitkommawert. Wir stellen den Betrag dar, der für einen Artikel für diesen Kunden in dieser Transaktion ausgegeben wurde. Wir beginnen, indem wir die Felder in dieser Zeile basierend auf dem Komma Zeichen mit Zeilenpunktsplit aufteilen. Und wir weisen das in den Feldern Wert zu. Und dann geben wir einfach das Tupel zurück, das das erste Feld enthält, das in eine Ganzzahl konvertiert wurde, und das dritte Feld, das in eine Gleitkommazahl umgewandelt wurde. Und denken Sie noch einmal daran, wir fangen an, in diesem speziellen Format von 0 zu zählen. Zu diesem Zeitpunkt haben wir unsere Eingabe in eine neue zugeordnete Eingabe-RDD abgebildet , die Tupel von Kunden-IDs und den ausgegebenen Betrag enthält. Und das ist eigentlich ein Schlüsselwertpaar, weil es ein Tupel von zwei Dingen ist, richtig? Also unser Schlüssel ist jetzt die Kunden-ID und unser Wert ist jetzt der Betrag, der in dieser Transaktion ausgegeben wird. Jetzt müssen wir das nur mit der ReduceByKey-Operation reduzieren. Und wir verwenden diese Syntax hier, um eine laufende Summe der Gesamtsumme zu halten die von jeder Kunden-ID ausgegeben wird. So reduzieren wir nach Schlüssel für jeden Kunden und addieren diese Werte, sobald sie hereinkommen. Dies nimmt also ein Paar von zwei Werten ein, die mit dem Schlüssel verbunden sind. Und wir werden sagen, wir wollen die addieren, weil wir die Gesamtsumme wollen. Und was wir zurückbekommen, ist die Gesamtsumme nach Kunden-RDD, die die Schlüssel, jeden eindeutigen Schlüssel, jede eindeutige Kunden-ID
und die Summe, die von jeder Kunden-ID ausgegeben wird. Wir können dann die Ergebnisse wieder sammeln. Das wird also unsere Aktion sein, die
die Ergebnisse zurückbekommt und sie an unser Skript zurückgibt,
an unser Treiberskript, das hier lokal ausgeführt wird. Und dann können wir einfach ForEach mit
der Druckzeilenfunktion aufrufen , um jede Zeile dieser Ergebnisse zu drucken. Also lassen Sie es uns laufen und sehen, ob es funktioniert. Ich werde mit der rechten Maustaste auf die vom Kunden ausgegebene Gesamtsumme klicken und sagen, die vom Kunden ausgegeben wurden. Ab geht es. Und da haben wir es. Sehr cool. Na gut, es scheint funktioniert zu haben. So zum Beispiel, Benutzer-ID 91 ausgegeben $4.642,26, und so weiter und so weiter. Benutzer 53 hat $4.495 ausgegeben. Sie sind alle ungefähr in der gleichen Nachbarschaft, weil dies
alles zufällig generierte Daten mit gleichmäßiger Zufallsverteilung waren . Aber das geht in meinen Data Science Kurs, nehme
ich an. Wie auch immer, es hat funktioniert. Also hoffentlich haben Sie eine ähnliche Ausgabe zu hören. Die Reihenfolge kann anders sein, das ist okay. Aber Sie wissen, Sie sollten in der Lage sein zu sehen, dass
Sie für eine bestimmte Benutzer-ID nach dieser Benutzer-ID suchen und hoffentlich die gleiche Nummer erhalten können. Also, wenn Sie nach Benutzer 89 suchen und sicherstellen, dass Sie 4851947, 95. Das könnte eine gute Idee sein. In Ordnung, also werde ich Sie jetzt weiter herausfordern, können
Sie das noch besser machen, wie wir es in unserem Wortzahl-Beispiel tun. Es wird viel nützlicher sein, wenn das sortiert wurde, oder? Wenn ich also mehr daran interessiert war, zu sehen, wer meine großen Spender sind, möchte
ich vielleicht diesen Datenspeicher nach ausgegebener Menge sortiert sehen. So konnte ich leicht sehen, wer die geringste Menge an Geld auf meiner Website ausgab und wer die meiste Menge an Geld auf meiner kleinen gefälschten E-Commerce-Website hier ausgab. Das ist also Ihre Herausforderung. Gehen Sie los und gehen Sie weiter und sehen Sie, ob Sie
die Ergebnisse nach Betrag sortieren können , die für ein zusätzliches Bonus-Team ausgegeben wurden.
Ich möchte sehen, ob Sie formatieren können, die tatsächlich
zwei Dezimalstellen der Genauigkeit dort nach dem Dollarzeichen dort haben . Also lassen Sie das eher wie echte Währung aussehen. Aber das sind sie, Ihre einzige echte Herausforderung im Moment ist es, diese Ergebnisse nach ausgegebener Menge zu sortieren. Und wieder, die Rücksicht auf das Wort zählen besser sortiertes Beispiel, das wir früher hatten. Dasselbe genaue Trick dort. Also versuche ich nicht, dich hier zu hart zu denken. Ich möchte nur, dass Sie hier etwas Übung machen und anwenden, was Sie in diesem Abschnitt gelernt haben. Wie gesagt, wir werden bald schwieriger werden. Also geh los und probiere das mal aus. Sehen Sie nun, ob Sie diese Ergebnisse nach ausgegebener Menge sortieren und ihm einen Schuss geben können. Und wir kommen in der nächsten Vorlesung zurück und Sie können
Ihre Ergebnisse in Ihrem Code mit meinem eigenen vergleichen .
20. Prüfe deine Ergebnisse und Implementierung von meiner Mine: Okay, ich hoffe, du hattest eine Chance, diese Ergebnisse
nach ausgegebener Menge zu sortieren , damit wir dort eine nützlichere Ausgabe erhalten können. Vergleichen wir Ihre Lösung nochmals mit meiner. Also, wenn Sie auf meine schauen möchten, können
Sie auf die Summe von Kunden ausgegeben klicken sortiert. Doppelklicken Sie darauf und sehen Sie, wie ich es gemacht habe. So ziemlich das gleiche Zeug wie der ursprüngliche Code, den wir in der vorherigen Vorlesung durchgemacht haben. Also werde ich nicht all das Zeug wiederholen, das sich nicht geändert hat. Alles, was wir geändert haben, war dieses Stück hier. Also an dieser Stelle hier haben wir den Gesamtbetrag nach Kunden. Daher haben wir unsere Daten reduziert, um Schlüsselwertpaare zu haben, bei denen individuelle Kunden-IDs mit
dem Betrag verknüpft sind , den dieser Kunde in der gesamten Datenbank ausgegeben hat. So wie wir es in dem Wort zählen sortierten Beispiel getan
haben, werden wir das auf den Kopf drehen und versuchen,
die Sortierung nach Schlüsseloperation zu nutzen , die Funken bietet. Auf diese Weise können wir die Sortierung dieses auf dem Cluster verteilen, wenn wir wollen. Um dies zu tun, müssen wir unsere Werte,
die Schlüssel und die Schlüssel zu den Werten machen , weil wir nach den Werten sortieren wollen, die Menge ausgegeben. Also erstellen wir diese umgedrehte RDD. Das ist nur die Zuordnung der Gesamtsumme durch den Kunden, um das Eingabe-Schlüssel-Wert-Paar x zu nehmen und das zweite Element zu nehmen und es zuerst zu machen. Und wir nehmen das erste Element und machen es an zweiter Stelle. Es dreht sich also nur um den Schlüssel und den Wert, um den neuen Schlüssel, den ausgegebenen Betrag und den neuen Wert, die Benutzer-ID zu machen. Wir sortieren dann nach Schlüssel, um das tatsächlich nach dem Betrag zu sortieren, den der erste Wert dort ausgegeben hat. Dann können wir die Ergebnisse wieder sammeln und jede Zeile ausdrucken. Also mal sehen, ob es funktioniert. Klicken Sie mit der rechten Maustaste auf die Gesamtsumme der Kunden sortiert und führen Sie sie Und wir sollten sehen, wer große Spender sind. Alles klar, sieht so aus, als hätte es funktioniert. Also haben wir in der ersten Spalte jetzt den Betrag ausgegeben. So können wir sehen, dass die meisten jemand mit
$6.375.45 ausgegeben hat und das war durch Benutzernummern 68. So können wir sehen, dass Benutzer 68 unser größter Spender war. Und wenn wir nach oben scrollen, können
wir unseren billigsten Spender sehen, wenn Sie so wollen. $3.309 ging an Benutzer 45. Und wieder, wenn Sie sich weiter bewegen möchten, könnten
Sie versuchen, diese Ausgabe ein wenig schöner zu formatieren. Ich werde das nicht mit Ihnen durchgehen,
aber wenn Sie das Gefühl haben, dass Sie noch mehr von einer Herausforderung wollen,
sehen Sie, ob Sie jede Zeile ausdrucken können, nur um ausführlicher zu sagen,
Benutzer-ID, was auch immer so viel Geld ausgegeben und formatieren Sie das Geld in real Geldformat, Dollarzeichen, ein ganzzahliger Punkt zwei Dezimalstellen, richtig? Und das wird nicht wirklich ein Funkenproblem sein. Es ist eher ein Scala-Problem. Aber wenn du noch weiter gehen willst, ist
das eine Möglichkeit, es zu tun. Aber ja, das reicht für den Moment. Also haben wir etwas über RDDs gelernt. Rdds sind die ursprüngliche API für Apache Spark gehen zurück zu Spark one, und sie haben immer noch ihren Platz für viele Arten von Problemen. Sie können die beste Leistung und die größte Flexibilität bieten und was Sie tun können. Aber es ist Zeit, weiterzumachen. Lassen Sie uns als nächstes über Datenrahmen und Datasets sprechen, denn das ist wirklich die modernere Art, Spark-Code zu machen. Und wir werden diese Beispiele erneut besuchen sie erneut mit Datensätzen im nächsten Abschnitt
durchführen.
21. Einführung in SparkSQL: In unserem nächsten Abschnitt stellen wir Spark SQL vor. Und mit den moderneren APIs von Spark DataFrame und Datasets in der Welt von Scala werden
wir uns mehr auf Datensätze konzentrieren, weil das noch effizienter ist. Dies wird also die modernere Schnittstelle für Spark sein. Und wir werden uns im Kurs darauf konzentrieren. Es ist eine Schicht auf der Oberseite von Spark Core. Aber wenn Sie sich Ihre Probleme in Bezug auf einen SQL-Befehl vorstellen können, dem die meisten Datenanalyseprobleme Spark SQL sein können und Datenrahmen und Datasets eine sehr effiziente und einfach zu bedienende
Lösung
bieten , um die gewünschten Antworten in einem gesamten Cluster. Also lasst uns eintauchen und sehen, wie es funktioniert. Also haben wir viel über die RDD-Schnittstelle in Spark gesprochen, die bisher die ursprüngliche Schnittstelle
war und Spark in allem darauf gebaut ist. Manchmal ist es immer noch nützlich, darauf zurückzugehen und wirklich auf ein niedriges Niveau
zu kommen , um die beste Optimierung für einfachere Probleme zu erzielen. Aber beginnend mit Spark zu, begannen
sie wirklich, stattdessen die Spark SQL-Schnittstelle und Apache Spark zu betonen. Und Spark SQL bringt Dinge wie Datenrahmen und Datasets auf die Tabelle. Lass uns darüber reden. Also kam DataFrame zuerst. Sie haben RDDs auf ein Datenrahmenobjekt erweitert. Und ein DataFrame ist ähnlich wie eine relationale Datenbank. Es enthält Zeilenobjekte, die eine Art strukturierter Informationen enthalten. Es hat ein Schema. Und so können wir Dinge effizienter speichern. Und weil wir ein Schema und diese Zeilen haben, können
wir es einfach wie eine SQL-Datenbank behandeln und tatsächliche SQL-Abfragen auf unseren DataFrames ausführen. Und weil es sehr wie eine tatsächliche Datenbank aussieht, können
Sie eine Menge Interoperabilität mit Datenbanken und datenbankbezogenen Dateiformaten haben. So können Sie JSON- oder HIV- oder Parkettformate lesen und schreiben. Und Sie können sogar direkt über eine JDBC- oder ODBC-Schnittstelle oder über Tableau kommunizieren. So können wir tatsächlich wie eine relationale Datenbank aussehen, obwohl es Apache Spark auf einem Cluster läuft. Ziemlich cool, richtig? Und weil es Dinge in Bezug auf SQL-Abfragen denken kann, bringt
das auch die gesamte Welt der Abfrageoptimierungstechnologien auf den Tisch, richtig? Über die üblichen gerichteten azyklischen Graph-Optimierungen hinaus, die mit Spark passieren können
wir auch Ihre tatsächlichen SQL-Abfragen betrachten, die Sie auf
einem DataFrame ausgeben möchten, und die gleichen Dinge tun, die
relationale Datenbank diese Abfrage zu optimieren. Wenn Sie also Dinge auf eine Art SQL-Art mit einem DataFrame ausführen, können
Sie manchmal sogar noch mehr Optimierung erzielen als mit einer RDD. Dann kamen wir mit Datensätzen und Datasets und DataFrame sind irgendwie das Gleiche. Technisch gesehen ist ein DataFrame nur ein Datensatz von Zeilenobjekten. Also eine Reihe ist nur eine Reihe von Sachen, richtig? Der wichtige Punkt hier ist, dass Sie auch
einen Datensatz haben können , der Hilfe und expliziten Typ und explizite oder
unexplizite Struktur umschließt , wo wir das eigentliche Schema im Voraus zur Kompilierzeit kennen. Zum Beispiel könnte ich einen Datensatz einer Personenfallklasse erstellen, die genau
definiert, was die Felder sind, die eine Person definieren und was diese Typen sind. Oder ich könnte ein Dataset erstellen, das
explizit besagt, dass ich eine Zeichenfolge und ein Double für jede Zeile möchte. Und dadurch wird es wissen, was diese Spalten von Anfang an sind. Im Gegensatz zu einem DataFrame, wo ich nur weiß, dass ich ein Dataset von Zeilen in dieser Zeile habe. Zeile könnte alles enthalten, bis ich es definiere, eine Datenmenge vorne, welche Typen befinden sich darin? Grund kennt das Dataset sein Schema zur Kompilierungszeit. Dies bedeutet, dass typbezogene Fehler beim Erstellen des Skripts erkannt
werden, nicht wenn Sie das Skript tatsächlich ausführen. Und das ist riesig, oder? Denn das Ausführen eines Skripts ist oft eine sehr teure Operation, wenn Sie es auf einem großen Cluster tun. Ein großer Vorteil von Datasets besteht also darin, dass Sie diese typbezogenen Fehler zur Kompilierungszeit
erkennen. Und das macht Ihre Entwicklung ein bisschen einfacher. Es führt auch zu einer besseren Optimierung. Das bedeutet, dass wir tatsächlich einige Optimierungen durchführen können, während wir kompilieren, anstatt zur Laufzeit. Und das ist auch ein großer Vorteil. Jetzt ist der Fang mit Datasets, dass Sie sie nur in kompilierten Sprachen verwenden
können, weil es all diese Dinge zur Kompilierungszeit macht . Das bedeutet Java oder Scala in der Welt von Spark. Dies ist also ein weiterer Grund, Scala anstelle von Python zu verwenden. Wenn Sie nicht können, obwohl Python viel beliebter zu sein scheint. Mit Python sind wir auf DataFrame beschränkt, da es diese Kompilierungszeitoptimierung nicht durchführen
kann. Also mit Scala, aber wir können die coolen Kinder sein. Wir können Datensätze verwenden und wir können wissen, was unsere Typen im Voraus sind. Python wird jedoch auf DataFrame beschränkt sein. Jetzt müssen Sie nicht alle mit Datasets eingehen, wenn Sie nicht möchten,
Sie können eine RDD tatsächlich in ein Dataset mit zwei ds konvertieren und Sie können auch umgekehrt gehen. So ist es möglich, das Beste aus beiden Welten zu haben und einige Verarbeitung mit RDDs durchzuführen und einige weitere Verarbeitung mit Datensätzen durchzuführen und alles zu tun, was sinnvoll ist. Wie wir sehen werden, sind RDDs für einige Operationen noch nützlicher. Aber für SQL-ähnliche Abfragen möchten Sie
natürlich Datasets verwenden. Datensätze sind wirklich die neue Schärfe. Der Trend in der Spark-Entwicklung besteht insgesamt darin, RDDs weniger und Datensätze mehr zu verwenden. Und ich bekomme tatsächlich einige Studenten, die irgendwie wütend werden, dass ich jetzt sogar RDDs abdecke, aber sie haben wirklich ihren Platz. Datensätze, die oft effizienter
sind, können sehr effizient serialisiert werden. Und wegen dieser Ausführungspläne,
die zur Kompilierzeit bestimmt wurden , kann
das oft viel effizienter sein, wie ich sagte, dann ermöglicht die Verwendung eines RDD-Datasets auch eine bessere Interoperabilität, nicht nur mit externen Dateiformaten und Datenbanken, sondern auch innerhalb der verschiedenen Komponenten von Spark selbst. Daher verwenden die Sparks Machine Learning Library und Spark Streaming Engine jetzt Datasets als primäre API anstelle von RDDs Wenn Sie
also Ihre Daten zwischen diesen verschiedenen Komponenten von Spark verschieben möchten, verwenden
Sie Datasets als diese Art von Art und Weise, es innerhalb von Scala zu tun. Und manchmal kann die Verwendung eines Datensatzes Ihre Entwicklung wirklich vereinfachen. Wenn Sie nur SQL-Operationen ausführen und darüber nachdenken können, was Sie mit Ihrer Analyse auf Spark in Bezug auf einen SQL-Befehl zu tun
versuchen, werden
Sie feststellen, dass es wirklich, wirklich, wirklich, sehr einfach ist, dies mit einem Dataset zu tun. Während es vielleicht viel schwieriger gewesen sein könnte, dies mit einer RDD zu tun. Wenn Sie jetzt Spark SQL verwenden, einschließlich Datasets innerhalb von Scala, gibt es hier einen Unterschied in der Struktur, wie Sie Ihre Skripte angehen. Und das werden wir in Kürze mit einigen Beispielen sehen. Die Hauptsache ist, dass Sie
ein SparkSession-Objekt anstelle eines Spark-Kontextes erstellen , wenn Sie Ihr Skript starten. Wenn Sie Spark SQL oder Datasets verwenden
möchten, müssen Sie eine Sitzung auslösen. Stellen Sie sich das wie eine Datenbanksitzung vor. Und Sie müssen diese Sitzung explizit beenden, wenn Sie fertig sind. Sobald Sie diese Sitzung haben, können
Sie tatsächlich einen SparkContext daraus abrufen und
diesen verwenden , um SQL-Abfragen für Ihre Datasets auszugeben. Oder Sie können einfach die geradlinige Dataset-API verwenden, irgendwie so. Sobald Sie also ein Dataset-Objekt geladen haben, können
Sie Dinge wie anzeigen oder auswählen oder filtern oder GroupBy ausführen. Und Sie werden feststellen, dass dies sehr wie SQL-Befehle aussieht, oder? Das Format sollte also sehr vertraut aussehen. Wenn Sie zum Beispiel SQL kennen, wählen Sie einen Feldnamen Zitat aus, der genau das tut, was Sie denken, es würde tun. Es wählt tatsächlich die Zeile „Einige Feldnamen“ aus Ihrem Dataset aus und gibt diese in ein neues Dataset zurück. Filtern. Das ist eine interessante Syntax da, richtig? Also können wir tatsächlich sagen, Filter mit einem Feldnamen auf meinem Dataset größer als 200. Wir können diesen Ausdruck als Parameter innerhalb unseres Filterbefehls setzen und acht zurückbekommen. Es ist Dataset, in dem wir nur Dinge herausfiltern, die größer als 200 sind. Gruppieren nach, das funktioniert genau so, als ob es nicht auch SQL funktioniert. Also könnten wir eigentlich alles auf einem Feldnamen gruppieren. Und das wird dasselbe sein wie eine Reduce-Operation, richtig? Und dann können wir sagen.me sagen, um automatisch den Durchschnitt jedes dieser Ergebnisse zu berechnen. Also in einer Zeile dort, denke ich, wir haben gerade die gesamte Übung gemacht, eines unserer früheren Beispiele mit RDDs, richtig? Das ist also ein gutes Beispiel dafür, wie die Dinge einfacher werden können. Und wenn Sie etwas niedrigerer Ebene tun müssen, können Sie es immer noch. Sie könnten das zurück in eine RDD konvertieren und Ihre eigene benutzerdefinierte Kartenfunktion
übergeben, wenn Sie es auch möchten. Wie gesagt, Sie können hier mischen und abgleichen und das
Beste aus beiden Welten mit Datensätzen und RDDs erhalten. Datensätze eröffnen auch einige andere Möglichkeiten. Wie ich schon sagte, du kannst nicht mit uns reden, JDBC oder ODBC. Es ist also möglich, eine Shell zu öffnen um SQL zu entfalten und damit umzugehen, wie es eine Datenbank ist, was irgendwie genial ist, oder? Ich meine, das gibt Ihnen eine Art von dieser horizontal skalierbaren Datenbank, wenn Sie so wollen, über Ihren gesamten Spark-Cluster hinweg. Wie cool ist das? Und einige der Details hier sind hier auf der Folie aufgeführt, wenn Sie mehr Details wollen, aber ich möchte Ihr Gehirn nicht mit so viel verwirren, weil
wir das nicht in den Übungen machen werden, sondern nur wissen, dass es möglich ist. Sie können auch benutzerdefinierte Funktionen haben, wenn Sie möchten. Manchmal ist dies einfacher, außerhalb von Datasets zu tun, aber Sie dort, hier, wenn Sie sie brauchen. So könnten wir zum Beispiel eine einfache benutzerdefinierte Funktion erstellen, indem wir einfach Org Dot Apache Spark Punkt SQL dot, dot UDF
importieren. Wir könnten eine UDF namens square konstruieren, die nur den Ausdruck take x
enthält und machen es x mal x. Und dann könnten wir, zum Beispiel, Breite Spalte
sagen und eine neue Spalte namens square hinzufügen, die nur aufruft, dass quadratische benutzerdefinierte Funktionen. So können Sie das auch tun, genau wie Sie UDFs in Datenbanken haben können. Sie können UDFs auch in Datasets haben. Das wird also mit einigen Beispielen viel sinnvoller machen. Also lassen Sie uns einfach eintauchen und verbringen den Rest dieses Abschnitts mit Blick auf Beispiele praxisnah. Also gehen wir zurück zu unseren gefälschten sozialen Netzwerkdaten , die wir früher im Kurs mit RDDs verwendet haben. Und ich zeige Ihnen einige Möglichkeiten, Datasets zu verwenden, um diese Daten zu erkunden. Also zuerst werden wir es tatsächlich mit einem tatsächlichen SQL-Befehl abfragen, und dann gehen wir zurück und verwenden Funktionen der Dataset-API, um es abzufragen, ohne tatsächliche SQL-Befehle zu verwenden. Aber der Code wird immer noch viel wie SQL aussehen. Und danach gehen wir zurück zu unseren RDD-Beispielen und wiederholen sie mit Datensätzen und wir werden sehen, welche jetzt einfacher sind und welche komplexer sind. Und es wird eine gute Möglichkeit geben, die Stärken und
Schwächen sowohl von RDDs als auch von Datensätzen zu verstehen . Und Sie können lernen, wie Sie tatsächlich auswählen, welche API für ein bestimmtes Problem verwendet werden soll. Also lasst uns mit der folgenden Vorlesung eintauchen und zu unserem gefälschten sozialen Netzwerk zurückkehren und damit herumspielen.
22. [Aktivität] SparkSQL: Also lassen Sie uns mit Spark SQL und Datasets und
DataFrame spielen tatsächlich mit diesem kleinen einfachen Beispiel hier, öffnen Sie das Spark SQL-Dataset-Beispiel in Ihren Materialien hier. Und lasst uns durch das gehen, was in diesem hier vor sich geht. Also gehen wir zurück zu unserer gefälschten Freunde-Datenbank oder Datensatz , die für unsere Freunde nach Altersbeispiel im ersten Abschnitt verwendet wurde. Und wir werden diese Daten mit SQL SAL Schnittstellen statt Spark SQL abfragen. Also deklarieren wir ein Paket ist immer n. Jetzt beachten Sie, dass wir nur org dot apache, Spark dot SQL einschließen. Wir beschränken uns auf die Spark SQL APIs. Für dieses Beispiel haben wir auch log für J. Wir erstellen unser Objekt und beginnen mit der Erstellung einer Fallklasse. Worum geht es denn denn? Dies ist also eine Scala-Funktion, über die wir vorher noch nicht gesprochen haben. Eine Fallklasse ist also nur eine sehr kompakte Möglichkeit eine Klassen- und Objektdefinition zu
definieren, wenn Sie so wollen. Indem wir also Fall Klasse Person sagen, sagen
wir, dass wir ein Personenobjekt definieren wollen. Und es enthält die folgenden Felder mit den folgenden Typen. Wenn Sie zum Beispiel mit wie C plus plus vertraut sind , ist es irgendwie wie das Deklarieren einer Struktur. Aber die Syntax von hier ist ein bisschen kompakter. Also sagen wir, eine Person besteht aus vier verschiedenen Feldern. Es enthält ein ID-Feld und dieser Name ist aussagekräftig, das wird richtig gehalten. Und diese ID ist eine ganze Zahl. Es enthält ein Namensfeld vom Typ string und H Feld vom Typ integer, und ein Feld eines Freundes vom Typ integer sowie ein Feld vom Typ integer. Ok? Und dies wird tatsächlich verwendet, um die virtuellen Datenbanktabellen zu konstruieren, die mit Spark SQL abfragen werden. Also, wenn wir fertig sind, entspricht dies den Spaltennamen und
die Spaltentypen in unserer Tabelle werden eine ID-Spalte haben, die ganze Zahlen enthält, wird eine Namensspalte haben, die Strings enthält und so weiter und so weiter. Mit dieser einen Zeile haben wir das Schema für unsere Daten definiert. Okay, das ist sehr wichtig. Mit Datensätzen. Wir müssen dieses Schema zur Kompilierzeit definiert haben. Wir können es nicht einfach aus den Daten selbst ableiten. Mit dem in der Hand, werden wir in unsere Hauptfunktion gehen. Wir legen unseren Log-Level fest. Und jetzt, anstatt einen SparkContext zu erstellen, erstellen
wir eine Spark-Sitzung . Auch hier können Sie sich das als ähnlich einer Datenbanksitzung vorstellen. Also, um diese Funkensitzung zu erstellen, sagen
wir SparkSession Dot Builder. Um unsere zu erstellen, um tatsächlich unsere Sitzung zu bauen. Wir geben ihm einen App-Namen war Spark SQL. Wir sagen, unser Master ist lokaler Stern, gleiche genaue Syntax wie zuvor,
sagen, dass wir auf Ihrem lokalen Computer laufen und ich CPU-Kerne und erhalten oder erstellen. Das bedeutet, dass wir tatsächlich eine neue Spark-Sitzung erstellen oder eine vorhandene wiederverwenden können. Denk daran, dass ich dir gesagt habe, dass du diese Dinge aufhalten musst, wenn du fertig bist. Wenn wir hier ein wenig überspringen, sehen
wir, dass wir sagen, Funkenpunkt-Stopp am Ende, um diese Sitzung zu schließen. Es ist möglich, dass diese Sitzungen über die Lebensdauer dieses Treiberskripts hinaus weiterlaufen. Wenn Sie es also nicht explizit gestoppt oder unerwartet beendet haben, könnte
diese Sitzung immer noch auf Ihrem Cluster ausgeführt werden und unsere Kiste würde einfach diese vorhandene Sitzung wiederverwenden, anstatt in diesem Fall eine neue zu erstellen. So ziemlich interessantes Zeug. Lasst uns nun unsere Daten laden. Also denken Sie daran, dass unsere Daten in gefälschten Freunden dot CSV vorhanden sind. Und wir werden das einfach mit Spark dot read laden. Spark-Punkt, der auf dem SparkSession-Objekt gelesen wird, liest diese CSV-Datei. Wir werden ihm sagen, dass es eine Kopfzeile hat. Und wir werden Sie bitten, das Schema zunächst aus dem abzuleiten, was sich in dieser Kopfzeile befindet. Die Kopfzeileninformationen stimmen also mit den gleichen Namen überein, die wir in unserer Fallklasse hier oben angegeben haben, der Header ist ID, Name, Alter und Freunde. Und es ist wichtig, dass, Das passt in diesem Fall. Also an diesem Punkt, nachdem wir Spark dot read.csv gesagt haben, haben
wir einen DataFrame. Zu diesem Zeitpunkt wurde das Schema zur Laufzeit abgeleitet, oder? Das ist der Hauptunterschied zwischen einem Datenrahmen und einem Dataset. Aber wir wollen immer noch Datasets verwenden. Wir wollen alle Vorteile dieser Kompilierzeit-Typprüfung. Also werde ich diesen DataFrame nehmen, der nur aus diesen Zeilenobjekten mit abgeleiteten Schemas besteht, und diesen in ein Dataset mit einem expliziten Schema
konvertieren, indem ich Punkt als Person sage. Dieser Punkt als Person nimmt also den DataFrame, den wir aus der CSV lesen, und konvertiert ihn einen Datensatz mit einem Schema, das wir zur
Kompilierzeit mit der Personenfallklasse mit mir bisher kennen . Okay, es wird mehr Sinn machen, wenn wir es ausführen. Das erste, was wir tun werden, ist, das Schema
auszudrucken, um sicherzustellen, dass es das ist, was wir erwartet haben. Also an dieser Stelle haben wir ein Schema Menschen Dataset. Und jetzt können wir eine Datenbankansicht darauf erstellen, indem wir sagen, erstellen oder ersetzen temporäre Ansicht. Auch hier wird entweder ein neues erstellt oder ein vorhandenes mit dem gleichen Namen ersetzt. Und wir werden so wenige Leute nennen. Dies wird den Effekt haben, im Grunde
eine Datenbanktabelle namens Personen für alle Absichten und Zwecke zu erstellen . Und wir können diese Tabelle jetzt abfragen, indem wir nur Spark dot SQL sagen. Wir rufen den SparkSession Punkt SQL mit einem tatsächlichen SQL-Befehl hier. Wir werden sagen, wählen Sie Stern von Menschen. Das ist die Ansicht, die wir aus unserem Datensatz erstellt haben. Wenn das Alter größer oder gleich 13 ist und das Alter kleiner oder gleich 19 ist. Also erstellen wir hier eine tatsächliche SQL-Anweisung und geben
die Ergebnisse in einer neuen Struktur namens Teenagers zurück , einem neuen Datensatz. Wir werden dann den Inhalt dieser Ergebnisse sammeln und sie durchlaufen, sie alle
ausdrucken und die Sitzung beenden, wenn wir fertig sind. Also lasst uns voran gehen und das laufen und sehen, was passiert. Cool, es hat geklappt. So können wir das abgeleitete Schema hier sehen, tatsächlich das explizite Schema, das wir ihm für den Datensatz gegeben haben, richtig? So können wir bestätigen, dass wir eine ID, Name, Alter
und Freunde Feld der Typen haben , die wir erwarten Integer, String Integer und eine ganze Zahl. Das ist also das Schema unseres Schemas
People-Datasets , das wir dort einrichten und aus dieser CSV-Datei einlesen. Und dann haben wir die Ergebnisse aus unserer Anfrage hier. Und wir sehen, dass wir hier alle Teenager in unserem Datensatz haben. Das sind 19-Jährige und 18-Jährige, und ich denke, dass nur Daten ab 18 Jahren generiert wurden. Das ist also das Ergebnis unserer Anfrage dort. Es sieht so aus, als hätte es funktioniert. Ziemlich genial. Also haben wir tatsächlich einen tatsächlichen SQL-Befehl für
ein Dataset in Apache Spark über einen gesamten Cluster möglicherweise ausgeführt . Wie cool ist also, dass Sie die gesamte Leistung
der SQL-Sprache mit Apache Spark unter Verwendung von Datensätzen zur Verfügung haben. Und ich möchte hier noch einen Punkt ansprechen, bevor wir weitermachen. Also musste ich hier keinen Datensatz verwenden. Ich hätte einen DataFrame verwenden können. Lassen Sie mich Ihnen zeigen, wie das funktionieren würde. Also, wenn ich diese Zeile einfach auskommentiere , werden meine Schemaleute zu diesem
Zeitpunkt ein DataFrame sein. Es wird dieses Schema zur Laufzeit abgeleitet haben. Ich sage es nicht explizit mit dieser Fallklasse, was das Schema ist. Indem ich das kommentiere, verliere ich alle Kompilierungszeitfehlerüberprüfung und Kompilierungszeitoptimierungen, die ich mit Datasets erhalten werde. Aber es wird immer noch funktionieren. Es wird nur zur Laufzeit funktionieren. Also lassen Sie uns das laufen und sicherstellen, dass ich Ihnen keine Lüge erzähle. Und Sie können hier sehen, dass wir die gleiche Antwort haben. So ergibt sich die gleiche Abfrage hier von 18, 19-Jährigen, die wir wollten, und die Schemata immer noch gleich. Es funktioniert also immer noch als DataFrame. Es ist nur so, dass
wir durch die Verwendung eines Datasets und dieses explizite Schema eine bessere Leistung und eine bessere Kompilierungszeitfehlerüberprüfung erhalten. Lassen Sie uns als nächstes in ein anderes Beispiel eintauchen.
23. [Aktivität] Datensets verwenden: In unserer vorherigen Vorlesung sprachen
wir über die Verwendung von SQL-Befehlen direkt auf unseren gefälschten Freunden und Daten aus unserem gefälschten sozialen Netzwerk. Schauen wir uns eine andere Möglichkeit an, dies zu tun, ohne SQL-Befehle zu verwenden, sondern stattdessen die SQL-ähnlichen Funktionen zu verwenden, die für Datasets verfügbar sind. Werfen Sie einen Blick auf diese alternative Art und Weise, Dinge zu tun. Öffnen Sie das DataFrames-Dataset, Treiberskript. Und schauen wir uns das an. So wird die tatsächliche Einrichtung und das Laden unserer Daten vom letzten Mal identisch sein, wir werden eine Person Fallklasse wieder einrichten, die das Schema der Daten
definiert, die wir laden möchten. Und wieder haben wir eine ID, die eine ganze Zahl ist, einen Namen, der eine Zeichenfolge ist, und Alter, das ist eine ganze Zahl. Die Anzahl der Freunde, die auch eine ganze Zahl ist. Innerhalb unserer Hauptfunktion. Genau wie bevor wir unsere Log-Level setzen, erstellen
wir hier ein SparkSession Objekt mit einem Vornamen und Master und wir entweder erhalten oder erstellen es. Und dann wieder lesen wir das aus der CSV-Datei mit Spark dot read. Und wir erzwingen das tatsächlich ein Dataset zu sein, indem wir am Ende Punkt als Person sagen, um
dieses implizit definierte Schema zur Laufzeit in
ein hartcodiertes Schema zu konvertieren dieses implizit definierte Schema zur Laufzeit in , indem wir es hier zur Personenfallklasse zwingen. Also habe ich dies zunächst irgendwie überstrahlt, der Import-Spark Punkt implizit Punktunterstrich Linie ist wichtig, wenn Sie intelligent das Schema implizit ableiten, müssen
Sie sicherstellen, dass Sie dieses Paket direkt vor Du machst es. Syntax hier ist ein wenig seltsam. Normalerweise befinden sich Ihre Importanweisungen ganz oben in Ihrer Datei. Aber in diesem Fall wollen wir es direkt bevor wir
es tatsächlich verwenden , weil wir nur auf diesen spezifischen Bereich hier anwenden wollen. Jedes Mal, wenn Sie einen Befehl haben, sind wir die Schemata, die abgeleitet werden. Und hier ist es ziemlich explizit, dass wir das tun, während
Spark dot read sagen , um den Header in der CSV-Datei zu verwenden. Und wir ziehen das Schema anfänglich von diesem CSV-Header ab, wir müssen implizite auslösen, um das tatsächlich abziehen zu können. Jetzt, wenn wir fertig sind, konvertieren
wir das in ein Dataset mit einem expliziten Schema. Aber dieser Zwischenschritt erfordert Spark-Punkt-Implikate. Es gibt andere Möglichkeiten zum Laden von Datasets, die später angezeigt werden, für die Zwischenschritt eines abgeleiteten Schemas
nicht erforderlich ist, aber wir werden dorthin gelangen. Wie auch immer, wir drucken das Schema aus, wie wir es vorher getan haben. Und jetzt haben wir hier eine andere Art, mit unseren Daten zu spielen, die wir uns ansehen. Also, das ist jetzt das neue Zeug. Lassen Sie uns also beginnen, indem Sie nur die Namensspalte auswählen. Eine Sache, die wir in unseren RDD-Beispielen gemacht haben, so dass das ziemlich üblich war, war das Verwerfen von Spalten mit Informationen, die wir nicht brauchten. Und dies ist eine Möglichkeit, dies mit Datasets zu tun. Wir können sagen, Menschen Punkt wählen, Namen Punkt zeigen, und das würde nur die Namensspalte und nichts mehr auswählen. In diesem Fall werden wir das nicht einem neuen Dataset zuweisen. Wir werden nur Dot Show aufrufen, um Spark tatsächlich zu zwingen, zu gehen und dieses Ergebnis zu erhalten und es uns tatsächlich aus unserem Treiberskript anzuzeigen. So wie Sie sagen können, wählen Sie Name, wir sagen hier, wählen Sie Namen in Anführungszeichen hier anstelle eines SQL-Befehls, Ähnliche Syntax, gleiche Idee, nur eine andere Art, dies zu tun, die keine tatsächliche Datenbankansicht
erfordert. Wir können auch etwas Ähnliches tun wie unsere Freunde nach Altersbeispiel, wo wir gerade gehen, um jemanden über 21 Jahre alt filtern. So könnten wir sagen, People Dot Filter, Menschen Alter weniger als 21 Dot Show. Das ist also das gleiche wie das Auswählen des Namens, bei dem das Alter kleiner als 21 ist, und SQL, aber wir tun dies expliziter durch Funktionen auf dem Dataset selbst. Das ist also ein bisschen komisch, oder? Wissen Sie, wenn Sie es gewohnt sind, sind andere Sprachen nicht funktionale Sprachen. Die Idee, einen solchen Ausdruck zu
haben, Alter von weniger als 21 Jahren und es als Parameter an eine Funktion zu übergeben, könnte seltsam erscheinen. Aber in Scala kannst du das tun. Es funktioniert tatsächlich. Also ist es ziemlich cool. Also sagen wir einfach Leute und wir geben den Namen
der Spalte, die wir nach weniger als 21 filtern möchten. Und dieser Ausdruck, wenn Sie die Filterfunktion eines Datensatzes durchlaufen, funktioniert
einfach. Es tut das Richtige. Es ist fast magisch. Wieder werden wir die Ergebnisse zeigen, sie anzeigen, im
Gegensatz zum Speichern dieses in einem neuen Datensatz in unserem Beispiel hier. Auch in SQL haben wir die Gruppe nach Funktion. Und das ist im Grunde dasselbe wie die GroupByKey-Operation, die wir in RDD hatten. Es wird also alle unterschiedlichen Werte
des Alters zusammenfassen und sie alle zusammen verstopfen. Und dann werden wir darüber hinaus aufgerufen zählen, um nur
eine Gesamtsumme davon zu bekommen , wie viele Menschen in jedem Alter existieren, Jahr und zeigen die Ergebnisse auf einer Zeile hier haben wir etwas
getan, das wir ein wenig mehr mit RDDs tun mussten, Richtig? Wenn Sie sich erinnern, hätten wir Dinge mit einer Kartenoperation transformieren müssen, um eine Nummer eins für jede einzelne Person
einzufügen und dann eine ReduceByKey-Operation
durchführen, um sie alle hinzuzufügen, um dies vorher zu tun. Aber in diesem Fall können wir hier mehr von einer
SQL-Syntax verwenden und alles in einer Codezeile tun. So können Sie hier die Leistungsfähigkeit von Datensätzen sehen. Und da wir Datasets verwenden, kann
es auch effizienter sein. Also, ja, denken Sie nur ein bisschen mehr darüber nach. Wir werden nach Alter gruppieren. So kombiniert das grundsätzlich alle Einträge in Personen durch eindeutige AGE Nummern. Wir zählen jeden einzelnen innerhalb jedes Alters und zeigen die Ergebnisse an. Und hier ist ein weiteres interessantes Beispiel hier. In diesem Fall wählen wir alle Personen aus. Und wir werden nur die Namensspalte auswählen. Und dann werden wir auch Leute Alter plus 10 auswählen. Dies wird also eine Anzeige von zwei Spalten zeigen. Eins ist die Namensspalte aus dem ursprünglichen Personen-Dataset. Und die zweite Spalte wird angezeigt, dass wir
hier auswählen , wird die Alterskolonne mit 10 Haltung es sein. Also wieder können wir diese Ausdrücke innerhalb von Funktionen haben, wenn in Scala, und es funktioniert tatsächlich. Wir können sagen, dass die Leute älter plus 10 sind und das als Parameter an die Auswahlfunktion übergeben. Es ist ein bisschen seltsam, wenn Sie wieder an andere Sprachen gewöhnt sind, aber so machst du es in Scala und Funken, es funktioniert tatsächlich. Und denken Sie daran, Ihre Sitzung zu beenden, wenn Sie fertig sind. Andernfalls wird es weiterlaufen und
herumhängen und Ressourcen verwenden, die Sie nicht verwenden möchten. Und es könnte Sie verwirren, wenn Sie Dinge auch auf nachfolgenden Läufen ausführen. Vergessen Sie nie, Ihre Sitzung zu beenden, wenn Sie fertig sind. Also lassen Sie uns das in Aktion sehen und uns davon überzeugen, dass es tatsächlich funktioniert. Wir werden mit der rechten Maustaste auf DataFrame, Datasets und sagen laufen Sie weg, es geht. Alles klar, und lassen Sie uns durch das gehen, was hier passiert ist. Lassen Sie uns nach oben gehen, hier werde ich nach oben scrollen. Das erste, was wir getan haben, war das Schema vollständig zu drucken, und da ist es. So können wir uns davon überzeugen, dass es dort
tatsächlich die richtige Datensatzstruktur erhalten hat. Sieht für mich richtig aus. So schließen wir einen ID-Namen, Alter und Freunde Spalte der Typen integer, string, integer und integer jeweils ab. Unser erster Schritt hier mit der Auswahl der Namensspalte. Und es gab diesen Befehl hier, Leute dot select col gleich name dot show. Und es hat genau das getan, was Sie erwarten. Und es sieht so aus, wie Sie von
einer tatsächlichen relationalen Datenbankausgabe erwarten würden , nicht wahr? Weißt du, sie sind, sie versuchen wirklich, die Lücke zwischen Spark und der Verwendung
einer relationalen Datenbank zu schließen und es genauso zu machen, es mit Apache Spark und seinen neueren Versionen zu verwenden. Der Unterschied besteht natürlich darin, dass Sie anstelle eines einzelnen monolithischen Datenbankservers einen gesamten Cluster
haben, der dies potenziell tut. So können Sie sehen, dass wir die Namensspalte erfolgreich ausgewählt und gezeigt haben. So haben wir diese kleine Vorschau auf die ersten Einträge. Wir zeigen nur die Top 20 Zeilen standardmäßig an, oder andernfalls würde es nur für immer weitergehen. Und unser nächstes Experiment hier war, jemanden über 21 Jahren herauszufiltern ,
indem wir dieses Filter-Argument von Menschen unter 21 Jahren übergeben haben. Und sicher genug, die resultierenden Daten, die wir zurückerhalten haben,
zeigen nur Menschen im Alter von 19, 20 oder 18 Jahren, denn das sind alle Menschen, die weniger als 21 Jahre alt in unserem Datensatz sind. So dass die Arbeit sehr cool. Und wir haben auch diese Gruppe nach Alter Befehl hier wieder ausprobiert, ein bisschen schicker hier. Also nochmals, um zusammenzufassen, gruppierten
wir alle nach eindeutigen AGE Zahlen und wir zählten sie alle und wir zeigten sie und es sieht so aus, als ob es funktioniert hat. So haben wir 831-Jährige, 565 Jährige, 753-Jährige, et cetera, in unserem Datensatz. Also wieder eine Codezeile, sehr einfach, sehr einfach zu bedienen. Sie sind hochoptimiert. Und es ist viel einfacher als die Art und Weise, wie wir dies mit RDDs tun mussten. Schließlich haben wir dies getan, machen alle 10 Jahre älter Trick hier, wo wir
die Namenspalte ausgewählt und auch eine neue Spalte erfunden, die Menschen Alter plus 10 genannt wird. Mal sehen, ob das funktioniert hat. Und ja, es sah so aus, dass wir vermutlich ursprünglich 33 waren, aber im Alter plus 10 Spalte, die wir hier erstellt haben, ist
er jetzt 43. Und es funktioniert tatsächlich. Sie können mathematische Ausdrücke wie diese übergeben und sie werden tatsächlich ausgewertet und Ihnen auf diese Weise angezeigt. Als wir fertig waren, beenden wir die Sitzung, und das war es. Also da hast du es. Datasets, die Funktionen anstelle von tatsächlichen SQL-Befehlen verwenden. Sie können es so oder so tun, aber, wissen
Sie, hängt von Ihrer Präferenz ab. Also da hast du es. Zwei verschiedene Arten der Verwendung von Datasets.
24. [Übung] Beispielbild mit dem Beispiel von "Freunde von Age“: In Ordnung, du hast mir lange genug gehört, wie ich über Datensätze rede. Ich denke, es ist an der Zeit, deine Hände schmutzig zu machen und sie selbst zu benutzen. Lassen Sie mich Ihnen also Ihre erste Herausforderung mit Datensätzen geben. Erinnerst du dich an die Freunde nach Alter Beispiel, die wir mit RDDs gemacht haben? Nun, ich wollte wieder dorthin gehen und es wieder tun, aber diesmal Datasets anstelle von RDDs verwenden. Nur um zu überprüfen, worum es in diesem Beispiel geht, haben
wir eine gefälschte Freunde kommagetrennte
Wertedatei zur Verfügung gestellt , die Daten in diesem Format enthält. Es handelt sich im Grunde um eine Benutzer-ID, ihren Namen, ihr Alter
und die Anzahl der Freunde, die sie haben. Und deine Aufgabe ist es, mir die durchschnittliche Anzahl von Freunden nach Alter zu geben. Also möchte ich im Durchschnitt wissen, wie viele Freunde als 33-Jährige haben, viele Freunde ist ein 55-Jähriger haben und so weiter und so weiter für jedes Alter in meinen gefälschten Freunden dot CSV Datei vertreten. Und es nennt sich gefälschte Freunde, weil es alles falsche Daten sind. Es wurde alles nach dem Zufallsprinzip erzeugt. Sie sind also nicht so, ich hier kein Wert-Urteilsvermögen über Ihre Freunde mache. Wie auch immer, einige Hinweise, wie man das durchkommt. Es gibt also eine gefälschte Freunde Dot CSV-Datei in Ihrem Kursmaterial, die eine Kopfzeile enthält. Und wie Sie in unseren vorherigen Beispielen gesehen haben, ist die
Verwendung von Datasets wichtig, um Jakobsmuscheln und
Funken für das richtige Schema für diese Daten zu ermöglichen . Und ein paar Befehle hier, die sich als nützlich erweisen könnten. Denken Sie daran, wir können den Befehl select verwenden, um
bestimmte Spalten aus einem Datensatz zu extrahieren und eine neue zu erhalten, die nur die Daten enthält, die wir brauchen. Sie könnten sich erinnern, dass wir, als wir das mit RDDs gemacht
haben, eine Kartenfunktion hatten, die das tatsächlich für uns getan hat. Dies wird also viel einfacher mit einer Select-Anweisung sein. Und Sie werden eine andere Dataset-Funktion benötigen. Also GroupBy, die wir uns vorher angesehen haben, wird die Dinge im Grunde nach einzigartigen Zeitaltern zusammenfassen, irgendwie wie eine Reduce-Operation. Show zeigt die Endergebnisse und bekommt sie zurück. Und wenn wir nicht darüber gesprochen haben, war AVG für den Durchschnitt. Also, nachdem Sie die Dinge nach Alter gruppiert haben, werden
Sie dann wollen, um den Durchschnitt nach Alter zu erhalten. Und so sehe ich immer die Spaltennamen, die ich hier für illustrative Zwecke eingefügt habe, es liegt an Ihnen, die richtigen dort reinzubringen und sie in die richtige Reihenfolge zu bringen und was nicht. Aber das sind die Stücke, die Sie brauchen sollten, um dies zu tun. Und vielleicht möchten Sie zur Inspiration auf
die DataFrames-Dataset-Punkt-Scala-Datei zurückverweisen . Und du musst es auch nicht so machen. Sie könnten einfach einen geraden SQL-Befehl verwenden, wenn Sie es auch möchten. Es liegt also an dir, in welche Richtung du gehen willst. Also geh und probiere das mal aus. Und wenn wir zur nächsten Vorlesung zurückkommen, zeige
ich Ihnen meine Lösung und auch
einige Möglichkeiten, um es zu erweitern, um einige interessantere Dinge mit diesen Daten zu tun. Also geh und schaue, ob du
das zum Laufen bringen kannst und komm dann zurück und ich zeige dir meine Lösung. Schauen Sie nicht auf die Lösung. Es ist da drin und natürlich Materialien, also stellen Sie sicher, dass Sie eine neue Datei erstellen, die einen eindeutigen Namen hat und der Versuchung
widerstehen, Jungs zu peppen und zurück zu kommen und wir werden über die Antwort gehen.
25. Übung von: Freunde von Alter und Datasets.: Okay, also hoffe, dass Sie diese Übung durchlaufen konnten und
die Freunde nach H-Aktivität mit Datensätzen ohne zu viel Mühe implementieren konnten. Wenn Sie Ihren Ansatz mit meinem vergleichen möchten. Hier ist meine Lösung hier. Wenn Sie die Freunde nach Alter Dataset-Skript hier in den Kursmaterialien öffnen. Und wieder gibt es viele Möglichkeiten, dies zu tun. Also, wenn Ihr Code nicht genau mit meinem übereinstimmt, ist das okay. Alles, was wirklich zählt, ist, dass Sie die gleichen Endergebnisse haben. Also vor Ort überprüfen Sie ein paar der durchschnittlichen Ergebnisse, die Sie
für verschiedene Altersgruppen bekommen , und wenn sie mit meinen übereinstimmen, Sie sind gut. Lasst uns durch das gehen, was ich hier getan habe. So wird viel davon vertraut aussehen. Wir haben in diesem Fall eine Fallklasse namens „Fake Friends
“ anstelle von Person erstellt , nur um die Dinge ein wenig zu vermischen. Dies definiert das explizite Schema unserer Daten aus der gefälschten Freunde dot CSV-Datei, die aus einer ID und Namen, Alter und Freunden besteht. Wir haben das schon mal gesehen, nur einen anderen Namen. Als erstes stellen wir unseren Log-Level ein, erstellen Sie eine SparkSession, wie wir es zuvor getan haben. Und wie wir es vorher getan haben, laden
wir den Datenschrägstrich gefälschte Freunde dot CSV-Datei mit abgeleitetem Schema aus dem Header. Und dann zwingen wir diesen DataFrame in einen Datensatz, indem wir Punkt S sagen und übergeben, in diesem Fall Klasse gefälschte Freunde explizit definieren, was sein Schema ist. Jetzt können wir zur Kompilierzeit alle Typen überprüfen und was nicht und einige Optimierungen auch zur Kompilierzeit durchführen. Okay, das erste, was wir tun, ist, nur die Spalten auszuwählen, die wir brauchen. Wie Sie sich erinnern, die einzigen Dinge, die uns in
diesem Beispiel wirklich wichtig sind, das Alter und die Anzahl der Freunde, die Benutzer-IDs und die Namen für dieses Problem irrelevant. Daher werden wir nur aus diesem Dataset,
die Spalte Alter und Freundeauswählen die Spalte Alter und Freunde und diese in ein neues Dataset namens Freunde nach Alter übergeben. Und jetzt müssen wir nur Freunde nach Alter Dot Groupby auf Alter sagen. Das wird also alles nach einzigartigen Alterswerten gruppieren. Und dann, sobald wir das haben, werden
wir außerdem sagen Punkt AVG, um den Durchschnitt der
Freunde Spalten nach Alter gruppiert zu bekommen und dann Punkt zeigen, um die Ergebnisse anzuzeigen. Und das war's. Wir wären tatsächlich an dieser Stelle erledigt. Es gibt noch ein paar Tricks, die ich dir hier zeigen möchte, also gibt es noch mehr zu reden. Aber für die Herausforderung, wie gesagt, ist das alles, was Sie brauchen. Das ist also ziemlich cool, oder? In zwei Codezeilen haben wir im Grunde getan, was wir
im gesamten Beispiel mit RDDs gemacht haben . Gehen wir zurück und schauen uns das nur für Vergleichszwecke an. Also hier ist die Freunde von Alter Punkt Scala Skript, wo wir dies mit RDDs gemacht. Und Sie werden sehen, dass es hier viel komplizierter ist. Also hier hinten mussten wir diese Parse-Line-Funktion schreiben, um alles
zu analysieren und Dinge durch Kommas zu teilen und die Felder zu extrahieren, die wir wollen, und ein neues Tupel zurückzugeben. Das ist, was die Felder, die wir wollen. Während bei Datensätzen können wir einfach
den CSV-Lader verwenden , der in unserer Spark-Sitzung integriert ist. Und verwenden Sie die select-Anweisung, um die Felder auszuwählen, die wir wollen. So viel einfacher bei der Verwendung von Datensätzen. Also mit RDDs mussten wir alle möglichen
verschlungenen Dinge tun , um diesen Durchschnitt zu berechnen, oder? Wir mussten gehen und Dinge auf x Komma eins hier abbilden. So können wir einfach alles mit ReduceByKey zählen. Und es ist eine ziemlich verdrehte Art zu tun, was wir gerade hier im Dataset-Beispiel
verwendet haben, gruppiert um einen Durchschnitt. Und nach diesem ReduceByKey mussten
wir den Durchschnitt auch von Hand berechnen, indem wir MapValues verwenden. Also dieser Code, denke ich, macht viel mehr Sinn. Es ist viel einfacher zu lesen. Es ist viel einfacher. Im Gegensatz zu dem, was wir hier mit RDDs tun mussten, um dasselbe zu tun. Das ist also ein gutes Beispiel dafür, wo Datasets viel einfacher zu verwenden sind und es vielleicht sogar noch schneller sein können. Aber unter der Haube sind
es RDDs auf einer niedrigeren Ebene. Und so manchmal ist es gut, auf diese niedrigere Ebene zu gehen, wenn Sie wirklich brauchen, um die Dinge auf dieser Ebene zu optimieren, lassen Sie uns weiter und nehmen dies jedoch zum nächsten Schritt. Was wäre, wenn ich diese Daten sortieren wollte? Es stellt sich heraus, dass das auch einfach ist. Wenn ich diese Dinge nach Alter sortieren wollte, könnte
ich vor der Show einfach einen Punkt sortieren Alter Befehl dort stecken. Und das wird die Ergebnisse meiner Durchschnittswerte
nach Alter nehmen und sie einfach nach der Altersspalte sortieren, bevor sie angezeigt werden. Und außerdem könnte ich das noch schöner formatieren. Unsere Durchschnittswerte werden manchmal viele
Dezimalstellen haben und es macht keinen Sinn, so viel Präzision zu haben. Ich könnte sagen, AGG und dann runder Durchschnitt. Das erfordert ein bisschen, um den Kopf herum zu kriegen. Also haben wir den Durchschnitt der Anzahl der Freunde hier, die wir vorher gemacht haben. Und dann sagen wir, dass wir das auf zwei Dezimalstellen mit Genauigkeit runden. So funktioniert der runde Befehl dort. Und wir müssen diese AGG-Funktion verwenden, weil wir alle Daten für das gegebene Alter
aggregieren, nach dem wir gruppiert sind, richtig? Also Qualen, wir werden diesen Durchschnitt über
das Aggregat aller Werte für dieses Alter berechnen , die wir dort ausgewählt haben. Nachdem diese Rundung abgeschlossen ist, sortieren
wir die Ergebnisse erneut nach Alter und zeigen sie. Und wir können auch unsere Spaltennamen anpassen. Und das ist es, was dieses Beispiel hier macht. Hier fügen wir einen Alias hinzu, nachdem alles abgerundet wurde. Und wir werden das umbenennen, um Freunde unterstrichen Durchschnitt. Und dann wieder sortieren wir es und zeigen es. Also lasst uns das noch mal durchlaufen. Nachdem Sie die Ausgabe gesehen haben, könnte es ein wenig mehr Sinn machen. Lassen Sie uns mit der rechten Maustaste auf Freunde nach Alter Datensatz und führen Sie es aus. Und los geht's. Okay, also lassen Sie uns hier von oben durch jede Reihe von Ergebnissen gehen, scrollen Sie hier bis zum Anfang. Also, unser erstes Beispiel war das einfache, wo wir gerade eine Gruppe nach Alter und dann Durchschnitt von Freunden
gemacht haben und es gezeigt haben. Und das funktioniert. So gruppierte die Gruppe nach Alter alles nach eindeutigen Altersgruppen und durchschnittlich den Computer eines Freundes, der Durchschnitt der Freundesspalte für jedes Alter. Es ist einfach, und das funktioniert in der Tat. Sie werden jedoch feststellen, dass die Kanten nicht sortiert sind, so dass es ein wenig schwierig ist, Dinge nachzusehen und eine spezifische Antwort davon zu erhalten. Auch die Anzeige hier ist ein bisschen seltsam, oder? Wir haben all diese verrückten Mengen an Präzision den Durchschnitten, die wahrscheinlich nicht notwendig sind. In unserem nächsten Beispiel lösen
wir das Sortierproblem. Alles, was wir hier getan haben, war, eine Punktsortierung mit einem Altersparameter dort
zum Mix dort am Ende hinzuzufügen . Und das hat funktioniert. So sehen wir, dass die Zeitalter jetzt sortiert sind. Wir beginnen mit 18, 19, 20, 21 usw. und das scheint auch funktioniert zu haben. Und darüber hinaus können wir es noch schöner machen. Wenn wir also zu diesem dritten Beispiel hier gehen, runden
wir die Ergebnisse auf zwei Dezimalstellen der Genauigkeit ab, indem wir
eine runde Funktion auf den Durchschnitt anwenden und
Ag verwenden , um diese auf die gesamten Altersergebnisse für diese Gruppe anzuwenden. Also hier haben wir das Alter und den Ausdruck runde durchschnittliche Freunde Komma zwei, die diesen Durchschnitt auf zwei Dezimalstellen der Genauigkeit rundet. Und Sie können sehen, dass tatsächlich wie beabsichtigt funktioniert. Sehr cool. Und schließlich haben wir diesem einen benutzerdefinierten Spaltennamen gegeben, indem wir auch den Alias-Befehl innerhalb dieses Aggregats verwenden. Indem wir also Punkt-Alias sagten, haben wir diese Spalte von
runden durchschnittlichen Freunden Komma zwei in etwas nützlicheres umbenannt , Freunde unterstreichen den Durchschnitt. Und wenn Sie dies in einem resultierenden Dataset sagen würden, würde
das es einfacher machen, auf diese neue Spalte zu verweisen, die wir
nach ihrem Namen berechnet haben, ohne diese riesigen gewundenen Ergebnisse eingeben zu müssen. Wenn Sie also Datasets auf diese Weise miteinander verketten, ist das oft sehr nützlich um auf diese berechneten Ergebnisse in dieser Spalte zu verweisen. Und da haben Sie es in Datensätzen mit unseren Freunden nach Alter Beispiel, getan ein paar verschiedene Möglichkeiten und erweitert auf ein paar verschiedene Arten, dies zu tun,
Ich hoffe, Sie haben ein paar Dinge gelernt, es. Gehen wir zu einigen weiteren Beispielen über und machen Sie sich noch besser mit Datensätzen vertraut.
26. [Aktivität] Wort, die den Beispiel, mit Datensätzen verwendet: Lassen Sie uns also weiter über Datasets durch Beispiele lernen. Und wieder kehren wir zu unseren RDD-Beispielen zurück und passen unsere
Wortzählerübung an, um Datensätze anstelle von RDDs zu verwenden. Und wir gehen direkt zu der komplizierteren Version, die tatsächlich reguläre Ausdrücke
verwendet und die Ergebnisse sortiert. In diesem Beispiel werden
wir SQL-Funktionen verwenden, um die gewünschten Ergebnisse zu erzielen. Anstatt FlatMap zu verwenden, werden
wir eine Funktion namens explode verwenden, die Spalten in Zeilen explodiert. Wenn also jede Spalte ein Wort ausnutzbar darstellt, fügen Sie jedes Wort in eine eigene Zeile ein. Wir werden die Split-Funktion verwenden, um die Dinge nach Wort zu teilen. Wir verwenden die niedrigere Funktion, um alles in Kleinbuchstaben zu konvertieren. Und ein paar Notizen hier über Syntax zu beachten. Wenn Sie also einen Spaltennamen als Parameter in diese SQL-Funktionen übergeben, ist
die Syntax Dollarzeichen und dann der Spaltenname in Anführungszeichen. Zum Beispiel teilen Dollarzeichen Anführungszeichen Wert Komma, und dann würde der reguläre Ausdruck aufteilen, was Text in
der Wertspalte ist , basierend auf den Worttrennzeichen dort aufteilen. Ebenso würde Filter auf die gleiche Weise funktionieren, wenn wir filtern wollten, um Wörter zu entfernen, die eine leere Zeichenfolge haben, würden wir es auf diese Weise tun. Filtern Sie Dollarzeichen, und dann Wort in Anführungszeichen. Und beachten Sie die seltsamen Gleichheitsoperatoren hier, wenn Sie hier Filteraussagen verwenden, es wird nicht ein Bankzeichen gleich sein, es wird gleich sein, Knallsinus gleich. So ein kleines bisschen seltsam. Ähnlich Ungleichheit Operator hier wäre gleich, gleich, gleich. Also nur etwas zu erinnern, Sie erhalten einen Fehler im Compiler, wenn Sie das nicht richtig verstehen. Das wird dich daran erinnern, wenn es ein Problem gibt, aber irgendwie eine seltsame, schrullige Sache dort. Also wieder, das ist ein Beispiel für das Testen, wo es gegen eine leere Zeichenfolge, nur zwei Anführungszeichen mit nichts dazwischen. Nun ist es erwähnenswert, dass das Dataset wirklich am besten mit strukturierten Daten funktioniert. Und wenn wir es nur mit Textzeilen zu tun haben, das keine wirklich strukturierten Daten. So passen Sie hier einen quadratischen Pfosten in
ein rundes Loch ein, indem Sie Datasets verwenden. Bis zu einem gewissen Grad. Manchmal sind RDDs einfacher und dies könnte einer davon sein, aber Sie müssen nicht nur Datensätze oder RDDs verwenden. Sie können beide zusammen verwenden und wir werden in einer Sekunde mehr darüber reden. Eine andere Sache
ist jedoch zu beachten, dass etwas anderes Es ist seltsam, Datasets in
diesem Sinne zu verwenden , ist, dass wir, weil
wir keine strukturierten Daten hereinkommen, auch kein Schema haben. Das Schema, das am Ende abgeleitet wird, ist irgendwie willkürlich. Wir enden nur mit einem DataFrame voller Zeilenobjekte mit einer Spalte namens Wert standardmäßig für jede Textzeile, da es kein Schema gibt. Jede Zeile ist nur eine Textzeile. Es gibt also einen Standardnamen für diese Spalte namens Wert, über den Sie irgendwie wissen müssen. Und so werden wir im Skript auf diese Daten verweisen. Aber auch hier können Sie beides verwenden und wir werden einen Weg sehen, dies zu tun. Denken Sie also daran, dass Sie RDDs zwei Datensätze konvertieren können. Und so manchmal ist es sinnvoll, Ihre Last,
Ihre Daten über die RDD-Schnittstellen offenzulegen und sie dann in ein Dataset zu
konvertieren, um später die weitere Verarbeitung zu erleichtern. Also werden wir das auch versuchen. Lass uns eintauchen und sehen, wie es aussieht. Also lassen Sie uns die Wortzahl öffnen, besser sortiertes Dataset-Skript hier und gehen durch, was hier vor sich geht. Also werden wir das hier auf ein paar verschiedene Wege machen. Beginnen wir, als ob wir immer nur all das importieren, was wir brauchen, unser Paket
deklarieren, ein Objekt deklarieren. Dieses Mal werden wir eine sehr einfache Fallklasse
haben, um unseren ursprünglichen Datensatz von Daten zu laden. Wir nennen es einfach „Buch“. Und die einzigen Daten, die es hat, ist eine Zeichenfolge, die wir Wert nennen müssen. Denken Sie daran, wir werden später darauf zurückkommen, warum dieser Wert benannt werden muss. Gehen wir zu unserer Hauptfunktion, legen Sie die Protokollebene fest, erstellen Sie eine Spark-Sitzung wie zuvor. Und wieder werden wir dies zunächst als
DataFrame importieren , indem wir readme.txt mit Datenbuch Punkttext verwenden. Und um dieses Schema implizit herauszufinden, müssen
wir Funkenpunkt-Implikate importieren, um dies auf DataFrame-Ebene zu tun. Wir rufen dann dot als Buch auf, um dies in
einen Datensatz zu erzwingen , der ein definiertes Schema hat, über das wir bei der Kompilierung wissen können. Was hier seltsam ist, ist, dass, wenn wir dieses Schema implizit mit dem DataFrame abgeleitet haben, kein Schema zur Verfügung gestellt wurde. Alles, was wir wissen, ist, dass wir Textzeilen haben, die durch Spark dot-dot text kommen. Und standardmäßig wird jede Textzeile als Wert bezeichnet. Das ist der Name der einen Spalte, die wir haben. Und das müssen wir nur wissen. Damit dieses Dataset mit dem abgeleiteten DataFrame-Schema übereinstimmt, müssen
wir diesen Zeilenwert benennen. In Ordnung, also haben wir diesen Namen nicht willkürlich gewählt. Wenn es etwas anderes als Wert wäre, würde
diese Zeile nicht funktionieren. Also wieder, wir befassen uns mit, wie Verwendung von Datasets in einigen Situationen ein wenig klobig sein kann, wenn Sie es nicht mit tatsächlichen strukturierten Datenquellen zu tun haben aus einer Datenbank oder einem Datenbankformat
kommen. Aber sobald wir das getan haben, werden
wir einfach weitermachen. Also, jetzt werden wir das mit
einem regulären Ausdruck aufteilen , wie wir es irgendwie zuvor mit dem geteilten Operator getan haben, wir verwenden RDDs. Und dann, anstatt FlatMap zu verwenden, um das in einzelne Zeilen für jedes Wort zu blasen, werden
wir die Explode-Funktion verwenden. Schauen Sie sich das genauer an. Wir sagen Eingabe,
das ist unser Eingabe-Dataset , das eine Zeile Text in jeder Zeile enthält. Und wir werden sagen, wählen, explodieren, teilen Sie Wert mit einem regulären Ausdrucksmuster, um Dinge in einzelne Wörter aufzuteilen. Okay, also fangen wir hier in der Mitte an. Also beginnen wir zu sagen, teilen Sie die Wertspalte. Und wieder, das ist nur der Name, den wir automatisch einer Textspalte zugewiesen haben, die wir auf dem Worttrennzeichen basieren. Also an diesem Punkt werden wir eine Reihe von Wörtern haben. Wir werden Explode nennen, um das dann
in eine Reihe von einzelnen Zeilen für jedes Wort aufzuteilen . Und dann geben wir dem einen Alias namens Wort, denn sonst wäre es diese große gewundene Beschreibung dieser Spalte, die wir generiert haben. An dieser Stelle sollten wir einen neuen Datensatz haben, der
eine Wortspalte hat, in der sich jedes Wort in einer eigenen Zeile befindet. Darüber hinaus stellt sich heraus, dass wir mit
einem Haufen leerer Strings enden , wenn wir es so machen,
und wir wollen diese herausfiltern, damit wir nicht
diesen großen Eintrag in unseren Endergebnissen erhalten , dass leere Strings wirklich üblich sind. Also, um das zu tun, werden wir nur Punktfilter sagen. Und wir werden filtern, wo das Wort Spalte nicht gleich einer leeren Zeichenfolge ist, nur zwei Anführungszeichen mit nichts dazwischen. Also nochmal, notieren Sie die Syntax hier, Dollarzeichen und dann den Spaltennamen in Anführungszeichen. Und an dieser Stelle hatten wir bereits einen Alias zu dieser neuen Wortspalte namens Wort gegeben,
so dass wir auf sie durch das Namenswort in der Filteroperation, die danach kommt, verweisen können. Also, jetzt haben wir einen neuen Wortdatensatz, der einzelne Wörter in jeder Zeile enthält. Wir haben alle leeren Worte herausgefiltert. Als nächstes werden wir das in Kleinbuchstaben umwandeln. Und wieder werden wir sagen, words.py wählen Sie in unserer unteren Funktion übergeben. Und wir werden diese niedrigere Funktion auf das Wort Spalte anwenden. Und wir werden diesem wieder einen neuen Alias geben und das Namenswort behalten. Wir werden das im Grunde in Kleinbuchstaben umwandeln. Als nächstes zählen wir die Vorkommen jedes Wortes, indem die Gruppe nach Operator
verwenden, und dann zählen. Also wird groupby alle einzigartigen Wörter zusammen sammeln und dann zählen, wird dies alle Vorkommen von jedem zählen? So haben wir jetzt ein neues Wort-Zähldatensatz, das eine Zählung jedes einzelnen Wortes enthält. Wir sind fast fertig. Jetzt müssen wir nur die Ergebnisse nach der Zählspalte sortieren und sie anzeigen. Und beachten Sie die Syntax hier. Also, was genau hier los ist, wenn wir sagen, zeigen Wortzahlen, sortierte Punktanzahl, dot t2 int, wir stellen nur sicher, dass der show Befehl zeigt den vollständigen Satz von Ergebnissen hier. Standardmäßig werden nur die ersten 20 Zeilen angezeigt. Wir wollen alle Ergebnisse zeigen. Die Art und Weise, wie diese Show funktioniert, ist, dass Sie ihm die Anzahl der Zeilen übergeben, die Sie anzeigen möchten. Und wir wollen das Ganze. Also werden wir Wortzahlen sortierten Punktanzahl aufrufen,
um die Anzahl der Zeilen in Wortzahlen sortiert zu erhalten. Und dann müssen wir das explizit in eine ganze Zahl konvertieren, um
sicherzustellen , dass show den erwarteten Datentyp erhält. Wenn Sie also
den gesamten Inhalt eines Datasets anzeigen möchten , würden Sie dies tun. Sie würden nur das Dataset name.com dot t2 int sagen und das als Parameter an
den show Befehl übergeben , um sicherzustellen, dass jede Zeile angezeigt wird. Gehen wir also weiter und führen Sie das aus, bevor wir weitermachen und sehen, wie das funktioniert. Klicken Sie also mit der rechten Maustaste auf WordCount, besser sortiert Datensatz. Ab geht es. Und da sind unsere Ergebnisse. Scrollen wir nach oben. Und Sie können sehen, dass es funktioniert hat. Sieht so aus, als hätte ich da einen Tippfehler. Verwenden Sie drei. Das sind alle Worte und erschien nur einmal in meinem ganzen Buch. Und wenn wir nach unten scrollen, werden wir immer häufiger Wörter sehen, während wir gehen. Es ist also das Ende davon. Ja. Also ist das Wort, das Sie eigentlich das häufigste Wort gefolgt von dem Wort, ziemlich unüberraschend Ergebnisse und die gleichen Ergebnisse, die wir mit RDDs als auch zurückbekommen. Lassen Sie mich Ihnen einen anderen Weg zeigen, dies zu tun, denn wie gesagt, der Prozess, diese Daten in einen Datensatz zu laden, war ein wenig klobig. Vielleicht ist ein RDD besser geeignet, um diese Rohdaten zu plündern. Also, wie ich auf den Folien sagte, wir können mischen und zusammenpassen. Sie können das Beste aus beiden Welten bekommen. In diesem alternativen Ansatz laden
wir die Daten über die RDD-Schnittstelle. Also werde ich diese SparkContext aus
der SparkSession holen und die alte TextFile-Funktion aufrufen. Also, das wird nur alle Buchpunkt-Textdaten in
eine RDD laden , wo jede Zeile eine Textzeile ist. So können wir jetzt einfach FlatMap auf Buch RDD aufrufen und das mit einem regulären Ausdruck aufteilen, wie wir es vorher getan haben. Und das ist wohl ein bisschen einfacher als die Art, wie wir es mit einem Datensatz gemacht haben. Wir mussten diese seltsame gewundene Sache mit Split machen und einen Alias und Filter
explodieren, um das mit einem Dataset zum Laufen zu bringen. Hier ist ein Beispiel, in dem eine RDD tatsächlich einfacher ist. Aber wenn Sie Analysen durchführen möchten, sind
Datensätze normalerweise die bessere Wahl, oder? Weil Sie die gesamte Leistung von SQL
hinter sich haben und die bessere Optimierung, die, das bietet. Also an dieser Stelle können wir die RDD2 ein Dataset konvertieren. Und das ist es, was hier mit zwei ds los ist. Und von diesem Punkt an ist
der Code im Grunde der gleiche. Der einzige Unterschied besteht darin, dass wir uns auf
diesen Wert-Namen anstelle von Wort beziehen , da
wir an diesem Punkt immer noch mit dem Standardspaltennamen des
Werts zu tun haben, den wir erhalten haben, als wir die RDD in ds konvertiert haben. Und das funktioniert auch. Also haben wir das schon ausgeführt. Wenn wir nach unten scrollen, können wir den zweiten Lauf sehen, bei dem wir die gleichen genauen Ergebnisse nur auf eine andere Weise
erhalten haben, indem wir eine RDD verwenden, um die Daten zu laden, und ein Datensatz, um sie tatsächlich zu analysieren. Manchmal kann das ein nützlicher Trick sein, besonders wenn Sie es nicht mit einer strukturierten Datenquelle zu tun haben. Und Sie können sehen, dass wir am Ende die gleiche Antwort haben. Das sind zwei Möglichkeiten, dies mit Datasets zu tun und auch einen hybriden RDD- und Dataset-Ansatz zu verwenden. So kann es manchmal nützlich sein, diese Werkzeuge in der Gesäßtasche zu haben.
27. [Aktivität] Wiedersehen des Minimum mit Datensätzen: also Datasets verwenden, ist es eigentlich ziemlich einfach, wie Sie gesehen haben, aber wir werden hier schnell ein paar weitere Beispiele durchlaufen, um diese RDD-Beispiele zum Beispiel mit Datensätzen
neu zu implementieren. Gehen wir also zurück zu den Minimal- und Maximaltemperaturübungen, die wir gemacht haben, und haben einen Blick auf diejenigen genommen, die Datensätze anstelle von RDDs verwenden. Nicht ganz neu in diesem Beispiel. Eines ist jedoch, dass wir
ein explizites Schema für SparkSession dot read zur Verfügung stellen werden . Anstatt es aus einer CSV-Datei abzuleiten, werden
wir es explizit sagen, was das Schema ist, wie es im DataFrame liest. Wir müssen das immer noch in ein Dataset mit einer Fallklasse konvertieren. Dies ist jedoch eine andere Möglichkeit, Daten aus einer Textdatei zu importieren, die wir uns ansehen werden. Und wir werden auch die Verwendung der Breitenspaltenfunktion in
einem Dataset betrachten , um eine neue Spalte mit unserer eigenen benutzerdefinierten Funktion zu erstellen. Also lasst uns eintauchen und sehen, wie das alles funktioniert. Lassen Sie uns also einen Blick auf die ursprüngliche RDD-Version davon werfen. Das ist das Min temperatur-Skript hier. Und nur um Ihren Speicher zu aktualisieren, haben wir eine 8800 Punkt CSV-Datei geladen, die Wetterinformationen aus dem Jahr 8800 enthielt. Wir analysieren das dann, um die Felder zu extrahieren, die wir wollten und wandelten es in Fahrenheit, während wir gingen. Und dann haben wir mit dem Filterbefehl alles ausgeschnitten, was kein T min Eintrag für die tatsächliche Art des Wettereintrags war. Wir ordnen das auf Stations-ID und Temperatur-Tupel zu und reduzieren es per Schlüssel um die Mindesttemperatur für jede einzigartige Wetterstation zu verfolgen. Also lassen Sie uns sehen, wie wir dies mit einem Datensatz anstelle einer RDD tun. Klicken Sie auf Min. temperaturdatensatz. Und hier ist unsere neue Implementierung. Interessanterweise ist es mehr Code, nicht weniger. Also wieder, für einfache Dinge wie diese , die nicht wirklich mit Datenbank-Arten von Problemen zu tun haben. Manchmal könnte eine RDD tatsächlich einfacher sein. Aber schauen wir uns mal an. Wir beginnen also mit unserer Paketdeklaration und importieren bestimmte SQL-Typen, die wir innerhalb unseres Skripts,
der SparkSession und der SQL-Funktion verwenden werden. Anstatt alles zu importieren, ist
es normalerweise eine bessere Übung, nur das zu importieren,
was Sie brauchen, was wir hier tun. Wir beginnen mit der Deklaration einer Temperaturfallklasse. Dies wird das Format sein, das wir aus unserer eigentlichen Datendatei einlesen. Es hat das Format einer String-basierten Station-ID, ein Datum, das wir als Ganzzahl interpretieren können, einen Messtyp
, der eine Zeichenfolge ist, und eine Temperatur, die ein Gleitkommawert sein wird. Wir legen unseren Log-Level fest, erstellen unsere Spark-Sitzung wie zuvor. Und jetzt werden wir hier etwas Neues machen. Wir werden ein bestimmtes Schema für diese Eingabedaten deklarieren. Anstatt es von einem Header abzuleiten, weil wir keinen Header auf dieser CSV-Datei haben. Wir werden es explizit sagen, was diese Spalten bedeuten, dass es eingelesen wird. Nun, bevor wir betrogen, indem wir sagen, den Header importieren und das Schema aus dem Header ableiten, aber wir haben das diesmal nicht. Also hier ist eine alternative Möglichkeit, es zu tun. Wir richten also einen Temperaturschemawert ein, der ein StructType sein wird. Und wir werden die Add-Funktion auf
diesem StructType aufrufen , um dieser Struktur verschiedene Felder hinzuzufügen. Also sagen wir einfach hinzufügen Station-ID, die ein String-Typ ist, und es kann mobil sein. Datum als Integer-Typ Measure-Typ ist ein String-Typ, Temperatur ist ein Float-Typ C. Und das alles stimmt mit den Namen überein, die wir hier in unserer Fallklasse haben. Und die gleichen Typen, die gleichen Namen. Jetzt, da wir das haben, können wir
Funkenpunkt-Implikate importieren und unsere Daten aus der CSV-Datei lesen. Dieses Mal statt 3D aus dem Header zu sagen, werden
wir Punktschema mit Temperaturschema sagen. Das wird uns erlauben, unseren DataFrame korrekt aus diesen CSV-Daten zu konstruieren. Und dann wie zuvor konvertieren wir dies explizit in ein Dataset mit einer hartcodierten Kompilierungszeitstruktur, die in der Temperaturfallklasse lebt. Also nochmal, Sie sehen den Unterschied hier. Wir ziehen tatsächlich das Schema zur Laufzeit noch ab, da wir dieses Schema zur Laufzeit als Struktur definieren. Während wir Punkt als Temperatur zur Kompilierzeit sagen, wissen
wir, was dieses Temperaturobjekt ist und Spark mehr Optimierungen vornehmen kann, geben Sie uns Kompilierungsfehler anstelle von Laufzeitfehlern. Es scheint also ein zusätzlicher Schritt zu sein, der vielleicht nicht notwendig ist, aber wir bekommen daraus einen Vorteil. Also, jetzt gehen wir zurück und machen das gleiche, was wir
zuvor mit RDD's gemacht haben , aber mit einem Datensatz. Das erste, was wir tun werden, ist, alles herauszufiltern, was kein Team im Eintrag ist. Anstatt Filter für eine RDD zu verwenden, verwenden
wir einfach Filter für das Dataset. Und wir verwenden diese Syntax hier, Dollarzeichen wieder vor dem Spaltennamen. Also wollen wir die Spalte des Measuretyps testen und sehen, ob sie gleich T min ist. Und wieder, in diesen Filteranweisungen, ist
die Syntax ein wenig ungewöhnlich für die Gleichheit. Es sind drei Gleichheitszeichen. Dadurch wird ein neues MR1-Zelt-Dataset erstellt, das nur Team-Inlines enthält. Als nächstes möchten wir einfach die Spalten auswählen, die wir brauchen. Es gibt eine Menge Sachen, die wir nicht brauchen, wie die spezifischen Termine, weil wir nur das Minimum über das ganze Jahr suchen. Uns ist es egal, wann das passiert ist. Also werden wir nur eine Auswahl mit einer Liste der Spalten machen, die wir wollen. Stations-ID, Komma Temperatur. Das ist alles, was wir bewahren müssen. Jetzt kommen wir in das Fleisch der Dinge. Wir werden sie gruppieren und das Minimum finden. So gruppieren nach Stations-ID alle Einträge für eindeutige Stations-IDs zusammen. Und es sollten nur noch zwei davon in diesem Datensatz übrig sein. Und wenn wir diese Gruppen haben, rufen
wir außerdem Min an, um den minimalen Eintrag innerhalb jeder Gruppe zu finden, die Temperatursäule zu
betrachten und den Minimalwert
der Temperatur für jede Gruppe von Stations-IDs zu finden . Hab es. Also jetzt haben wir ein Min-Term-Raumstation-Dataset, das nur Station ID und minimale Temperatur
ist. Wir sind fast fertig. Das Letzte, was zu tun ist, diese Temperaturen um zwei Grad Fahrenheit umzuwandeln. Und wir können auch die Ergebnisse sortieren, während wir dabei sind. Das ist also, was hier los ist. Wir machen einen neuen Datensatz namens Min versucht von Station F, weil wir dies in Fahrenheit konvertieren. Und das wird unsere Min mal pro
Stationsdatensatz nehmen und diese Breitenspaltenfunktion darauf anwenden. Dies wird also eine neue Spaltennamentemperatur erzeugen. Das ist eigentlich anders als das, mit dem wir hier angefangen haben. Mit Spalte kann also entweder eine vorhandene Spalte ersetzen oder eine neue erstellen. In diesem Fall erstellen wir tatsächlich eine neue, weil mit vielen Versuchen nach Station,
alles, was wir von diesem Gruppen-BY-Befehl erhalten, ist die Station-ID und eine neue Spalte, die Min bei Temperatur mit Temperatur in Klammern genannt wird. Also unsere Temperatursäule, die wir ursprünglich hatten, ist
es tatsächlich in den Zustand gegangen und wir werden es jetzt neu erstellen wir eine neue Temperaturspalte hier mit dem Befehl Breite Spalte erstellen. Also mit Spalte, werden wir unsere neue Säulentemperatur nennen. Und es wird mit dieser Funktion konstruiert werden. Also sahen wir mit Spalte vor, wenn wir über
benutzerdefinierte Funktionen sprachen , das gleiche Konzept hier. Wir verwenden nur keine tatsächliche Funktion, die wir definiert haben. Wir übergeben hier explizit einen Ausdruck. Also fangen wir in der Mitte an. Wir beginnen mit der min temperaturspalte, und das ist, was diese Spalte wurde automatisch benannt, als wir sie mit dem Befehl group BY erstellt haben. So gruppieren durch Gruppieren auf der Min-Temperatur wird eine Min-Temperaturspalte erstellt. Und wenn Sie eine Show auf diesem Dataset durchführen würden, während Sie Dinge debuggen, hätten
Sie diesen Spaltennamen gesehen. Alternativ hätten wir Alias dazu aufrufen können, um ihm
einen expliziteren Namen zu geben , auf den wir später verweisen könnten, aber wir haben es nicht getan. Also werden wir nur diesen Standardnamen hier verwenden. Also werden wir das nehmen, multiplizieren es mit 0,1. Das wird das Rohdatenformat in tatsächliche Grad Celsius konvertieren. Und dann wandeln wir das in Fahrenheit um, indem wir mit neun Fünfteln multiplizieren und 32 hinzufügen. Darüber hinaus wird dies in der runden Funktion hier leben. Parameter von zwei, was bedeutet, dass wir das auf zwei Dezimalstellen der Genauigkeit runden wollen. Okay, das wird also wieder eine neue Temperatursäule erzeugen, wobei unsere Temperatur in Fahrenheit auf zwei Dezimalstellen gerundet wird. Darüber hinaus werden wir die Daten auswählen, die wir benötigen,
so dass wir diese Min-Temperatursäule nicht mehr benötigen. Wir wollen nur die konvertierte endgültige Fahrenheit Spalte statt. Wir werden also
die Stations-ID und die Temperaturspalten auswählen , denn das ist alles, was wir am Ende anzeigen möchten. Und schließlich werden wir es nach Temperatur sortieren, so dass wir diese Ergebnisse nach Temperatur sortieren, der Mindesttemperatur, die bei jedem beobachtet wurde. Schließlich werden wir diese Ergebnisse sammeln, genau wie Sie es mit einem RDD gemacht hätten. Und an dieser Stelle befinden sich alle unsere Daten wieder in unserem Treiberskript und wir leben wieder in der Welt von Scala. Also gehen wir hier einfach den Scala-Code durch durchlaufen alle Ergebnisse in unserer Ergebnismenge. Extrahieren Sie die ersten, zweiten Elemente des Tupels, nennen Sie es Station in temp. Darüber hinaus werden wir die Temperatur explizit als Gleitkommawert abgeben. Wir können das dann mit dem Druck-F-Operator hier formatieren. Und schließlich drucken Sie Zeile die tatsächlichen Ergebnisse mit dem Substitutionsoperator, wie wir über weit zurück in unserem Scala Crashkurs gesprochen. Also lasst uns es laufen und uns davon überzeugen, dass es funktioniert. Klicken Sie mit der rechten Maustaste, führen Sie Min temperaturen Dataset aus, und aus. Und es hat funktioniert. Großartig. So haben wir unsere beiden Wetterstationen dort mit ihren minimalen Temperaturen in Fahrenheit auf zwei Dezimalstellen gerundet. Wu es hat funktioniert. In Ordnung, also ja, wenn Sie ein bisschen eine zusätzliche Herausforderung wollen, können
Sie voran gehen und versuchen, dies zu modifizieren, um maximale Temperaturen zu machen und
eine Mindesttemperatur zu setzen , nur um Ihre Hände auf ein wenig mehr sollte trivial sein. Also bin ich nicht einmal gegangen, um Ihnen eine Lösung dafür zu bieten. Aber wenn Sie mit diesem etwas mehr herumspielen wollen, ermutige
ich es sicherlich.
28. [Übung ] Umsetzung des Problem von Kunden, um den Kunden“ mit Datensätzen: Lassen Sie uns also diesen Abschnitt
mit einer anderen Übung und einer anderen praktischen Herausforderung zusammenfassen . Was wir tun werden, ist auf die Übung aus dem vorherigen Abschnitt zurückzugehen, wo wir die Summe berechnet haben, die vom Kunden in unserem gefälschten E-Commerce-Datensatz ausgegeben wurde. Und wir werden das mit Datensätzen anstelle von RDDs überprüfen,
wahrscheinlich sah, dass man nach Hause kam. Um zusammenzufassen, was wir tun werden, ist
die Summe, die der Kunde in unserem Datensatz ausgegeben hat, hier addieren , die Rohdaten, das CSV-Format. Und es enthält drei Spalten, eine Benutzer-ID und Artikel-ID und einen Preis, der für diesen Artikel bezahlt wird. Was ich tun möchte, ist den gesamten Betrag, der durch Benutzer-ID bezahlt wird, zu addieren. Also in diesem einfachen Beispiel wieder, Benutzer-ID 44 verbrachte insgesamt $77,83. Userid 35 verbrachte 7897, und so weiter und so weiter. Unsere Strategie wird also etwas ähneln, wie wir es mit RDDs gemacht haben. Es ist nur die Technik wird ein bisschen anders sein. So werden wir laden die Daten Kundenbestellungen dot CSV-Datei
als Datenrahmen mit acht expliziten Schema wird der einfachste Weg sein, es zu tun. Und Sie können festlegen, dass diese explizit in ein Dataset konvertiert werden soll, wenn Sie möchten. Offensichtlich wird das manchmal zu einer besseren Leistung führen, aber Sie müssen es nicht tun. Danach werden wir diesen Datensatz nach Kunden-ID gruppieren. Sie summieren es nach dem Betrag, den Sie mit der Kundennummer ausgegeben haben. Und wenn Sie Bonuspunkte wollen,
nicht, dass jemand wirklich Punktzahl hält. Sie können das auf zwei Dezimalstellen runden, während Sie gerade sind, sortiert nach dem Gesamtbetrag. So können wir auch unsere Top-Spender und billigsten Kunden sehen und dann die Ergebnisse zeigen. Und ein paar nützliche Snippets, wenn Sie einige weitere Hinweise hier wollen, überprüfen Sie die vorherigen Beispiele in diesem Abschnitt, wir sicherlich hilfreich sein. Und es gibt eine SQL-Funktion namens sum, die Sie verwenden können, um Dinge hinzuzufügen, nachdem Sie sie gruppiert haben. Und speziell die Syntax für eine Rundung, die nach dem Summieren wie AG aussehen wird, runden einige, egal wie der Spaltenname es ist, Sie summieren Komma tubal Runde auf zwei Dezimalstellen. So wenig, kleiner Betrüger da. Und ja, diese Lösung ist in den Kursmaterialien. Bitte widerstehen Sie der Versuchung, zu blicken und nach vorne zu schauen. Probieren Sie das selbst aus und sehen Sie, ob Sie es ausarbeiten können. Es ist eine gute Praxis. Und ich komme zurück und gehe in der nächsten Vorlesung durch meine Lösung.
29. Exercise Gesamtaufwand vom Kunden mit Datensätzen: Ich hoffe, Sie hatten einen gewissen Erfolg bei der Durchführung dieser Übung und beim Neuerstellen unseres Gesamtbetrags, der von Kundenaktivitäten mithilfe von Datasets ausgegeben wurde. Werfen wir einen Blick auf meine Lösung und Sie können meinen Ansatz mit Ihrem vergleichen. Öffnen Sie hier die Gesamtsumme, die von Kunden sortiert Dataset-Skript ausgegeben wurde. Und wieder, Sie wissen Ihren, Ihr Code muss nicht genau wie meins sein. Was zählt, ist das Endergebnis wirklich da, es gibt viele Möglichkeiten, es zu tun. Also beginnen wir mit dem Importieren der Dinge, die
wir brauchen, und wir erstellen ein Objekt namens Gesamt ausgegeben von Kunden sortierten Datensatz und beginnen mit einer Fallklasse,
die das Schema definiert , in das unser Datensatz gezwungen wird. Wir sagen also explizit zur Kompilierzeit, dass unser Kundenbestellen-Datensatz eine ganzzahlige Kunden-ID und ganzzahlige Artikel-ID und einen ausgegebenen Betrag mit doppelter Genauigkeit
enthalten wird. Dann gehen Sie in meine Hauptfunktion hier und wir richten unsere Spark-Sitzung ein, wie wir es immer tun. Und wir werden ein Schema für die Verwendung mit
dem Lesen in der CSV-Datei als DataFrame erstellen. Wir werden also ein Kundenbestellschema erstellen,
das heißt, Sie wissen schon, ähnlich wie ein vorheriger Code aussieht, den wir uns angesehen haben. Also hoffentlich konnten Sie das heben, erstellen
Sie einen neuen StructType und fügen Sie eine Kunden-ID vom Typ Integer-Element-ID des Integer-Betrags vom Typ Double hinzu. Und dann lesen wir das tatsächlich vor der CSV-Datei hier mit
dem Schema, das wir zur Verfügung gestellt haben. Und wir werden das in einen Datensatz zwingen, die Kundenbestellungen Fallklasse
verwenden, wie wir es zuvor getan haben. Jetzt kommen wir in das Fleisch der Übung. Hier erstellen wir eine neue Gesamtsumme nach Kundendatensatz, die so ziemlich alles macht. Wir beginnen mit der Gruppierung nach dem Kunden-ID-Feld. Und denken Sie daran, dass wir diesen Namen hier oben in unserer Fallklasse definieren, dieser Name muss mit dem hier oben übereinstimmen. Indem wir nach Kunden-ID gruppieren, gruppieren
wir alle verschiedenen Einkäufe für jeden Kunden zusammen. Und dann ist diese nächste Zeile, was eigentlich alle zusammenfasst. Also fangen wir von der Mitte an und arbeiten uns raus. Wir beginnen mit der Summe Unterstrich verbracht Spalte summieren. Daher werden
wir für jede eindeutige Kunden-ID alle Beträge zusammenfassen, die Spence mit dieser Kunden-ID verknüpft ist. Und das wird weiter von einer runden Funktion umschlossen, um diese auf zwei Dezimalstellen mit Genauigkeit zu
runden. Wir werden Punkteeis verwenden, um dieses Ergebnis
in einer einzigen Spalte im Endergebnis zu aggregieren . Und wir werden diesen neuen Spaltennamen geben, indem wir Punkt-Alias sagen, Gesamtunterstrich ausgegeben, um es einfacher zu verweisen. Weil wir ihm einen Namen geben müssen, um ihn einordnen zu können, oder? Also erkenne ich, dass diese AGG-Funktion ein wenig verwirrend sein kann. Im Grunde, was es tut, ist zu sagen, dass wir diese Funktionen in einer einzigen Spalte zusammenfassen werden, okay? Und wir werden dieser Spalte auch einen Namen mit Punkt-Alias geben. Zu diesem Zeitpunkt wird die Struktur unseres Datensatzes
eine Kunden-ID-Spalte und eine Gesamtunterstrich ausgegeben Spalte sein . Jetzt können wir es sortieren, indem wir einfach Punkt sortieren mit
dem gesamten Unterstrich verbrachte Spaltennamen sagen , die wir
in der vorherigen Zeile angegeben haben und die Ergebnisse wieder anzeigen, Gründe wenig Trick, um die Gesamtsumme von wie vielen Zeilen in der Summe nach Kundendatensatz, konvertiert diese in eine Ganzzahl und übergibt diese als Parameter an die Show-Funktion, um sicherzustellen, dass wir explizit das gesamte Dataset und nicht nur die ersten 20 Zeilen anzeigen. Also lasst uns weitermachen und das losgehen. Und da haben wir. Es sieht so aus, als hätte es funktioniert. Es sieht so aus, als ob die Ergebnisse nach ausgegebener Menge sortiert sind. Also unser größter Spender war UserID 68, der $6.375,45 ausgab. Sehr cool. In Ordnung. Ich hoffe, es hat dir gefallen und du hättest vielleicht noch weiter gegangen. Ich meine, ich hätte dies einen Schritt weiter machen können, indem ich das zu einem Punkt 24-Beispiel erzwinge.
Ich verwende ein Druck-f-Format, um tatsächlich
jede einzelne Zeile zu durchlaufen , die zurückgesendet wurde, und die Ausgabe mehr nach meinen Wünschen zu formatieren. Aber ja, wenn du das tust, Bonuspunkte für dich. Aber hey, hoffe, du hast das durchgemacht. Also haben wir CAD Einführung in Datensätze und wie sie auf ziemlich hohem Niveau arbeiten, es gibt mehr zu erkunden, ich sollte hinzufügen. Es gibt viel mehr zu Apache Spark, als ich in diesem Kurs abdecken kann. Also, wenn Sie jemals in der Dokumentation für
den vollständigen Satz von Referenz auf, was Sie tun können, verweisen möchten. Sie können zu Spark dot apache.org slash docs
slash neueste gehen , um die neueste Dokumentation zu erhalten. Wenn Sie beispielsweise alles, was Sie mit dem Dataset tun können, durchbohren möchten, können
Sie einfach zur Organisation navigieren. Apache Spark. SQL-Dataset wird der Pfad für diesen Klassennamen sein. Und es wird Ihnen alles darüber in jedem komplizierten Detail erzählen. Wenn Sie nach unten scrollen, sehen Sie einige Beispiele, die noch nützlicher sind. Und Sie können eine Liste aller Methoden sehen, die im Dataset verfügbar sind. Die meisten von ihnen werden vertraut aussehen. Wir haben eine Menge von ihnen abgedeckt. Beispiel: Sammeln und Zählen für jede Anwendung einer Funktion auf jede Zeile. Kopf ist eine Möglichkeit, die ersten n Zeilen des Datensatzes zu erhalten, zeigen, dass wir das viel verwendet haben, oder? Take kann auch verwendet werden, um eine bestimmte Anzahl von Zeilen aus dem Dataset zu nehmen. Es gibt auch einige andere Dinge, die man hier erkunden kann. Sie können tatsächlich erklären, um die tatsächliche Art und Weise zu erklären, wie es ausgeführt wird, was für Debugging-Zwecke interessant ist. Es gibt Möglichkeiten, es auf einer Festplatte zu speichern. Es gibt eine Möglichkeit, es in eine RDD zu konvertieren. Wir sahen uns das ein bisschen an. Wir können das Schema ausdrucken. Das haben wir schon mal gemacht. Wir können es tatsächlich auch in einen DataFrame konvertieren, wenn wir wollen, sowie eine richtige Funktion, um es auf der Festplatte zu speichern. Und wir werden später über Streaming reden, wir werden später darauf kommen. Und es gibt andere Dinge hier, wie verschiedene Operationen wie unterschiedlich, um nur eindeutige Werte im Dataset zu erhalten. Wir haben uns Filter vorher angesehen, wir haben über FlatMap gesprochen. Sie können dies sowohl auf ein Dataset als auch auf
einen RDD GroupByKey anwenden , von dem wir über Join-Schnittpunkte gesprochen haben. Sie können dort einige boolesche Operationen durchführen, um Mapping. Sie können das auf einem Dataset genau so tun, wie Sie es auf einer RDD tun können, obwohl es mit einem Dataset etwas umständlicher wird. Und ja, geh einfach weiter und angeln durch das, wenn du jemals
ein vollständigeres Beispiel dafür bekommen willst , was du tun kannst und was verfügbar ist. Und wenn Sie Fragen zu der Syntax und den Parametern haben , die für diese Dataset-Funktionen unterstützt werden. Dies ist der Ort, an dem Sie sich wenden können, um es herauszufinden. Wie Sie sehen können, gibt es eine lange Liste dessen, was Sie für den Datensatz tun können. Wir haben einige der häufigsten Dinge angesprochen, die Sie tun können. Aber wie Sie sehen können, gibt es hier eine ganze Speisekarte. Daher werden wir während des gesamten Kurses weiterhin Datasets verwenden. Beachten Sie auch, dass es in Ihren Kursmaterialien für jede Übung sowohl eine RDD-Version als auch eine Dataset-Version gibt. Also, wenn du die beiden jemals vergleichen willst, sind sie alle da. Wir werden nicht jede einzelne Version jedes einzelnen Skripts durchlaufen. Wie ich schon sagte, wir werden uns von hier an auf Datensätze konzentrieren. Aber wenn Sie jemals neugierig sind, können
Sie sich beide Versionen ansehen. Und es gibt einige, die wir auch nicht angefasst haben. Zum Beispiel unser anfängliches RDD-Beispiel. Es ist auch eine Dataset-Version davon, wenn Sie auch damit spielen möchten. Es ist also alles da für Ihre Referenz und Freude. Und gehen wir weiter zu einigen komplizierteren Beispielen in unserem nächsten Abschnitt.
30. [Aktivität] Finde den beliebtesten Film: Bis zu diesem Punkt im Kurs haben
wir euch Spark vorgestellt und einige ziemlich einfache Beispiele verwendet. Aber ich möchte, dass du siehst, dass Spark eine Menge Macht darüber hinaus hat. Wenn Sie also sogar ein komplizierteres Problem haben,
manchmal, wenn Sie kreativ denken, lösen Sie ungelöste Probleme aus, von denen Sie nicht gedacht hätten, dass es lösen könnte. Und wir werden einige Beispiele wie das im folgenden Abschnitt mit
einigen ziemlich lustigen Beispielen mit Filmdaten und Superhelden-Daten eintauchen . Lassen Sie uns eintauchen und sehen, was Sie mit Spark tun können, die Sie vielleicht
nicht gedacht haben, dass Sie tun könnten, wenn Sie einfach ein wenig kreativ über Ihre Probleme
nachdenken. Okay, Also ich weiß, dass der Name dieses Abschnitts fortgeschrittenere Beispiele für Apache Spark ist, aber wir müssen mit etwas Einfaches beginnen und unseren Weg nach oben arbeiten. Also, um den Grundstein für dieses nächste Beispiel zu setzen, werden wir etwas Leichtes tun. Wir werden den beliebtesten Film im MovieHens Dataset finden. Und um zusammenzufassen, tatsächlich tun, Wir sprachen über Movielens bereits. Wir haben kurz zurück mit der, die Bewertungen Gegenbeispiel. Also werden wir hier den Movielens 100 K Datensatz aufnehmen. Und um das Format zusammenzufassen, enthält
es diese vier Spalten. Sie entsprechen einer Benutzer-ID, Film-ID, einer Bewertung und einem Zeitstempel. Und um den beliebtesten Film zu finden, müssen wir nur die Film-IDs finden, die die meisten Bewertungen haben, oder? Wenn wir also davon ausgehen, dass jemand, der den Film bewertet hat, ihn angesehen hat, und wir definieren populär als den meistgesehenen Film, als indem wir nur die Film-ID finden, die am häufigsten erscheint. In diesem Datensatz finden wir den beliebtesten Film auf diese Weise. Lassen Sie uns also zum Code gehen und sehen, wie wir dies mit Datensätzen tun können. Ziemlich unkompliziert, aber wir werden darauf aufbauen, um etwas
komplizierteres in der nächsten Vorlesung zu tun . Lassen Sie uns also das beliebte Film-Dataset-Skript in Ihren Kursmaterialien erkunden. Und wir werden das durchlaufen. Es ist hier nicht allzu schick, aber auch werden
wir darauf aufbauen, um etwas
tiefer und komplexer in nachfolgenden Vorträgen zu tun . Also fangen wir an, wichtig selbst. Wir brauchen, wie üblich, nennen wir das unser Objekt, populäre Film-Dataset. Wir sind nicht erforderlich Fall Klasse genannt Film. Die Einsicht hier ist, dass alles, was wir tun, ist zu zählen, wie
oft jede Film-ID in unserem Datensatz erscheint. Und um das zu tun, brauchen wir nur die Film-ID-Spalte, richtig? Wir kümmern uns nicht um die Bewertungen. Uns ist egal, wann sie bewertet wurden. Uns ist egal, wer es bewertet hat. Alles, was uns wichtig ist, ist, dass diese Film-ID in jeder einzelnen Zeile angezeigt wird. Das sind also die einzigen Daten, die wir tatsächlich extrahieren müssen, was die Dinge ein bisschen einfacher macht. Eintauchen in unsere Hauptfunktion hier, wir setzen unsere Log-Level, größere SparkSession, nichts Besonderes dort. Wir erstellen unser Film-Schema zum Laden des anfänglichen DataFrame aus der CSV-Datei. Obwohl es sich hier tatsächlich um eine tabulatorgetrennte Wert-Datendatei handelt. Aber das ist in Ordnung. Wir können immer noch den CSV-Lader vorwärts verwenden, wie wir sehen werden. Und wir werden es sagen, die Struktur dieser Daten ist Benutzer-ID, Film-ID, Bewertung und Zeitstempel mit drei ganzen Zahlen und eine lange, um diese Daten darzustellen. Importiert ausgelöste Implikte, um diese CSV mithilfe dieses impliziten Schemas zu laden. Und wir werden laden, beachten Sie den Optionssatz Backslash t. Das sagt dem CSV-Lader, der ein Trennzeichen ist eigentlich kein Komma,
sondern ein Tabulatorzeichen,
das ist, was diese Daten tatsächlich formatiert sind sondern ein Tabulatorzeichen, , während wir in der -Pfad zur Datendatei, d. h. der Datendatei, die die tatsächlichen Bewertungsinformationen enthält. Und dann werden wir es anschließend in ein Film-Dataset erzwingen. Und indem wir das tun, werfen wir es in
die einzige erste Spalte dort, die nur aus der Film-ID und nichts anderes besteht. So wenig interessanter Trick da. Ihr Dataset muss nicht alle Spalten enthalten, daher ist der DataFrame, aus dem Sie es erstellen. Und jetzt passiert das Fleisch davon in dieser einzigen Zeile. Und es ist sehr SQL ähnlich und wie es sich dem Problem nähert. Also beginnen wir mit der Gruppierung nach Film-IDs. Also haben wir gerade alle Bewertungen für jede Film-ID zusammengefasst. Dann zählen wir sie alle auf. Und dann ist die Reihenfolge im Grunde, wie Sie eine Sortierung in SQL durchführen, so dass es dasselbe tut. Wir sagen im Grunde Reihenfolge BY der Zählspalte, die von dieser Funktion dort erstellt werden wird. Und in absteigender Reihenfolge, damit wir unsere beliebtesten Filme oben auf der Liste und unsere am wenigsten populären am Ende der Liste bekommen. Danach werden wir
die Top Ten Ergebnisse zeigen , und das sollte uns unsere Top 10 beliebtesten Filme geben. Also lasst uns das loslegen und sehen, was wir bekommen. Okay, da haben wir unsere Ergebnisse und es scheint, als hätte es funktioniert. Der populärste Film ist also der Film ID 550, mit 583 unterschiedlichen Bewertungen, die mit diesem Film verbunden sind. Aber das ist nicht furchtbar hilfreich, oder? Woher wissen wir, was Film ID 50 ist? Ein offensichtlicher nächster Schritt, um dieses Skript zu erweitern, wäre also,
den Filmnamen zu importieren , der mit jeder Film-ID verknüpft ist
, damit wir tatsächlich einen Einblick in das bekommen können, was diese Filme sind. Ich meine, wir könnten es auf die harte Weise tun, wie diese Daten in der Artikeldatei in unserem Datensatz leben. Wenn wir das öffnen, um zu erkunden, was da drin ist, können
Sie sehen, dass dies alle möglichen zusätzlichen Informationen über jede Film-ID enthält. So zum Beispiel, Film ID eins ist der Film Toy Story und es sagt Ihnen, dass das Jahr veröffentlicht wurde, verknüpft mit IMDB-Daten von ihm. Und diese Nullen und Nullen entsprechen tatsächlich den Genres, in denen sich der Film befindet. Und wenn Sie auf Film ID 50 gehen, werden
wir sehen, dass unser Gewinner tatsächlich Star Wars ist, der Original von 1977. Nicht zu überraschend. Aber ja, wir wissen es nicht. Wir wollen die nicht mit der Hand nachsehen müssen, richtig. Also lasst uns zurückkommen und darüber reden, wie wir das tatsächlich mit unseren Film-Namen Daten verbinden können. Und wie man das optimal macht, damit wir diese Daten tatsächlich an jeden Knoten in unserem Cluster
verteilen können .
31. [Aktivität] Den Broadcast zum Anzeigen von Filmnamen: Deshalb müssen wir diese Ergebnisse für Menschen lesbar machen. Diese Film-IDs sind für uns als
Menschen nicht wirklich nützlich , weil wir nicht wissen, was der Film sagt. Es gibt also keine Intuition, die man gewinnen kann. Lassen Sie uns jetzt auf dieses Problem aufpassen. Wir wollen also die Filmnamen und nicht nur die IDs anzeigen. Und dazu müssen wir Informationen aus dieser
u-Punkt-Elementdatei aus dem MoviElens-Dataset zusammenführen . Jetzt gibt es viele Möglichkeiten, dies zu tun. Am einfachsten wäre es, einfach ein anderes Dataset einzurichten, das IDs Namen nach dem Parsen in dieser u-Punkt-Elementdatei
zuordnet. Und dann können wir diesen Datensatz einfach mit unserem Bewertungsdatensatz durch die Film-IDs verbinden und diese Filmnamen auf diese Weise mitmachen. Das wäre die einfachste Art, es zu tun. Und von einem SQL-Standpunkt würden Sie sich so auch diesem Problem nähern. Aber das ist nicht der einzige Weg, es zu tun. kannst du nicht tun. In der Tat ermutige
ich Sie, dass einen Versuch zu geben, wenn Sie
eine kleine praktische Übung zum Üben wollen . Aber wir werden es auf eine andere Weise tun. Da ein Join wie ein Dataset über den Cluster verteilt wird, ist
das eine ziemlich schwere Operation. Und es ist nicht völlig notwendig für diese Daten, oder? Weil es nicht so viele Filme auf der Welt gibt. Die Tabelle der Film-IDs zu Filmnamen ist eigentlich nicht so groß. Wir können all das im Speicher ganz einfach auf einen einzelnen Computer passen, also müssen wir das nicht wirklich in einem Dataset verteilen. Also könnten wir einfach eine Tabelle im
Treiberprogramm laden und diese verwenden, um die IDs auch zuzuordnen. Filmnamen, wie wir sie ausdrucken. Das wird gut. Aber es gibt eine andere Möglichkeit, zwei zu machen. So könnten wir Spark auch automatisch für jeden Executor lassen, wenn nötig. Stellen Sie sich also vor, wenn Sie so wollen, dass wir diese Filmnamen innerhalb
des Treiberskripts selbst haben müssen und nicht nur für die letzte Ausgabephase. Wir können tatsächlich, es gibt eine Möglichkeit, mit dem, was wir
Broadcast-Variablen nennen , ein Objekt weiterzuleiten,
das eine Karte enthalten kann , die Film-IDs zuordnen kann, um zum Beispiel die Namen zu verschieben, und das automatisch an jeden Executor innerhalb unser Cluster nach Bedarf verwendet werden. Und wissen Sie, wenn die Tabelle massiv ist, könnte
dies eine wichtige Sache sein, diese Broadcasts-Variablen zu verwenden, denn das wird sicherstellen, dass wir sie nur an jeden Executor übertragen und dort aufbewahren. Vergleichen Sie das mit einem Dataset, in dem es möglicherweise überall geworfen wird. Es ist ein bisschen eher eine komplexe Operation. Durch die Verwendung einer Broadcast-Variablen können
wir sicherstellen, dass diese Tabelle, diese Karte von Informationen, die IDs zu Namen zuordnet, nur über will an jeden Executor gesendet wird, und sie bleibt dort, bis wir sie explizit loswerden. Mit Broadcast-Variablen können
wir jedes Objekt an
alle Executoren übertragen , so dass sie immer da sind, wann immer nötig. Wir müssen nur Broadcast auf dem Spark-Kontextobjekt in
unserem Treiberskript aufrufen , um diese Daten zu versenden,
was Sie an jeden Executor Knoten versenden wollten. Wir müssen nur sicherstellen, dass es in ihre Erinnerung passt offensichtlich. Und dann, nachdem das ausgestrahlt wurde, können
wir Punktwert auf dieser Broadcast-Variable verwenden, um es abzurufen und dieses Objekt zurück zu erhalten und innerhalb des Skripts, das im gesamten Cluster verteilt wird, darauf zu verweisen. Und wir können diese ausgestrahlten Objekte verwenden, wie Sie möchten. Sie können sie innerhalb von Kartenfunktionen in RDDs verwenden oder in unserem Fall möchten
wir sie auf Datasets anwenden, was bedeutet, dass wir eine benutzerdefinierte Funktion einrichten werden, damit wir sie in einer Art SQL-ESC-Art verwenden können. Lassen Sie uns also zum Code eintauchen und sehen, wie Broadcast-Variablen funktionieren. Also lassen Sie uns die beliebten Filme
schöner Dataset-Skript hier öffnen und sehen, wie das aussieht. Auch hier wäre die einfachere Methode, dieses Problem zu
behandeln, ein Dataset
von Film-IDs in Filmnamen zu laden und diese in einer Art SQL-Operation zu verbinden. Aber wir werden es auf ein wenig andere Weise tun, weil wir wissen, dass dies ein relativ kleiner Datensatz ist, und wir können damit davonkommen , dass
nur an jeden einzelnen Executor zu liefern, wenn unser Skript startet und einfach darauf verweisen lokal innerhalb jedes Executor-Knotens. Es ist also nur eine andere Art, es zu tun. Manchmal können Broadcast-Variablen so nützlich sein, dass Sie sie nicht wirklich so oft in der Praxis verwendet sehen, um ehrlich zu sein, aber es ist ein Werkzeug in Ihrer Werkzeugkiste, von dem Sie wissen sollten. Und das gibt uns auch die Möglichkeit,
die Verwendung von benutzerdefinierten Funktionen in einem Datensatz zu veranschaulichen , was auch gut zu wissen ist. Obwohl dies ein bisschen ein erfundenes Beispiel ist, veranschaulicht
es ein paar wichtige Punkte. Also lasst uns hier in den Code eintauchen. Wir importieren alles, was wir brauchen. Und wir werden eine vollständige Fallklasse
aus dem Film-Datentyp hier einrichten , die die Benutzer-ID,
Film-ID-Bewertung und Zeitstempel enthält , die aus der u dot Datendatei importiert werden. Wir werden dann eine Load Film-Namen Funktion erstellen. Und der Zweck dieser Funktion ist nur,
eine Scala-Karte zu erstellen , die Film-IDs Filmnamen zuordnet. Das ist also nur gerade Scala-Code. Es ist kein Spark-Code. Alles, was es tut, ist, diesen u dot item Ordner mit der richtigen Zeichencodierung zu laden , was übrigens ein wenig obskur ist. Und wir geben eine Karte von Ganzzahlen zu Strings zurück, die Film-IDs Filmnamen zuordnet. Wir laden die Datei einfach direkt von der Festplatte, durchlaufen jede Zeile in dieser Datei teilen sie basierend auf diesem Pipe-Zeichen auf, das sie begrenzt. Und wir machen eine kleine Vernunft Check, um sicherzustellen, dass es eine gültige Zeile ist. Und wenn ja, fügen wir zu unserer Filmnamen Karte und Eintrag hinzu, dass das erste Feld, das ist die Film-ID auf das zweite Feld, das ist der Filmname. Schließen Sie die Datei, wenn wir fertig sind, und geben Sie die resultierende Filmnamen Karte. Also wieder, das ist kein Spark-Code, das ist nur gerade Scala-Code, der diese Daten von der lokalen Festplatte
liest, von wo auch immer wir sind, wir führen unser Treiberskript aus. Also lasst uns in das eigentliche Skript selbst einsteigen. Wie üblich beginnen wir mit unserem Log-Level und richten ein SparkSession-Objekt ein. Und jetzt werden wir diese
Funktion zum Laden von Filmnamen aufrufen, um diese Karte von Film-IDs in Filmnamen zu laden. Und wir werden Broadcast von unserer Spark-Kontext-Schnittstelle anrufen. Und wir werden diese resultierende Broadcast-Variable namens es kurz für Namenswörterbuch nennen, macht Sinn, richtig? Also zu diesem Zeitpunkt wurde diese Karte geladen und sie wurde an
alle Executoren gesendet , die unsere Spark-Anwendung hier ausführen werden. So wird es jedem Executor
lokal zur Verfügung stehen , schnelle Nachschlagen von Film-IDs zu Filmnamen durchzuführen. Alles klar, jetzt kommen wir in den Spark-Code selbst. Wir werden unsere Film-Daten mit dem folgenden Schema laden. Also werden wir die Datendatei laden, die das Tab-Trennzeichen angibt. Auch hier ist dies der gleiche genaue Code aus dem vorherigen Beispiel und mit dem Schema, das wir bereitstellen. Und dann werden wir es in die Film-Fallklasse zwingen, um den vollständigen Inhalt der Daten dieses Films so definiert zu bekommen. In Ordnung, weiter, wir werden dann die Anzahl der Bewertungen pro,
pro Film-ID bekommen, genau wie wir es vorher mit den einfachen Gruppen-BY-Anweisungen getan haben. Also werden wir nach der Film-ID-Spalte gruppieren und jede einzelne Film-ID
zählen, wie oft sie auftritt. An dieser Stelle haben wir das, was wir vorher hatten. Wir haben ein Film-Zähldatensatz, das
Film-ID und Anzahl für jede einzelne Film-ID enthält . Also, jetzt brauchen wir eine Möglichkeit, diese Film-IDs tatsächlich in Filmnamen innerhalb unseres Datensatzes
umzuwandeln. Also wieder, dies ist ein erfundenes Beispiel. Du hättest das genauso einfach in der Ausgangsphase machen können, oder? Und wir hätten das resultierende Dataset, das wir zurückerhalten haben, durchlaufen und diese Filmnamen lokal
im Treiberskript
nachschlagen können, wenn wir die Ergebnisse tatsächlich drucken. Aber wir versuchen nur, die Verwendung von UDFs hier und Broadcast-Variablen zu veranschaulichen. Also werden wir dies tatsächlich innerhalb des Clusters selbst tun. Also für jeden Executor, der eine Teilmenge der Filme, eine
Teilmenge von Film-IDs für dieses Problem behandelt , werden
sie einzeln die Filmtitel für die Film-IDs betrachten. Sie sind dafür verantwortlich, etwas skalierbarer zu sein, oder? Um dies zu tun, müssen wir zuerst
eine benutzerdefinierte Funktionen einrichten , so dass wir tatsächlich einen Datensatz Befehl
einrichten können, um eine neue Spalte mit dieser Funktion zu erstellen, um die Daten dieser Spalte zu generieren. Jetzt ist die Syntax dafür ein wenig seltsam, also haben wir das noch nicht gesehen. Wir deklarieren hier, was eine anonyme Funktion genannt wird. Und in Scala sieht die Syntax dafür so aus. Also definieren wir hier im Grunde eine Inline-Funktion. Wir werden es Nachschlagenamen nennen. Das ist der Name unseres, unserer Funktion. Wir sagen, dass es eine ganze Zahl nehmen und eine Zeichenfolge zurückgeben wird. Und wir werden das gleich dieser folgenden anonymen Funktion setzen. Es nimmt also eine ganze Zahl namens Movie-ID ein und geht in diesen Codeblock aus, der nur
die Suche nach dem Namenswörterbuch zurückgibt, da diese Film-ID angegeben ist,
notieren Sie den Punktwert, so dass er wieder als Broadcast-Variable benannt wird. Es ist nicht die eigentliche Karte. Um das Map-Objekt zurück zu bekommen, müssen wir den
Punktwert aufrufen wollte, um den Namen Dick Objekt abzurufen. Also wieder, benannte dict ist die Broadcast-Variable. Um seinen Inhalt zu erhalten, müssen
wir Wert darauf aufrufen. Also an dieser Stelle haben wir eine tatsächliche Scala-Karte zu verwenden. Und dann können wir einfach Film-ID übergeben, um
nachzusehen , was der Filmname mit dieser Film-ID verknüpft ist. Als nächstes müssen wir diese Funktion mit einem UDF umschließen. So können Sie oben hier notieren, die wir explizit importiert haben. Hier ist es, oder Punkt Apache Punkt Spark dot SQL dot functions.php UDF. Und das erlaubt uns, diese Funktion tatsächlich
als benutzerdefinierte Funktion zu umschließen , die wir dann in einer SQL-Einstellung verwenden können. Also, jetzt, da wir Lookup-Namen UDF haben, können wir es verwenden. Und hier ist, wo die Magie passiert. Also sagen wir Filme mit Namen. Dies wird unser neuer Datensatz sein, der eine zusätzliche Spalte namens Filmtitel hat. Und um diese Spalte hinzuzufügen, werden wir nur sagen, Film zählt Punktbreite Spalte. Um diese neue Spalte zu diesem Dataset hinzuzufügen, rufen
wir diesen neuen Spaltenfilmtitel auf. Und der Inhalt dieser Spalte wird mit dem Nachschlagenamen UDF generiert, dieser benutzerdefinierten Funktion, die wir gerade definiert haben. Und die Parameter dafür werden aus der Film-ID-Spalte kommen. Die Syntax hier besteht also darin, die Aufruffunktion zu verwenden, die von
SQL-Punkt-Funktionen kommt , um den Inhalt eines bestimmten Spaltennamens,
in diesem Fall Film-ID, tatsächlich zu übergeben . Und weil wir das mit einem UDF umschließen, akzeptiert
es diese Spalte und transformiert sie in
die ganze Zahl, die die eigentliche zugrunde liegende Funktion für Sie erwartet. Das ist also, wo alles passiert. eine verteilte Art und Weise über den gesamten Cluster, wird
es unsere benutzerdefinierte Funktion verwenden, indem wir unsere Broadcast-Karte verwenden, um
Film-IDs zu Filmnamen zu suchen und einen neuen Datensatz namens Filme mit Namen zu generieren. An diesem Punkt können wir es dann erneut
über den gesamten Cluster basierend auf dem Zählfeld sortieren . Und an diesem Punkt können wir einfach die Ergebnisse abrufen und sie zeigen. In diesem Fall werden wir nur
die ganze Sache zeigen , weil wir vielleicht in alle Details davon graben wollen. Und so werden wir nur als Parameter übergeben, die gesamte Liste, die Anzahl D2 und die jede einzelne Zeile dieses Datensatzes zu erhalten. Und darüber hinaus werden wir sagen, abschneiden gleich falsch, um zu verhindern, dass es tatsächlich die Länge jeder einzelnen Zeile abschneidet. Andernfalls würde es einige dieser Filmnamen abschneiden, um in eine bestimmte Zeilenbreite zu passen. Also lasst uns das loslegen und sehen, was passiert. Und da haben wir es. Also haben wir in diesem Fall keine absteigende Sortierung gemacht, wir sind eigentlich nur Endungen. Am häufigsten werden
die beliebtesten Filme in diesem Fall am Ende sein. Und wir haben das gleiche Ergebnis. Star Wars ist, werden Film gelehrt, gefolgt von Kontakt, gefolgt von Fargo, gefolgt von Rückkehr der Jedi. Sie können feststellen, dass dies definitiv ein datierter Datensatz ist. Es gibt mehr aktuelle, die Sie von
MoveLens bekommen können , wenn Sie mit ihnen experimentieren möchten. Also denken Sie daran, dass dies alte Daten sind, also seien Sie nicht überrascht, dass in der Nähe von Lieblings-Blockbustern und hier auftauchen. Aber ja, es funktioniert. Also wieder ein bisschen ein künstliches Beispiel,
aber der Punkt war, Sie über Broadcast-Variablen und benutzerdefinierte Funktionen zu lehren. Auch hier können Sie oft erreichen, was wir mit
einer Broadcast-Variablen tun müssen , indem Sie stattdessen ein Dataset verwenden. Aber manchmal wird eine Broadcast-Variable effizienter sein. Es ist also ein weiteres Werkzeug in deiner Werkzeugkiste und jetzt hast du es. Lasst uns weitermachen.
32. [Aktivität] Finde den populärsten Superhero in einer sozialen Diagramm: In unseren nächsten Vorträgen werden wir uns einen ziemlich lustigen Datensatz ansehen. Es basiert eigentlich auf
dem Marvel-Comic-Universum ist ein Marvell oder Marvell und jeder wusste, wie man das ausspricht. Aber wie auch immer, wir reden über Superhelden wie Spiderman und Thor und alle auf der ganzen Welt dort. Und es stellt sich heraus, dass man sich die Welt der Superhelden als ein bisschen soziales Netzwerk vorstellen kann. Der Datensatz, mit dem wir arbeiten werden, ist irgendwie interessant. Es modelliert Superhelden als ein Netzwerk von Superhelden, indem
sie in einem einzigen Comicbuch die anderen Superhelden betrachten , mit denen jeder Held auftauchte. Also, wenn Sie Spiderman in demselben Comic wie Thor erscheinen
lassen, dann würden wir sagen, es gibt eine Verbindung zwischen Spider-Man und gründlich, zum Beispiel. Und es stellt sich heraus, dass es viele dieser Arten von Helden im selben Comicbuch
gibt. Und es führt zu dieser wirklich interessanten Netzwerkstruktur zwischen all diesen Helden im Marvel-Universum. Also haben wir eigentlich einen ziemlich coolen öffentlichen Datensatz da draußen. Und es enthält die beiden Dateien, an denen wir interessiert sind. Einer wird Marvell gestrichelter Graph Punkttext genannt. Und was wir getan haben, ist, dass wir
jedem einzelnen Charakter, der in diesen Comicbüchern erscheint, eine ID zugewiesen haben . Die erste Zahl, die in jeder Zeile erscheint, ist das Zeichen, von dem wir sprechen, gefolgt von einer Liste aller Zeichen-IDs, mit
denen dieser Charakter in anderen Comicbüchern erschienen ist. Also habe ich keine Ahnung, welche Charakter-ID für 395 ist, aber lasst uns einfach so tun, als wäre es Spider-Man. Das würde bedeuten, dass Spider-Man mit den Charakteren 22,
37, 17, 6, 7,
4, 7, 2 und so weiter und so weiter erschienen 37, 17, 6, 7, ist. Und dann können wir nachschlagen, welche Namen mit einzelnen Zeichen-IDs verbunden sind. Wir nennen sie Heldenausweise, wenn du willst. In der Marvel Strichnamen dot txt-Datei ist das sehr einfach. Es ist nur eine ID gefolgt von einem Anführungszeichen eingeschlossenen Namen,
die dieser Helden-ID entspricht. Nun eine Sache, die Sie hier oben stolpern kann, ist, dass ein Held mehrere Zeilen in der Marvel gestrichelten Graph dot txt Datei
überspannen kann . So erscheinen einige Superhelden so oft, dass sie
so viele Ko-Ereignisse mit anderen Helden haben , dass sie nicht alle in einer Zeile passen können. In diesem Fall könnten wir zwei oder mehr Zeilen haben, die mit derselben Helden-ID beginnen würden. So können wir sehen, wie dies aus Sicht der Datenverarbeitung interessant sein könnte. Wir müssen diese zusammen kombinieren, während wir sie irgendwie verarbeiten. Und nun, lassen Sie uns darüber reden, wie das geht. Unsere Herausforderung besteht also darin, herauszufinden, wer der beliebteste Superheld in der Marvel-Comic-Welt ist. Und wir werden populär definieren, wer mit den meisten anderen Superhelden in anderen Comicbüchern
erscheint? Wer ist, wer am meisten in der Comicbuchwelt herumkommt. Hier ist also unsere Strategie, um dieses Problem tatsächlich zu beantworten. Also laden wir unseren Datensatz aus der Datendatei dort. Und das erste, was wir tun werden, ist, die erste Nummer
in jeder Zeile aufzuteilen , denn das ist die Helden-ID, über die wir reden. Mit dieser Linie. Wir werden dann einfach aufzählen wie viele Leerzeichen getrennte Zahlen insgesamt in dieser Zeile sind. Uns ist es egal, wer die Verbindungen sind. Wir zählen sie nur hoch, oder? Und so kümmern wir uns nur darum, wie viele Verbindungen dieser Hero hat. Also, indem wir die Gesamtsumme davon nehmen, wie viele Dinge in dieser Linie sind. Wenn wir nur eine subtrahieren, um
diese anfängliche Helden-ID loszuwerden , die identifiziert, um wen es geht, erhalten
wir die Anzahl der Verbindungen zu
dieser Helden-ID , die durch diese Datenzeile mit mir dargestellt werden. Also werden wir einfach aufzählen. Wie viele andere IDEs befinden sich in dieser Zeile zu dieser Hero-ID, um eine Anzahl davon zu erhalten, wie viele Verbindungen durch diese Datenzeile dargestellt werden. Und wie gesagt, können wir mehrere Zeilen für eine bestimmte Helden-ID haben, was bedeutet, dass wir sie irgendwie miteinander kombinieren müssen. In SQL können wir also einen Gruppen-BY-Befehl oder auf unserem Dataset machen, dass wir einen Gruppen-BY-Befehl ausführen können, um diese insgesamt zu kombinieren. Und dann können wir alle Verbindungen für verschiedene Helden-IDs
zusammenfassen, die aufgeteilt wurden. An diesem Punkt können wir einfach nach den gesamten Verbindungen sortieren und Top-Ergebnis abziehen, um den beliebtesten Superhelden zu erhalten. Und zur gleichen Zeit können wir einen anderen Datensatz aus
der Marvel-Namens-Textdatei laden lassen und einfach
einen Filter nach der Jahres-ID machen , an der wir interessiert sind, um den Namen unseres Gewinners zu erhalten. Lassen Sie uns also zum Code gehen und sehen, wie es funktioniert. Also zurück zu unserem Projekt hier, öffnen
wir das beliebteste Superhelden-Dataset-Skript und gehen durch, was es tut. Also werden wir die gleiche Strategie tun, über die wir in den Folien hier gesprochen haben. Wir fangen an, indem wir die Dinge importieren, die wir brauchen, wie immer und unser Objekt deklarieren. Wir haben hier zwei Fallklassen, da wir zwei Datensätze zum Laden haben. Einer wird die Datenbank der Superhelden-Namen sein, die Superhelden-IDs zuordnet, die ganze Zahlen sind, zwei Namen, die Strings sind. Und wir haben auch nur einen Superhelden-Datensatz. Und das wird nur eine Zeichenfolge sein, weil wir uns nicht wirklich darum kümmern, diese Daten zu strukturieren. Wir werden uns nur darum kümmern, na ja, was die eigentliche rohe Zeile der Eingabedaten ist und wie viele durch Leerzeichen getrennte Dinge darin sind. Also müssen wir hier nicht schick werden. Wir werden nur in der eigentlichen Zeichenfolge der Zeile selbst in ihrer rohen Form importieren. Also nicht wirklich voll ausschöpfen, was Datensätze hier tun können, aber wir müssen es nicht. Wir sind nicht so, als würden wir hier ausgefallene Analysen machen. Wir zählen nur, wie viele Felder in jeder Zeile sind. Damit werden wir die Dinge loslegen. Unsere Log-Ebene hat also unsere Spark-Sitzung definiert. Und wir werden beginnen, indem wir unser Superhelden-Namensschema erstellen. Dies ermöglicht es uns, diese Marvel Bindestrich Namen Punkt
TXT-Datei zu laden , weil es keine Header-Datei hat, von der wir das Schema ableiten können. Wir müssen ihm sagen, was es explizit ist. Wir werden also sagen, dass wir zwei Spalten in dieser Datei haben. Eine ist die ID und eine ist der Name. Und sie werden durch ein Leerzeichen getrennt. Obwohl wir den CSV-Lader verwenden, können
wir jedes Trennzeichen verwenden, das wir wollen. Und in diesem Fall wird es das Leerzeichen sein. Und Sie könnten an dieser Stelle sagen, aber Frank, was ist, wenn ich einen Platz in meinem Namen habe? Nun, das Gute an dem CSV-Lader ist, dass es klug ist, Anführungszeichen zu machen. Also wird es das tatsächlich behandeln, weil unsere Namen in
Anführungszeichen in dieser Datei sind , was cool ist. In Ordnung, dann müssen wir auch die Marvel-Dash-Graph-Datendatei laden. Und wir werden das einfach direkt als Superhelden-Datentyp laden. Also keine Notwendigkeit, ein Schema dort abzuleiten, weil wir nur eine Zeile haben, wir nehmen es nur in, sagen wir, Rohdaten. Es gibt also überhaupt keine Transformation. Wir werden das einfach in das Superhelden-Dataset laden, das wir nur als einfache alte Zeichenfolge definieren. Also hier ist, wo die Aktion passiert. Wir nehmen diesen Zeilendatensatz, der die Rohdaten enthält, und fügen eine neue Spalte namens id hinzu. Und alles, was tun wird, ist, den allerersten Eintrag in der Zeile zu enthalten. Also verwenden wir Split hier. Die Split-Funktion in SQL für die Wertspalte. Dies ist der Standardname der Spalte, die vom DataFrame mithilfe
des Leerzeichens importiert wurde . Und wir werden nur die allererste Elementnummer
0 aus dieser geteilten Operation extrahieren . All dies tut also, ist zu sagen, diese Zeile von
Rohdaten aufzuteilen und das erste Ergebnis abzuholen und das die ID aufzurufen. Und wir werden das in eine neue Spalte namens id setzen und dann machen wir etwas Ähnliches für alles andere. Wir haben also eine andere Spalte namens Verbindungen, die nur die Größe annimmt, wie viele Dinge in dieser Zeile vorhanden sind, die durch Leerzeichen geteilt sind. Also lasst uns hier von innen arbeiten. Wir beginnen mit der Wertspalte, die der Standardname dieser Spalte ist, die der DataFrame geladen hat. Das sind alle Rohdaten. Wir teilen das basierend auf dem Leerzeichen auf, und dann würden wir Größe aufrufen, um zu zählen, wie viele dieser Dinge existieren. Nachdem wir also alles nach Raum aufgeteilt haben, wie viele Felder haben wir? Anschließend subtrahieren wir eins, um die Helden-ID am Anfang dieser Datenzeile zu subtrahieren. Und das ist unsere Zählung, wie viele Verbindungen mit dieser Datenzeile verbunden sind. Und wir setzen diese Nummer in unsere neue Verbindungsspalte. Und dann werden wir nach ID gruppieren. Dies ermöglicht es uns, mehrere Zeilen für die gleiche Helden-ID zu kombinieren. Und wir verwenden sind zusammengebaut Aggregation Trick hier, wir werden alle Verbindungen und
alle mehrere Einträge für eine gegebene Helden-ID zusammenfassen , die sie alle zusammen addiert. Und wir geben das neue Ergebnis für Tidal, den Alias der Verbindungen. Also führen wir eine neue Summe für jede Gruppe zusammen ein, Helden-ID. Und wir werden diese Verbindungen nennen. Also, das ist es im Grunde. Wir haben jetzt einen Datensatz, der jede eindeutige Hero-ID enthält, da wir eine Gruppe
BY gemacht haben und die Gesamtzahl der Verbindungen für diese hier IID unter einer Verbindungsspalte sind. Alles, was wir jetzt tun müssen, um die beliebtesten Superhelden zu finden, um sie zu sortieren. Und das machen wir hier, sortieren in absteigender Reihenfolge. Und wir werden außerdem das allererste Ergebnis abpflücken, du bekommst den beliebtesten Superhelden. Jetzt enthält unser beliebtester Datensatz eine Zeile, die der beliebteste Superheld ist, mit einer Spalte für die ID und für die Anzahl der Verbindungen, die Hero hat. Als nächstes müssen wir den Namen des Gewinners dort nachschlagen. Es bedeutet also etwas für uns. So können wir den beliebtesten Namen sagen. Wir werden diese Namen Dataset nehmen, die wir früher geladen haben, filtern Sie es basierend auf der beliebtesten ID. Die beliebteste 0 wird also das erste Feld sein, das die Helden-ID ist. Und wir verwenden das, um unser Namens-Dataset nach dieser ID zu filtern, die wir suchen. Das wird uns also die eine Zeile für die ID zurückgeben, die uns wichtig ist. Wir werden dann die Namensspalte dieses Ergebnisses auswählen und erneut das erste Ergebnis in der unwahrscheinlichen Situation dieser mehr als eine Zeile für dieselbe Hero-ID in diesem Datensatz abziehen. Und an diesem Punkt können wir nur die Ergebnisse ausdrucken. Hier holen wir also die erste und einzige Spalte
unseres beliebtesten Namensdatensatzes ab und drucken den Namen im Substitutionsformat aus. Und wir sagen, das ist der beliebteste Held mit dem beliebtesten, der das zweite Feld des beliebtesten Ergebnisses dort abreißen
wird, das wir bekommen haben, was die Anzahl der Verbindungen sein wird, die Held hatte. Also lass es uns loslegen und sehen, was passiert. Rechtsklick. Lauf. Wer ist wohl der beliebteste Superheld im Marvel-Universum? Die Antwort könnte Sie überraschen. Es stellt sich heraus, dass es Captain America ist. Ich habe das nicht kommen sehen. Aber es stellt sich heraus, dass von allen Superhelden im Marvel-Universum Captain America am häufigsten in allen Comicbüchern mit anderen Charakteren erscheint. Also kommt er herum, geh Figur, wer wusste es. Also da ist es, Das verwendet Datasets, um dieses Problem zu lösen. Ich möchte Ihre Aufmerksamkeit jedoch auch auf die RDD-Version des Skripts lenken. Du wirst also bemerken, dass wir hier
einige verwirrte Sachen machen mussten , um diese Daten zu analysieren, richtig? Also mussten wir gerne diese neuen Spalten hinzufügen , die dort einige ziemlich schwere Informationen gemacht haben. Wir hatten die ursprüngliche Datenlinie auf dem ganzen Weg herum. Obwohl Sie dies nur mit Dataset-Befehlen tun können, bedeutet das nicht immer, dass es das Richtige ist. In der Tat, wenn Sie sich viele Online-Beispiele für das Parsen von Daten wie diesem ansehen,
wo Sie eine echte Bereinigung und Neuanordnung der eingehenden Daten durchführen müssen. Oft werden Sie sehen, dass sie beginnen, indem sie Dinge mit den RDD-Schnittstellen laden und dann diese RDD in ein Dataset konvertieren, um es weiter zu analysieren. Und wenn man sich die RDD-Version davon anschaut, ist
das hier das beliebteste Superhelden-Skript. Sie werden sehen, dass es eigentlich ein bisschen einfacher ist. Also, nun, ich würde nicht einfacher sagen, aber es ist in gewisser Hinsicht einfacher, zumindest das Parsen der Daten. Schauen wir uns zum Beispiel an, wie wir
diese Marvel-Punkt-Graph-Datei hier im RDD-Beispiel analysieren . Hier rufen wir nur an, laden das in eine RDD neu und verwenden dann eine Kartenfunktion für Count-Co-Vorkommen. Schauen wir uns an, was das tut. Ziemlich unkompliziertes Zeug, oder? Also hier teilen wir nur die Linie basierend auf
Leerzeichen auf und wir kehren einfach das allererste Element zurück, die Helden-ID und die Elemente Punktlänge minus 1. In vielerlei Hinsicht ist das einfacher und einfacher als wie wir es mit Datensätzen gemacht haben, wo wir diese Art von verwoben mit
Spalte tatsächlich zwei verschiedene mit aufrufenden Befehlen machen mussten , mit all diesen verschachtelten SQL-Funktionen, um das gleiche Ergebnis. Also wohl könnte das tatsächlich effizienter sein. Und sobald wir das haben, können wir einfach
einen ReduceByKey machen , um die Gesamtsumme von Freunden nach Charakter zu erhalten. Also wieder, wissen Sie, manchmal können RDDs einfacher und sogar schneller sein, aber Datensätze sind auch für Sie da. Wenn Sie keine kompliziertere Datenanalyse für echte strukturierte Daten durchführen wollten, glänzen
die Datasets wirklich und ihre Leistung wird attraktiv. Aber denken Sie daran, obwohl Datasets in DataFrame eine Art moderne Art sind, Spark zu verwenden. Es ist nicht immer der beste Weg. Manchmal werden RDDs einfacher sein. Also sollten Sie sich immer noch frei fühlen, die beiden zu mischen und anzupassen, weil manchmal RDD die richtige Antwort ist, manchmal sind Datensätze die richtige Antwort. Es ist nicht immer ein Datensatz. Aber da hast du es. Der beliebteste Superheld, Captain America, sah nicht, dass kommt als nächstes, Lassen Sie uns einige kompliziertere Sachen mit diesem Datensatz machen und einige weitere interessante Informationen daraus
extrahieren.
33. [Übung] Finde die meisten Obskure Superhelden: Nun, das scheint ein guter Zeitpunkt zu sein, dass Sie losgehen und
Ihren eigenen Code für ein bisschen hier schreiben und einige praktische Übungen machen. Ihre Herausforderung wird also sein,
die obskuren Superhelden im Gegensatz zu den beliebtesten Superhelden zu finden . Und ich finde gerne kitschige Fotobilder. Manchmal sieht dieser Superheld ziemlich obskur aus. Vielleicht ist es ein Büroangestellter. Ich weiß es nicht. Es ist ohnehin etwas beunruhigend. Das Problem ist also, dass Sie die Namen
aller Superhelden in unserem Datensatz auflisten , die nur eine Verbindung haben. Und das wird ein bisschen schwieriger, als es klingt, als könnten Sie denken, Sie könnten einfach das vorhandene Skript nehmen, das Sie für die beliebtesten Superhelden
haben, und irgendwo
ein Maximum auf ein Minimum ändern und damit fertig sein oder nach eine andere Reihenfolge. Aber es ist nicht so einfach, weil der Code, den ich dir gerade gegeben habe, davon ausgeht, dass es nur eine Antwort gibt, einen einzigen populärsten Superheld. In diesem Fall gibt es jedoch tatsächlich viele Superhelden in unserem Datensatz, die nur eine einzige Verbindung haben. Und du wirst sie alle zusammen mit ihren Namen auflisten. Das macht die Dinge also ein bisschen komplizierter. Sie müssen einem Dataset irgendwann mit dem
Namens-Dataset verbinden , um alle diese Namen gleichzeitig auszudrucken. Ich meine, du könntest es nach der Tatsache machen und, weißt du, irgendwie mit der Art tun, wie wir es ursprünglich gemacht haben, und individuelle Namen nachschlagen, während du sie ausdruckst. Aber das wird nicht so effizient sein, wie nur irgendwann in die Namen
einzutreten, um sie alle
in einer verteilten Weise über den Cluster zu bekommen . Und für zusätzlichen Kredit, Sehen Sie, ob Sie
die tatsächliche kleinste Anzahl von Verbindungen berechnen können , anstatt nur davon auszugehen, dass es eine ist. Wenn Sie herausfinden können, wie Sie den Befehl min ausführen, um tatsächlich
die kleinste Anzahl von Verbindungen im gesamten Dataset herauszufinden , anstatt sie nur hart zu kodieren. Das wäre die prinzipiellere Sache, richtig? Aber es stellt sich heraus, dass die Antwort eine ist, die die kleinste Anzahl von Verbindungen ist. Es gibt keine, die 0 im Dataset haben. Sie wurden offenbar schon herausgefiltert. Und eins ist die magische Zahl, aber es wäre besser, das irgendwie zu berechnen, oder? Hier ist also die Gesamtstrategie, die Sie hier verwenden möchten. Beginnen Sie mit einer Kopie des beliebtesten Superhelden-Dataset-Skripts, das wir gerade angesehen haben. Und wenn Sie nur eine Kopie dieses Skripts und Intel J machen und es dann in das Paket einfügen. Dadurch haben Sie die Möglichkeit, dieses Skript beim Kopieren umzubenennen. Also nenne es einfach so etwas wie die meisten obskuren Superhelden oder so etwas. Und dieses Skript kann bis zu
dem Punkt, an dem wir das Verbindungs-Dataset erstellen, weitgehend unverändert bleiben . Das wird Ihnen dieses Dataset geben, das
jeden Superhelden hat und wie viele Verbindungen sie haben. Und das wird immer noch nützlich für diese Übung sein. Aber von da an wird
es ganz anders sein. An diesem Punkt möchten Sie das filtern, um nur die Zeilen
zu finden, die eine Verbindung haben. Und wenn Sie das nach unten filtern, möchten
Sie diese Ergebnisse mit unserem Namens-Dataset verbinden, um die Namen für jeden Superhelden in diesem Filter unten am Dataset zusammenzuführen. Jetzt beachten Sie, dass wir hier ein wenig über die Leistung nachdenken, oder? Ich hätte mich diesem Namensdatensatz anschließen können, bevor ich all diese Verbindungen
herausgefiltert habe, die nur eine Verbindung haben. Aber das würde meinen Cluster zwingen, viel mehr Arbeit zu erledigen, als es nötig hat, oder? Was ist der Sinn, in den Namen für all diese Superhelden, die mehr als eine Verbindung haben, ich werde diese nicht anzeigen. Manchmal, obwohl Spark optimiert ist und eine Menge automatischer Optimierung hat, müssen
Sie immer noch ein wenig über die
gewünschten Ergebnisse und die richtige Reihenfolge nachdenken , um Dinge zu tun. Alles klar, sobald wir das haben, müssen
wir nur die Namensspalte auswählen und sie anzeigen. Und das ist es so ziemlich. Und wenn Sie hier einige zusätzliche Hinweise wünschen,
hier sind ein paar Codeausschnitte, die Ihnen helfen könnten. Wenn Sie ein Dataset für einen Spaltennamen herausfiltern möchten, der einem Wert entspricht, würde
es etwa so aussehen. Nur der Punktfilter für den Dataset-Namen. Denken Sie daran, dass die Syntax das Dollarzeichen und dann Anführungsspaltenname ist. Und drei Gleichheitszeichen für den Wert, nach dem Sie filtern möchten. Auch um ein Dataset mit einem anderen zu verbinden. Dies ist genau wie eine SQL-Join-Operation. Sie können einfach den Dataset-Namen sagen, was auch immer es ist, Punkt-Join, und dann den Namen eines anderen Datasets angeben, das
einen gemeinsamen Spaltennamen verwendet, den Sie zum Verbinden dieser Datasets verwenden können. In unserem Fall wird das die ID-Spalte sein. Und dann sagen Sie, dass die Verwendung von Spalte gleich ist, was auch immer dieser gemeinsame Spaltenname ist. Und das wird in den Feldern des zweiten Datasets
mit dem ersten Dataset verbunden , in dem dieser gemeinsame Spaltenname übereinstimmt. Und schließlich, wenn Sie den zusätzlichen Kredit wollen, behalte
ich hier nicht den Überblick über Ihre Punktzahl. Das ist total auf dem Ehrensystem. Wenn Sie jedoch
die minimale Anzahl von Verbindungen, die im Dataset gefunden werden, tatsächlich berechnen möchten, würde
es etwa so aussehen. Auf dem Dataset würden Sie den Befehl add und use verwenden, um
den minimalen Befehl für den Spaltennamen zu enthalten , bei dem Sie
das Minimum ermitteln möchten , dass ein Dataset zurückgegeben wird. Aber wenn Sie diesen tatsächlichen Wert tatsächlich als Scala-Wert
in Ihr Treiberskript zurückbekommen möchten. Um das zurück zu konvertieren, müssen
Sie zuerst dot aufrufen, um die erste Zeile dieses Ergebnisses zu extrahieren. Und es wird nur eine Reihe geben. Und das wird Ihnen einen Zeilendatentyp zurückgeben. Und das wird nicht für sich selbst nützlich sein. Also werden wir get long as 0 aufrufen, um die erste Zahl aus dieser Zeile zu extrahieren, die dieser Mindestwert sein wird. Syntax ist also ein wenig durcheinander, aber das müssen Sie tun, um diese Zahl tatsächlich aus
dem Dataset zurück zu bekommen und in einen tatsächlichen Wert, den Sie dann in Ihrer Filteroperation verwenden können. So viel Glück. Wow, wenn es einen Brokkoli-Mann gäbe, bin
ich mir ziemlich sicher, dass er in Ihren Ergebnissen auf der endgültigen Liste stehen würde. Das ist ein super störendes Bild. Lasst uns das verschwinden lassen. Schreiben Sie einen Code und wir kommen in der nächsten Vorlesung zurück und ich zeige Ihnen meine Lösung.
34. Übung ösung: Finde die meisten Obscure Superhelden: In Ordnung, ich hoffe, du hattest eine Übung und hier ist meine Lösung für das Problem. Auch hier gibt es viele Möglichkeiten, dies zu tun. Solange Sie also dieselben Ergebnisse erzielen, die ich getan habe, zählt das. Es gibt viele Möglichkeiten, dies zu tun. Denken Sie aber darüber nach, wie effizient Ihre Lösung war? Und wir werden ein bisschen darüber reden. Also, wie ich vorgeschlagen habe, habe ich gerade das beliebteste Superhelden-Skript kopiert. Und indem ich das tat, habe ich einfach mit der rechten Maustaste darauf geklickt und das
Kopieren und Kopieren oder einfach Control C. Und dann, wenn Sie es in com dot sun dot software dot spark einfügen, das gab Ihnen die Möglichkeit, dieses Skript mit einem neuen Namen zu duplizieren. Und in meinem Fall habe ich es mit dem Namen der meisten obskuren Superhelden dupliziert, Dot Scala. Gehen wir also weiter und schauen uns das an und gehen durch meine Veränderungen. größte Teil des Skripts ist unverändert. Alles, was ich tat, war, den Namen zu ändern, wie ich sagte, und ich änderte auch den App-Namen, weil warum nicht? Und wie ich schon sagte, wird es bis
hin zur Konstruktion dieses Verbindungs-Datasets gleich sein . Hier konstruieren wir also den Datensatz
aller Superhelden-IDs und die Anzahl der Verbindungen, die sie haben. Und diese Spalte für die Anzahl der Verbindungen heißt Verbindungen. Also an dieser Stelle haben wir einen Datensatz, der eine ID und Verbindungen hat. Das ist also unverändert. Wir verwenden dieselben Informationen, um den beliebtesten Superhelden zu finden. Aber sobald wir das haben, müssen wir das auf die Ergebnisse filtern ,
die die geringste Anzahl von Verbindungen hatten. Und ich weiß zufällig, dass die Nummer eins ist, dass die niedrigste Anzahl von Verbindungen in meinem Dataset eins ist. Aber wenn ich das algorithmisch definieren wollte, könnte
ich so etwas tun. Ich könnte Val sagen, Min. Verbindungszahl. Und das wird ein skalarer Wert sein, der
eine Anzahl gleich Verbindungen dot agg hält . Wir brauchen das nur, um diese Min SQL-Funktion dort zu wickeln. Der Name der Männer-Spalte entspricht Verbindungen. Also an diesem Punkt sagen wir Verbindungen AG Min, Spaltennamen-Verbindungen, so geben wir uns einen Datensatz zurück, der eine einzelne Zeile darin hat, enthält
wieder eine Spalte, die
den Mindestwert in der Spalte Verbindungen gefunden enthält . Jetzt haben wir an dieser Stelle noch einen DataFrame. Und wir wollten das tatsächlich als Wert an unser Treiberskript zurückgeben, richtig? Also müssen wir zuerst dot aufrufen, um dieses Dataset in eine einzelne Zeile zu konvertieren. Und dann, wenn wir dieses Zeilenobjekt haben, rufen
wir getline ungleich Null auf, um
das erste und einzige Feld in dieser Zeile zu extrahieren und dieses zurück in eine lange Ganzzahl zu konvertieren. Dieser kleine komplizierte Ausdruck berechnet diesen Minimalwert und konvertiert ihn zurück in ein Dataset, bringt ihn mit dem ersten Befehl zum Treiberskript zurück, und dann werden Aufrufe lange, um die Nummer aus das Dataset aus dieser Zeile des Datasets genauer. Also, jetzt wird die Anzahl der Hauptverbindungen gleich eins sein. In Ordnung, jetzt, wo wir wissen, was unsere minimale Anzahl von Verbindungen ist, können
wir unser Verbindungs-Dataset darauf filtern, indem wir sagen, Verbindungen Punktfilter, Dollarzeichenverbindungen gleich,
gleich, gleich, merken Sie sich drei gleich. Eine Art seltsame Eigenart der Syntax hier, entspricht min Verbindungsanzahl, die eins sein wird. Und wenn Sie hier den einfachsten Ansatz genommen haben und davon ausgehen, dass es einer war, hätten
Sie einfach gleich sagen können, gleich 1. Und das würde auch funktionieren. Also nehmen wir dieses gefilterte Dataset und nennen es Min Verbindungen. Das Men-Connections-Dataset enthält nun nur die Helden-IDs. Das enthält eine Verbindung. Also haben wir immer noch die Verbindungssäule hier rumhängen. Jetzt müssen wir uns den Namen dieser Superhelden anschließen damit wir sie tatsächlich anzeigen und für Menschen lesbare Ergebnisse erzielen können. Und das ist, was in dieser Zeile hier los ist, sagen
wir Min Verbindungen mit Namen gleich min Verbindungen Punkt verbinden mit dem Namen Dataset mit Spalten-ID. Sie werden also feststellen, dass sowohl die Verbindungen DataFrame als auch die Namen Datenrahmen ein Feld namens ID
haben. Und wir werden das verwenden, um diese beiden Datensätze miteinander zu verbinden. Daher werden
wir für jede Zeile in unserem Min Connections Dataset im Grunde die ID in dieser Zeile nachschlagen und den Namen aus dem Namen-Dataset mit derselben ID
verbinden. Genau wie ein SQL-Join-Befehl, wenn Sie damit vertraut sind. An dieser Stelle werden wir einen Datensatz haben, nicht nur eine ID und Anzahl von Verbindungen
enthält, sondern auch eine Namensspalte, die wir aus diesem Namen DataFrame verbunden haben. So können wir nun endlich unsere Ergebnisse ausdrucken. Lassen Sie uns zunächst ein wenig
einen Header ausdrucken , nur weil wir möchten, dass die Ergebnisse ordentlich aussehen. Du hättest das nicht tun müssen. Natürlich werden
wir sagen, dass die folgenden Zeichen nur Min Verbindung zählen Verbindungen haben. In diesem Fall werde ich 1. Und dann sagen wir einfach Min Verbindungen mit Namen, Punkt wählen Sie den Namen, um nur diesen Namen Spalte auszuwählen. Ich kümmere mich um nichts anderes für die endgültige Ausgabe. Und Punkte zeigen an, dass das als Ausgabe meines Treiberskripts angezeigt wird. Das macht Sinn. Ziemlich unkompliziert. Und wieder, es gibt mehr als einen Weg, es zu tun. Sie tun jedoch eine Sache mit der Leistung. Dies ist ein ziemlich guter Weg, es zu tun. Es könnte eine effizientere Möglichkeit geben
, diesen Minimalwert tatsächlich dort zu bekommen , ohne mein Skript hier tatsächlich zu
stoppen und im Grunde die Welt hier zu stoppen, um herauszufinden, was dieser Minimalwert an diesem Punkt ist. Weil es zu meinem Treiberskript zurückgekommen ist und ich
diesen Wert in einem nachfolgenden Abschnitt meiner Treiberskripte verwende . Also dieser ganze Abschnitt oben hier laufen muss, ist ein Schritt. Es wird auf dem Cluster anhalten,
warten, bis dieses Ergebnis auf den Minimalwert zurückkommt, und dann die nachfolgenden Datensatzoperationen starten,
die möglicherweise nicht ganz optimal sind. Aber es gibt einen besseren Weg, das zu tun. Ich habe es nicht herausgefunden. Ich denke, das ist in diesem Fall unvermeidlich. Aber eine Sache, die ich getan habe, wie ich auf den Folien sagte, war sicherzustellen, dass ich diese Join-Operation nur durchgeführt habe, wenn ich die Verbindungen zu den letzten Ergebnissen, die ich wollte,
gefiltert habe, Joins sind teure Operationen auf Spark. Sie möchten also auf jeden Fall diese so klein und so begrenzt wie möglich halten. Das war also die Methode meines Wahnsinns, in diesem
Join nach der Filteroperation statt davor zu tun . Und auch Lärm. Beachten Sie, dass ich die endgültigen Ergebnisse nicht durchlaufe, indem eine Datensatzsuche für das Namens-Dataset für jeden einzelnen Namen und das Treiberskript durchführe. Das wird noch schlimmer sein. Das ist also ziemlich optimal. Also lasst uns weitermachen und sehen, was wir bekommen. Die meisten obskuren
Superhelden laufen laufendavon. Und hier sind obskure Helden. Die folgenden Zeichen haben nur eine Verbindung. Und es ist eine ziemlich kurze Liste. Aber Arbeiter für Blair, Marvel-Junge. Tollpatschige Nachbeobachtung. Während das sind, weißt du, es gab eine Menge Marvel-Superheldenfilme irgendwie. Ich glaube nicht, dass wir eine über ungeschickte Nachbeobachtung sehen werden. Das ist eine ziemlich obskure Karte. Ich habe nicht von einem dieser Jungs gehört, haben Sie, wenn Sie, sagen Sie es in den Kommentaren, könnte interessiert sein, darüber zu hören. Also ja, wenn Marvel anfängt, Filme über diese Charaktere zu machen, wissen
Sie, sie haben wirklich den Boden des Fasses getroffen. Na gut, das war dort ein interessantes Beispiel. Also hoffe ich, dass du mit dieser Übung Erfolg hattest und dieselben Ergebnisse erzielt hast, die ich gemacht habe. Die Reihenfolge muss offensichtlich nicht die gleiche sein, aber Sie sollten die gleiche Liste von Ergebnissen hier in allem haben, was Sie getan haben. Wenn nicht, gehen Sie zurück zu Bug, was Sie getan haben und iterieren Sie weiter, bis Sie die richtige Antwort erhalten. Und es ist eine gute Praxis. Und damit machen wir weiter.
35. Superhero Einführung von Breadth-First Search: Der Zweck dieser nächsten Übung ist es, Ihnen zu zeigen, dass Funken oft verwendet werden
kann, um Probleme zu parallelisieren, von denen Sie vielleicht nicht gedacht haben, dass Spark tun könnte. Viele Male verwenden Leute Spark for Data Analytics und speziell für Dinge, die als SQL-Befehl ausgedrückt werden können. Aber es kann so viel mehr tun, wenn man einfach kreativ darüber nachdenkt. Also als Beispiel, lassen Sie uns herausfinden, den Grad der Trennung zwischen den Superhelden in unserem sozialen Netzwerk Superhelden hier, um mit der Idee der Grad der Trennung zusammenzufassen, ist, wenn Sie nicht mit ihm vertraut sind, na ja, zurück in Hollywood, es gab früher ein Konzept, das deine Specknummer genannt wurde. Und das war, wie viele Grad der Trennung und Schauspieler war von Kevin Bacon. Es gab diese Legende, in der Kevin Bacon so gut verbunden war, erschien in so vielen verschiedenen Filmen, dass fast jeder Schauspieler sich irgendwie zu Kevin Bacon zurückverfolgen konnte. Und es ist wirklich wahr. Also, wie funktioniert das? Lassen Sie uns das in Bezug auf unsere Superhelden-Daten sagen, richtig? Sagen wir also, dass
Spider-Man aus Gründen des Streits im selben Comicbuch wie der Incredible Hulk erschienen ist. Und der Incredible Hulk wiederum erschien im selben Comicbuch wie Thor. In diesem Fall würden wir sagen, dass Spider-Man und Thor zwei Grad der Trennung sind, oder? Denn wenn man sich die Verbindungen von Spider Mans anschaut, der Hulk nicht in dieser unmittelbaren Verbindung. Jemand, mit dem Spider-Man verbunden ist, ist mit dem Hulk verbunden. Also, das ist zwei Schritte von Spider-Man entfernt oder zwei Grad der Trennung. Das ist also eine interessante Sache, die man sich ansehen kann. Es stellt sich heraus, dass die Menschen näher verbunden sind, als Sie vielleicht denken. Und es stellt sich heraus, dass das auch in der Welt der Comicbücher zutrifft. Also, wie würden wir das tun? Nun, es gibt einen Informatik-Algorithmus namens Breadth-first search, der diese Art von Problem für uns löst. Und das ist sicherlich nicht etwas, wo Sie einfach
einen SQL-Befehl schreiben und damit fertig werden würden , um die Antwort zu finden, richtig? Wir wollen für jede bestimmte Person an einem bestimmten Knoten herausfinden, in diesem Fall einen bestimmten Superhelden in diesem Diagramm der Verbindungen. Wie viele Schritte entfernt ist ein Superheld von einem anderen Superhelden? Also, wie würden wir das mit Apache Spark machen? Nun, bevor wir über die Implementierungsdetails sprechen, lassen Sie uns über den Algorithmus sprechen. Um dieses Beispiel zu verstehen, müssen
Sie die Breiten-Suche oder BFS verstehen. Dies ist ein Problem der Informatik-Algorithmen. Und wenn Sie für Software-Engineer-Positionen interviewen, ist
es eine gute Sache zu wissen, obwohl es nicht direkt mit Funken verbunden ist. Also, wenn Sie den Details hier nicht folgen, lassen Sie sich nicht allzu aufhängen. Es ist nicht wirklich relevant, sich selbst zu entzünden. Ich bin nur relevant, um dieses Beispiel zu verstehen,
wie Spark verwendet werden kann, um Probleme zu lösen, von wie Spark verwendet werden kann, um Probleme zu lösen denen Sie vielleicht nicht gedacht haben, für die Spark verwendet werden kann. Stellen Sie sich also vor, dass dies unser Netzwerk darstellt. Jeder Kreis hier stellt also einen Superhelden dar, und jede Linie zwischen diesen Kreisen stellt eine Verbindung zwischen Superhelden dar. Das bedeutet also, dass sie zusammen im selben Comicbuch erschienen sind. Und einige, wissen Sie, manchmal haben Sie viele Verbindungen, die von
einem Superhelden kommen und manchmal gibt es viele Routen zwischen zwei Superhelden zu betrachten. Die Zahl innerhalb jedes Kreises stellt also die Entfernung dieses Superhelden von dem Superhelden dar, von dem wir den Grad der Trennung messen. Und anfangs kennen wir die Antwort nicht, da wir diesen Algorithmus starten. Also ist alles auf unendlich eingestellt. Wir gehen davon aus, dass sie unendlich weit weg sind, weil wir es noch nicht berechnet haben. Also, um zu beginnen, haben wir den Superheld ausgewählt, mit dem wir
anfangen wollen und von dem wir die Grade der Trennung berechnen wollen. Also lassen Sie uns sagen, dass Spider-Man, und wir werden das S hier in diesem Beispiel nennen. Also der Kickoff, der Algorithmus, wir färben diesen Anfangsknoten grau,
was bedeutet, dass wir diese NOAEL erkunden müssen, wollen
wir mehr über die Verbindungen von diesem Knoten erfahren. Und wir setzen die Zahl 0 ein, weil das die Entfernung von der Person ist, die wir mit 2 beginnen, diesem Knoten. Spiderman ist 0 Grad der Trennung von Spider-Man, weil Spider-Man Spider-Man ist. Was wir also im BFS-Algorithmus tun, ist, dass wir nach grauen Knoten in unserem Diagramm suchen. Und für jeden grauen Knoten, den wir finden, untersuchen
wir die Verbindungen, die von diesem grauen Knoten ausgehen. Und wenn wir tun, wenn dieser Knoten, den wir erforschen seine weiße,
was bedeutet, dass es zuvor unerforscht wurde, werden
wir es grau färben,
was bedeutet, dass wir diesen Knoten weiter iterativ erkunden müssen. Und wir nehmen den Knoten, den wir gerade erkundet haben, in der Farbe schwarz,
was darauf hinweist, dass wir diesen Knoten bereits erkundet haben. Wir müssen nicht wieder darauf zurückkommen. Wir erhöhen die aktuelle Anzahl der Entfernung. Also war es 0 plus eins ist eins. Also, jetzt wissen wir, dass wir ein Grad der Trennung auf R und W sind macht Sinn. Also begannen wir, diesen zunächst grauen Knoten
S Farbe zu schwarz zu erkunden , weil wir damit fertig sind. Und für alle seine Verbindungen, wenn sie weiß waren, machen
wir sie jetzt grau und setzen die aktuelle Anzahl der Entfernung von diesem Anfangsknoten ein. Also suchen
wir im nächsten Durchgang wieder nach den grauen Noten und erkunden ihre Verbindungen. Beginnen wir also mit w. Es wird seine Verbindungen ausbrechen. Also waren diese beide ursprünglich weiß und jetzt werden wir sie grau
färben und die Entfernung nochmals erhöhen. Also, jetzt sind wir zwei Grade der Trennung von S wird das gleiche tun für die Verbindung von S zu R Explore Es ist eine Verbindung zu v und Farbe es grau. Und wieder, setzen Sie eine Zwei da rein, weil wir
derzeit in der Iteration von zwei Distanzen von S sind. Nun, da wir erforscht haben, sind
wir in W , werden wir nennen es geht schwarz,
was bedeutet, dass wir diese nicht erneut in die Zukunft. Als Nächstes fangen wir wieder mit T. an. Wir müssen alle grauen Knoten durchlaufen und ihre Verbindungen wieder erkunden. Jetzt ist T mit u verbunden, das weiß war, also färben wir jetzt dieses Grau und erhöhen die Entfernungszahl wieder auf drei. Jetzt. Beachten Sie nun, dass t auch mit x und w verbunden ist, Aber diese sind nicht weiß. Wir werden versuchen, die dunkelste Farbe hier zu erhalten, während wir durchgehen. Also werden wir uns nicht wieder darum kümmern, x erneut zu besuchen. Es ist schon grau markiert. Wir werden W definitiv nicht wieder besuchen, weil das schwarz markiert ist. Das bedeutet, dass wir das schon gemacht haben. Wir brauchen keinen Prozess, den wir überhaupt nicht brauchen. So können wir markieren, dass x jetzt erforscht wird, wir können das Schwarz
jetzt markieren , weil wir bereits festgestellt haben, dass wir damit fertig sind. Und weitermachen. Wir müssen es auch erforschen, wenn wir das noch nicht fertig haben. Also gehen wir und überprüfen V jetzt auch als schwarz. Das war ursprünglich ein Grau. Jetzt ist der nächste Schritt, einfach schwarz zu nennen,
was bedeutet, dass wir fertig sind, es zu erforschen. Jetzt haben wir nur noch zwei weitere graue Knoten zu erkunden. Und sie haben keine neu unerforschten Knoten mit ihnen verbunden. Also werden wir sie einfach schwarz färben und damit fertig sein. Also der Gesamtalgorithmus hier, um zusammenzufassen, beginnen
wir, indem wir alles weiß mit einer unbekannten Entfernung färben. Unser anfänglicher Knoten ist grau, und für jede Iteration suchen
wir nach grauen Knoten, erkunden ihre Verbindungen. Und für jeden weißen Knoten, der von diesem grauen Knoten kommt, werden
wir ihn als grau für die
zukünftige Erkundung markieren , es sei denn, er wurde bereits grau oder schwarz gefärbt, wo genau die dunkelste Farbe dort erhalten bleibt, während wir gehen. Darüber hinaus bewahren wir
die niedrigste Distanzmetrik auf, die wir in diesen Knoten sehen, während wir gehen. Also werden wir nie so etwas wie von dir zurück nach
T gehen und sagen, dass T jetzt eine Distanz von vier ist, weil wir zurückverfolgt haben, das würde Sinn ergeben, richtig? Daher würden wir immer diese Metrik für niedrigere Entfernungen beibehalten, wenn wir das Diagramm durchlaufen. Es ist also eine Art schwierige Sache, den Kopf umwickeln. Und noch einmal, wenn du dem nicht ganz gefolgt bist, mach dir keine Sorgen darüber. Dies ist kein Kurs über Algorithmen, ist ein Kurs über Spark. Ich versuche nur zu vermitteln, wie es möglich ist,
Spark zu verwenden , um Probleme zu lösen, für die Sie vielleicht nicht denken würden, für die Spark geeignet ist. Sie können dieses Problem tatsächlich ziemlich
gut parallelisieren , wenn wir darüber kreativ nachdenken. Lassen Sie uns also über diese Implementierung in Spark
als nächstes sprechen und machen Sie dies auf unserem Spark-Cluster möglich.
36. Superhero Akkumulatoren und Implementierung von BFS in Spark: Lassen Sie uns also darüber sprechen, wie man dies als Funkenproblem umrahmt und tatsächlich verteilte Breitensuche über unseren gesamten Cluster potenziell verteilt. Das erste, was wir tun müssen, ist, unsere Daten als diese Knoten darzustellen , über die wir in der vorherigen Vorlesung gesprochen haben. So könnte beispielsweise eine Eingabezeile in diesem Format vorliegen, die erste Zahl ist eine Helden-ID, gefolgt von einer Liste der anderen Helden, die Hero mit einem anderen Comic-Bücher erschienen ist. Also wollen wir das in einer Weise strukturieren, die
einen dieser Knoten in der Breadth-first Suche darstellt . Zum Beispiel könnten wir dies als das folgende Tupel von Tupeln strukturieren, wenn Sie so wollen. Wo das erste Element die Helden-ID ist, von der wir sprechen. Der, der im Grunde durch diesen Knoten dargestellt wird, gefolgt von einer Liste aller anderen Helden-IDs, die mit diesem Helden verbunden sind. Stellen Sie sich also eine virtuelle Linie zwischen 59, 83 und 11, fünfundsechzig, achtunddreißig, sechsunddreißig, et cetera, et cetera. Das sind also alle Verbindungen, die mit unserem Helden verbunden sind. Und das selbst ist in seinem eigenen Tupel. Um das alles in sich zu halten. Das nächste Element in unserem Tupel stellt die mit
diesem Knoten verknüpfte Entfernung von dem Zeichen dar , von dem wir die Entfernung messen. Ein zunächst setzen wir das auf Unendlichkeit. Es gibt hier keine Möglichkeit, Unendlichkeit wirklich darzustellen, also werden wir es einfach auf eine wirklich große Zahl setzen. In diesem Fall 99. 99 wird unser Stand-in für Unendlichkeit als Anfangswert der Entfernung sein. Und wir müssen eine Farbe zuordnen. Denken Sie daran, dass unsere Notizen weiß, grau
oder schwarz sein können , wobei Weiß einen unerforschten Knoten darstellt. Grau stellt einen Knoten dar, der untersucht werden muss, und Schwarz ist ein Nein, das bereits untersucht wurde. Also zunächst ist jeder Knoten weiß. Das ist also ein Beispiel dafür, wie wir diese Zeilen in einem Format darstellen können,
das mit unserem Konzept der Knoten in einer ersten Atemsuche konsistent ist. Also, jetzt tatsächlich durch
diesen Breadth-first Suchalgorithmus zu gehen , kann als eine Karte betrachtet werden und den Betrieb reduzieren. Die Mapping-Funktion kümmert sich um
die Umwandlung dieser Zeilen in das BFS-Knotenformat, über das wir gerade gesprochen haben. Und dieser Code könnte so aussehen. Also müssen wir es nur nach Leerzeichen aufteilen, die Hero-IDs in ganze Zahlen
konvertieren und die Verbindungen zu Ganzzahlen
bilden ein Array von Verbindungen, die alle Verbindungen sind, die mit dieser Person verbunden sind. Legen Sie die Anfangsfarbe auf Weiß fest. Setzen wir den Anfangsabstand auf 99, 99. Und wenn die Helden-ID eins ist, beginnen
wir mit dem Anfangsfall für den Fall, von dem wir beginnen. Farbe, dass ein Grau mit einem Abstand von 0, aber alles andere sollte weiß mit einem Abstand von Unendlichkeit als unser anfänglicher Fall sein. Und wir geben einfach unsere tupled Struktur zurück, über die wir mit der Helden-ID gesprochen haben. Und dann weiter, die Anordnung der Verbindungen und die Entfernung und die Farbe. Nun, es ist vielleicht eine gute Idee hier ein wenig über die Geschichte der verteilten Computing zu
sprechen. Beachten Sie also, dass wir ein MapReduce-Paradigma verwenden, um über dieses Problem nachzudenken. Woher kommt diese Idee? So weit zurück, als Google zuerst mit groß angelegten Datenanalysen und der Notwendigkeit, Daten zu verarbeiten, die nicht auf einer einzigen Maschine passen konnte. Sie haben MapReduce erfunden. Und MapReduce war ziemlich beschränkt auf Kartenfunktionen und Reduce-Funktionen. Das ist es, was es getan hat, oder? Und wir haben Beispiele für Mapper und Reduzierer in früheren Beispielen in diesem Kurs gesehen, aber es muss sein, Das ist ziemlich der einzige Trick, den wir in den Ärmeln hatten. Hadoop wurde auf den Konzepten gebaut, die Google kam mit. Und Hadoop, es hat auch etwas namens MapReduce. Es heißt eigentlich MapReduce, ein Wort, das eine wesentliche Komponente von Hadoop selbst ist. Das Problem ist, dass MapReduce bei der Optimierung nicht sehr schlau war, und da kam Spark ins Spiel. Also Spark war es anfänglich nur eine schnellere Alternative zu MapReduce. Das ist also, wo die anfängliche RDD-Schnittstelle von spark herkam. Sie werden feststellen, dass RDDs über eine Kartenfunktion und eine Reduce-Funktion verfügen. Und deshalb, weil sie versuchten,
die Funktionalität der Hadoop MapReduce-Funktionalität zu replizieren . Jetzt später im Laufe der Zeit, als wir zu Spark Version 2 kamen
, dann wurden Datasets und DataFrame eingeführt. Dataframes kamen eigentlich zuerst. Und da begannen wir zu sagen, Hey, lassen Sie uns über diese in Bezug auf SQL-Operationen nachdenken. Sql wurde zu dieser Zeit eine gemeinsame Sprache zwischen Datenanalyse-Softwarepaketen. Also auch für Dinge, die verteilt wurden und technisch nicht für relationale Datenbankoperationen geeignet waren. Sql wurde immer noch zur gemeinsamen Syntax zwischen all diesen verschiedenen Plattformen. Also sahen wir diese Entwicklung von MapReduce zu Funken, die als Erweiterung gebaut wurde, um MapReduce besser zu machen. Um mehr von einer SQL SAL Schnittstelle zu entfalten. Aber nicht alles ist ein SQL-Problem, oder? So haben wir immer noch die niedrigere Funktionalität von MapReduce zur Verfügung, die wir verwenden können, um allgemeinere Probleme wie dieses zu lösen. Ich kann keinen SQL-Befehl schreiben, der besagt, dass die Entfernung in einem Diagramm zwischen zwei beliebigen Knoten
berechnet wird. Aber ich kann das als MapReduce-Probleme einrahmen. Also, das werden wir hier tun. Auch hier geht es darum, das richtige Werkzeug für den Job auszuwählen, obwohl wir dies mit einem Datensatz tun können. Und ich werde Ihnen zeigen, dass in diesem Fall Verwendung von RDDs und deren Low-Level-Mapping und die Reduktion Funktionalität der einfachere Ansatz sein wird. Okay, abseits von meiner Plattform, lassen Sie uns noch etwas über die Implementierung sprechen. So wie wir in den Folien für die Breitensuche durchgegangen sind, werden
wir die Dinge iterativ durchlaufen. Und für jeden Schritt, jede Entfernung, werden
wir nach all den grauen Knoten suchen und diese grauen Knoten
ausdehnen. Färben Sie die Nase. Wir sind fertig mit seinem Schwarz und erhöhen einfach die Entfernungen, während wir gehen. Sie werden also eine große Schleife sehen, die einfach iterativ durch dieses Diagramm immer und immer wieder
geht, nach grauen Knoten sucht und diese grauen Knoten
entsprechend den Regeln verarbeitet , die wir in der BFS definiert haben -Algorithmus. In Ordnung, also nochmal, wir stellen das nur als eine Karte und einen Reduzierjob ein. Jedes Mal, wenn wir unseren Algorithmus inkrementieren, erhöht
der Mapper die Entfernung um eins. Und es wird nach grauen Noten suchen. Wenn es einen grauen Knoten findet, schauen Sie sich alle Verbindungen dieses grauen Knotens an, färben Sie sie grau für die zukünftige Erkundung. Und anfangs werden sie keine Verbindungen haben, weil sie erforscht werden
müssen, um diese Verbindungen aufzubauen. Bei der nächsten Iteration das Korn Hafer es gerade verarbeiten dann schwarz gefärbt. Und es wird den Knoten selbst zurück
in die Ergebnisse kopieren , um sicherzustellen, dass wir ihn nicht verlieren. Der Reduzierer-Job wird sein, mit all den Fällen umzugehen, in denen wir
mehrere Pfade haben , die in den gleichen Knoten gehen, viele Verbindungen. Wir müssen also alle Knoten zusammenfassen, die für die gleiche Helden-ID existieren. Und wenn es einen Fall gibt, in dem es mehrere Verbindungen gibt, möchten
wir die Verbindung mit der kürzesten Entfernung und der dunkelsten Farbe bewahren. Und da es Dinge reduziert, die diese Liste der Verbindungen
vom ursprünglichen Knoten beibehalten werden , um sicherzustellen, dass wir diese bei der nächsten Iteration nicht verlieren. So funktioniert alles von einem algorithmischen Standpunkt aus. Aber woher wissen wir, wann wir fertig sind? Hier ist, wo wir ein neues Konzept namens Akkumulator in Spark vorstellen. Ein Akkumulator ist also im Grunde ein gemeinsamer Zähler für alle Executoren in Ihrem Cluster. Also, wenn Sie eine Art von einem allgemein gehaltenen Zähler haben müssen, wenn Sie so wollen, oder eine Flagge irgendeiner Art. Und der Akkumulator kann das tun. Es ermöglicht vielen Executoren, eine gemeinsam genutzte Variable über den gesamten Cluster zu erhöhen. Also hier ist ein Beispiel für diese Syntax. Ich könnte sagen, Trefferzähler ist ein langer Akkumulator namens Trefferzähler. Und standardmäßig wird der Anfangswert 0 sein. Während wir unseren Algorithmus durchlaufen, werden
unsere Iterationen über unsere gesamte Plattform verteilt werden. Und jeder einzelne Executor könnte auf den Charakter treffen, an dem wir interessiert sind. Wenn das passiert, muss
dieser Executor irgendwie zurück zum
Treiberskript als Ganzes signalisieren , Hey, wir sind fertig. Wir haben hier einen Treffer bekommen. So können wir den Trefferzähler Akkumulator in diesem Fall erhöhen, um anzuzeigen, dass er tatsächlich den Charakter gefunden hat, von dem wir versuchen,
die Entfernung zu unserem ursprünglichen Charakter zu finden . Wenn wir also mit jeder Iteration fertig sind, überprüfen
wir einfach, ob der Trefferzähler größer als eins ist. Und wenn es so ist, wissen wir, dass wir fertig sind und manchmal werden wir
einen Treffer aus mehreren Richtungen bekommen und dieser Hinderniszähler könnte mehr als einer sein. Aber so wissen wir, dass wir fertig sind. Diese Executors können zum Drehbuch zurücksignalisieren, Hey, ich habe einen Treffer. Und es kann verfolgen, wie viele Treffer durch
diesen gemeinsamen Akkumulator über alle Executoren. Das ist also eine Menge, um deinen Kopf herum zu wickeln. Lass uns zum Code gehen und sehen, wie er aussieht.
37. [Aktivität] Superhero Überprüfe den Code und führe es aus: Lassen Sie uns also in den Code eintauchen, öffnen Sie Grade der Trennung, nicht den Datensatz eins noch, nur Grade der Trennung. Und wir werden diesen Code durchlaufen. Jetzt wieder. Der Sinn dieser Übung besteht darin, Ihnen zu zeigen, dass Sie
komplexe Dinge mit Spark erledigen können , die sich nicht nur auf SQL-Operationen beschränken würden. Wenn Sie also wie herkömmliche Datenanalysen tun möchten, verwenden Sie SQL-Befehle. Aber für solche Dinge müssen
Sie möglicherweise auf die niedrigere Stufe von Spark gehen und zur RDD-Schnittstelle zurückkehren. Und das ist okay, das ist, das steht Ihnen auch zur Verfügung. Und weißt du, das ist eine Art kreatives Denken ist wirklich das, wofür Unternehmen wie Amazon und Google und Apple den Menschen die großen Mäuse zahlen werden, richtig? Es braucht nicht jemand wirklich Besonderes, um einen SQL-Befehl zu schreiben und herauszufinden, wie viele Website-Treffer Sie in der letzten Stunde hatten. Aber es braucht jemand Besonderes, um herauszufinden, wie ich
ein Problem nehmen kann , das noch nie gelöst wurde, bevor Sie Apache Spark verwenden und es lösen. Und hier ist ein Beispiel dafür. Wenn Sie also dem Code hier nicht folgen, wenn Sie dem Algorithmus nicht folgen, sich darüber
nicht zu sehr gestresst. Das ist nicht wirklich der Sinn dieser Aktivität. Der Punkt ist nur, Ihnen zu zeigen, dass es möglich ist, komplizierte Dinge in
Spark und Parallelität in einem Cluster zu tun , die Sie vielleicht nicht für möglich gehalten haben. In diesem Fall denken wir eher in einem MapReduce-Paradigma als in einem SQL-Paradigma. Und das ist okay. Also tauchen wir ein, importieren wir all das Zeug, das wir gebetet haben oder Objektklasse. Nun ist das erste,
was wir tun, zu definieren , von welchem Charakter wir beginnen und welchen Charakter wir suchen. Also der Zweck dieses Skripts wird es sein, die Grade der Trennung zwischen Spider-Man zu finden, die Zeichen ID 5306
ist, stellt sich heraus, und dem Zeichenatom 3,031
, der ehrlich gesagt das obskure Zeichen I im Datensatz
finden konnte, zumindest habe ich nie von ihnen gehört. Ich habe keine Ahnung, wer das ist. Und seine Charakter-ID ist 14. Wir versuchen also, den Grad der Trennung
zwischen Spider-Man und Adam zu finden , 3.031 hier. Und wir sprachen über die Verwendung eines Akkumulators namens Trefferzähler. Und so signalisieren unsere Führungskräfte zurück, um zu sagen, Hey, ich habe tatsächlich Atom 3.031 gefunden, während ich den Graphen von Spider-Man durchquerte. Das wird also irgendwie unser gemeinsamer Zähler sein, der besagt, hey, ich habe hier eine Verbindung. Als nächstes richten wir hier unsere Datentypen ein. Wir haben also einen BFS-Datentyp, der ein Array von
Ganzzahlen und eine Ganzzahl und eine Zeichenfolge ist , die eine Liste von Verbindungen, die Entfernung und die Farbe mit dem Knoten verbunden ist. Und der Knoten selbst wird die Hero-ID mit diesem Knoten und den damit verbundenen Daten verknüpft. Ein BFS-Knoten wird also einen dieser Kreise
in unseren Folien darstellen , der eine bestimmte Helden-ID darstellt. Und die Verbindungen bei diesem Helden haben die Entfernung von Spider-Man. Und schließlich die Farbe dieses Knotens
, der weiß, grau oder schwarz sein wird. Lassen Sie uns zur Hauptfunktion springen und von dort rückwärts arbeiten. Also hier unten haben wir eine Hauptfunktion. Beginnen Sie, indem Sie die Protokollebene sagen und wir richten einen neuen Spark-Kontext ein. Wir verwenden keine Spark-Sitzung, da wir in diesem Beispiel nicht die Dataset-Schnittstelle
verwenden, wir werden nur RDDs verwenden. Und dafür müssen wir nur Kontext Funken. Wir initialisieren unseren Akkumulator und geben ihm einen Namen. Und das erste, was wir tun, ist Start RDD. schafft also diese Anfangsbedingungen unseres Graphen. Mal sehen, was das tut. Wo ist das Erstellen von RDD? Sehr einfach, richtig? Also alles, was wir hier tun, ist,
den Marvel-Punkttext in eine rohe Eingabedatei RDD zu laden . Und dann rufen wir Map mit Converge zu BFS auf, um diese Daten in das BFS-Knotenformat zu konvertieren. Schauen wir uns Convert to BFS an. Teilt die Zeile in einzelne Felder, pflügt das erste macht, dass die Helden-ID alle nachfolgenden Felder hier abreißt und
ein Array von Ganzzahlen füllt und die
alle Verbindungen von diesem Helden zu anderen Helden. Wir setzen seine Standardfarbe auf Weiß und seine Standardentfernung auf 99,
99, was unsere Darstellung der Unendlichkeit ist, es sei denn, Sie sind Spider-Man. In diesem Fall färben wir Sie grau mit einem Abstand von 0. Das bedeutet, dass wir damit beginnen wollen, den Spiderman-Knoten zu erkunden und der Grad der Trennung von Spider-Man 2 selbst ist 0. Wir kehren dann zurück, dass BFS Notizen Struktur, über
die wir gesprochen haben, das ist eine Hero-ID und dann ein Tupel, das das Array
der Verbindungen, die aktuelle Entfernung und die aktuelle Farbe mit jedem Knoten verknüpft. Also zunächst wird alles eine weiße Farbe haben, eine Entfernung von 99, 99. Und alle Verbindungen, die mit jeder Helden-ID verknüpft sind, lesen aus dieser Textdatei ein, Ausnahme von Spider-Man, der mit einer Entfernung von 0 grau sein wird. In Ordnung, also haben wir den ersten Fall gemacht, sie sind eingerichtet. Was passiert als Nächstes? Also, jetzt gehen wir durch diese Iteration, wie wir sagten, und wir wählten zehn ist eine willkürliche Obergrenze. Es stellte sich heraus, dass Sie nie einen haben. Es sind eigentlich zehn Grad der Trennung in diesem speziellen Datensatz, das mehr als genug ist. Wir drucken aus, wie viele Iterationen wir gegangen sind. Dies stellt also die Entfernung dar, die wir bei diesem Schritt von Spider-Man betrachten. Und das erste, was wir tun, ist eine Kartenoperation. Also rufen wir FlatMap auf BF mit der BFS-Map-Funktion unter Verwendung dieser Iteration RDD auf. Also haben wir angefangen, ich sitze Iteration RDD in diesen Anfangszustand. Wir rufen dann FlatMap auf Iteration RDD. Und FlatMap
hat, wie Sie sich erinnern können, das Potenzial, neue Knoten zu erstellen, oder? Also mal sehen, was in der BFS-Karte passiert. Zu tun. Es gibt eine BFS-Karte. Alles klar, im Grunde extrahieren wir die Zeichen-ID und die zugehörigen Daten, und wir blasen diese Daten aus, um das Array der Verbindungen,
die Entfernung und die Farbe aus dem Knoten zu extrahieren , den wir betrachten, den wir zuordnen. Nun, da dies eine FlatMap ist, können
wir ein Array von BFS-Knoten mehr als eins zurückgeben, wenn wir zu unserer neuen RDD hinzufügen möchten. Und während wir gehen, suchen wir jedes Mal nach grauen Knoten, richtig? Die grauen Knoten sind also diejenigen, die untersucht werden müssen. Wenn wir also auf einen grauen Knoten stoßen, verarbeiten wir ihn. Wir untersuchen alle Verbindungen und erstellen einen neuen Knoten für diese Verbindung. Wir könnten also eine neue Zeichen-ID haben, eine neue Entfernung, die die Entfernung plus 1 von ihnen ist. Wissen Sie, dass wir angefangen haben, wird
die neue Farbe grau sein. Und wenn das tatsächlich der Charakter ist, nach dem wir suchen, wenn es sich herausstellt, Adam 3000,
31 oder was auch immer es war,
dann werden 31 oder was auch immer es war, wir unseren Trefferzähler erhöhen und sagen:
Hey, wir haben den Kerl gefunden, wir sind fertig. Wir haben tatsächlich einen Knoten gefunden, wo diese Person mit Spiderman verbunden ist. Dann erstellen wir einen neuen Knoten basierend auf der neuen Entfernung in neuer Farbe, die wir berechnet haben, und fügen diesen zu unserer Ergebnisliste hinzu. Also haben wir all diese neuen grauen Knoten erstellt, die wir aus den Verbindungen der grauen wissen, dass wir gerade gefunden haben, erkunden müssen . Und wir nehmen das Grau wissen, dass wir gerade erkundet und färben es schwarz,
was darauf hinweist, dass wir damit fertig sind. Okay. Wir geben nur die Ergebnisse zurück und wir sind fertig. Also, wenn Sie den BFS-Algorithmus nicht verstehen, lassen Sie sich nicht zu viel daran hängen. Das ist nicht wirklich der Sinn dieses Kurses, aber ich wollte Ihnen nur zeigen, was Sie tun können. In Ordnung, also haben wir die Kartenoperation durchgeführt. Wir drucken dann unseren Prozess aus, während wir gehen und sagen wir haben so viele Werte bisher verarbeitet. Und wenn wir tatsächlich einen Treffer bekommen haben, werden
wir sagen: „Hey, wir haben den Charakter gefunden, den wir suchen. Hier ist die tatsächliche Summe, wie viele Treffer wir von dieser Iteration erhalten haben. Es ist also möglich, dass mehr als ein Executor dieses Zeichen gleichzeitig verarbeitet hat. Und sie haben dir vielleicht mehrere Treffer
aus verschiedenen Richtungen gegeben , und das ist okay. Wir haben die Gesamtsumme hier ausgedruckt. Wenn ja. Bevor wir nun weiter iterieren, müssen
wir Daten miteinander kombinieren. So könnten wir neue Knoten für die gleiche Zeichen-ID generiert haben, wie wir gegangen sind. Als wir also all diese Verbindungen erkundet haben, könnten
wir uns in
mehrere verschiedene Richtungen verzweigt haben und
zurückkommen und wissen, dass wir zum Beispiel bereits verarbeitet haben. Um diesen Fall zu behandeln, mussten
wir eine ReduceByKey-Operation durchführen. Der ReduceByKey zieht alle neuen Notizen zusammen , die sie möglicherweise für dieselbe Zeichen-ID erstellt haben. Und die Aufgabe der BFS reduzierten Funktion im Leben besteht darin, den minimalen Abstand und die dunkelste Farbe in diesem Fall zu
bewahren. Das ist also alles, was hier vor sich geht. Ich werde den Code hier nicht sehr detailliert durchlaufen, weil er nicht wichtig ist. Aber das ist der Zweck dieser Funktion, nur um
die Fälle zu behandeln , in denen wir mehr als eine Verbindung haben, die in denselben Knoten kommt. in diesem Fall Bewahren Siein diesem Fallden minimalen Abstand und die dunkelste Farbe auf, die mit diesem bestimmten Knoten verknüpft ist. Also ja, mal sehen, ob es wirklich funktioniert. Lassen Sie uns mit der rechten Maustaste auf den Grad der Trennung klicken und es ausführen. Ziemlich komplizierter Job, oder? Aber Spark kann es kurz machen. Los geht's. Bereits so gut gemacht, haben wir dort tatsächlich 218.067 Verbindungen verarbeitet. Aber wir fanden heraus, dass selbst dieser obskure Charakter
nur zwei Grad der Trennung von Spider-Man ist. Zwar stellt sich heraus, dass selbst fiktive Superhelden in Comicbüchern sehr gut verbunden sind. Und das gilt tatsächlich in der realen Welt. Es stellt sich heraus, wenn Sie sich ansehen, wissen Sie, echte soziale Netzwerke wie LinkedIn oder IMDB ist Datenbank von Verbindungen von Schauspielern, die es zusammen im gleichen Film handeln, erhalten Sie ähnliche Ergebnisse. Die Menschen sind viel verbundener, als Sie vielleicht denken. Es ist irgendwie interessant. Sieh dir das an. Es hat funktioniert. Wieder ziemlich cool, dies ist nur ein Beispiel dafür, wie mit den niedrigeren Funktionalitäten von Spark manchmal Probleme lösen können, Siemit den niedrigeren Funktionalitäten von Spark manchmal Probleme lösen können,für die Sie nicht denken würden, dass Spark unbedingt geeignet war. Es geht nicht nur darum, SQL-Probleme zu lösen. Du kannst damit mehr Sachen machen als das. Denk daran, dass du diese Macht zur Verfügung hast. Das ist nicht zu sagen, dass ich das nicht in Bezug auf Datasets und SQL-Operationen
haben konnte , können
Sie, und wir haben das getan. Schauen wir uns kurz die Dataset-Version dieses Skripts an. Und es macht ziemlich seltsame Sachen. Also ich meine, zu versuchen, MapReduce zu tun, ohne MapReduce zu verwenden, Es ist möglich. Es wird nicht effizient sein. Also, wenn wir uns das ansehen, werde
ich das Skript hier nicht zu sehr ins Detail eingehen, aber Sie können sehen, dass wir hier
einige ziemlich verwirrte Sachen machen, die wir in den RDD-Skripten gemacht haben. Also, selbst das Erstellen dieser Anfangsbedingungen hier, nur eine Art der Konstruktion dieser Knotenstruktur endet diese komplizierte Operation von Breitenspalten in SQL-Funktionen, um zu versuchen, zu replizieren, was wir mit der Verwendung Sie wissen, gerade nach oben Scala-Code in unserer Karte und reduzieren Funktionen. Und wir haben all diese Sonderfälle für unseren Startcharakter. Wir müssen diese Filter im Grunde mögen und den gesamten Datensatz
durchsuchen , um nach diesem Sonderfall zu suchen, anstatt ihn nur in der Linie zu behandeln. Während wir jeden Knoten untersuchen, auf der Suche nach grauen Knoten, müssen
wir eine Filteroperation und alles tun, um diese grauen Knoten zu extrahieren. Wählen Sie die Informationen aus, die wir benötigen. Filtern Sie heraus, suchen Sie nach der Ziel-Zeichen-ID , die wir suchen, und behandeln Sie das, besonders. Also macht es das Gleiche. Nun, das ist komplizierter Code, den ich auch die dunkelste Farbe bewahre, um fair zu sein, es war auch in unserem Code ziemlich kompliziert, aber es umfasste keine Join-Operation. Guter Herr. Und all das wirklich ausgefallene SQL, dass es wahrscheinlich ziemlich schwere Operationen sein wird. Obwohl wir es also,
wenn wir darüber nachdenken, alsSQL-Problem
einrahmen können wenn wir darüber nachdenken, als , ist
es nicht der effizienteste Weg, darüber nachzudenken. Und nur um meinen Standpunkt zu beweisen, lassen Sie uns das laufen. Und wir werden zählen, wie viele Sekunden es dauert, bis diese Version des Skripts ausgeführt wird, sobald Spark hochgedreht wird. Also, hier geht's. 1, 2, 3, 4, 5, 6, 7. dauerte ungefähr sieben Sekunden, um die Antwort dort zu bekommen. Wir haben die gleiche Antwort. Das ist also gut. Es funktionierte, aber es dauerte sieben Sekunden, um diese Antwort zu bekommen. Im Gegensatz dazu lassen Sie uns die RDD-Version davon ausführen. Ein bis nicht einmal drei Sekunden, oder? Das war also mehr als doppelt so schnell wie die Dataset-Version. Auch hier geht es darum, das richtige Werkzeug für den Job zu wählen. Datasets sind großartig bei der Behandlung von herkömmlichen Datenanalyseproblemen. Wenn Sie Ihr Problem in Bezug auf einen SQL-Befehl leicht umrahmen können, bietet Ihnen ein Dataset wahrscheinlich die beste Leistung. Aber wenn Sie feststellen, dass Sie wirklich auf
Ihrem Kopf stehen müssen, um zu versuchen, das zu gestalten, was Sie versuchen, in Bezug auf SQL-Befehle zu tun. Es wird nicht gut enden, richtig? Und manchmal sind RDDs das bessere Werkzeug. In diesem Fall wir
durch die Verwendung der niedrigeren RDD-Schnittstelle von Spark zu einer niedrigeren Ebene haben
wir
durch die Verwendung der niedrigeren RDD-Schnittstelle von Spark zu einer niedrigeren Ebeneeine viel bessere Leistung erzielt als durch die Verwendung der Dataset-API. Aber wenn wir wirklich etwas tun würden, das gut für
einen SQL-Stilbefehl geeignet war , der das mithilfe von Datasets implementiert. Und es gibt Funktionen, die sehr ähnlich wie SQL-Befehle aussehen, mehr Optimierungen
ermöglichen und bei solchen Problemen schneller wären. Und in der realen Welt, wissen Sie, das ist wahrscheinlich das häufigere Problem, das Sie mit Apache Spark bekommen werden. Normalerweise versuchen Sie, Dinge zu tun, wie Fragen zu protokollierten Daten, die eingehen. Wie viele Fehler habe ich im letzten Monat bekommen oder was auch immer es ist? Dinge wie das. Datensätze sind genial. Aber wenn Sie versuchen, etwas auf einer niedrigeren Ebene zu tun,
denken Sie daran, RDDs sind auch für Sie da, und Sie haben diese Funktionalität zur Verfügung.
38. Item-basierte Collaborative Filtering in Spark, Cache() und persistance(): Also als ein weiteres interessantes Beispiel komplizierte Dinge, die Sie mit Spark tun können , die Sie vielleicht nicht gedacht haben, dass Sie mit Spark tun könnten. Lassen Sie uns über objektbasierte kollaborative Filterung sprechen. Dies ist im Grunde ein Empfehlungs-Engine-Algorithmus. Es ist die Art und Weise, wie Amazon verwendet, Dinge zu tun, wie Leute, die
diese gekauft haben, auch gekauft oder empfehlen Dinge, um Sie basierend auf Ihren früheren Einkäufen. Die High-Level-Idee ist, dass wir
einen Blick auf die Sachen, die Sie in der Vergangenheit gekauft haben, suchen nach ähnlichen Artikeln wie die Sachen, die Sie gekauft haben, und dann empfehlen können diese Artikel uns,
Dinge, die Sie interessieren könnten. Und wir werden dies im Kontext von Filmen tun, die den MoviElens-Datensatz verwenden. Das Grundlegende, was wir brauchen, ist eine Messung von Filmen, die einander ähnlich sind, basierend auf Benutzerbewertungen. Das werden wir also hier machen. Und während wir dabei sind, werden wir auch
das Konzept vorstellen , Ihre Datensätze zwischenzuspeichern, um die Leistung zu verbessern. So ähnliche Filme, das ist ein kleiner Screenshot und ein älterer von den Grouplens-Websites. So haben sie tatsächlich eine Benutzeroberfläche, wo Sie Filme bewerten können, sagen Sie ihnen explizit die Bewegungen, die UV-Licht, und es wird Ihnen neue Filme empfehlen basierend auf diesen Bewertungen. Eine Möglichkeit, es zu tun, ist, einen Blick auf alle Filme zu werfen, die Ihnen gefallen haben. Und für all diese Filme, schauen Sie sich die ähnlichen Filme an wie diese Filme. Und diese Ähnlichkeiten basieren
auf anderen Benutzern, die die gleichen Filme mögen, die Sie mögen. Ok? Der grundlegende Algorithmus hier ist, dass wir anfangen werden, jedes Paar von Filmen zu
finden, die von derselben Person gesehen wurden. Unser Ziel ist es, alle Filme zu finden, die jedem anderen Film ähnlich sind. Ok? Um das zu tun, werden wir zuerst
jedes Paar Filme aufbrechen , die von denselben Personen gewaschen wurden. Also, wenn Benutzer a und Benutzer B den Film anschauen und ihn mochten, wäre
das ein Paar Filme. Jetzt können wir dann alle Benutzer, die diese Paare von Filmen mögen, zusammennehmen und die Ähnlichkeit ihrer Bewertungen
für alle von ihnen
messen , die beide Filme angesehen haben. Filme in Bezug auf Bewertungen, basierend auf jedem Benutzer, der dieses Paar Filme gesehen hat und es mochte Wie ähnlich sind dieseFilme in Bezug auf Bewertungen, basierend auf jedem Benutzer, der dieses Paar Filme gesehen hat und es mochte? Dann können wir diese alle nach der Film-ID gruppieren, sie
nach ihrer Ähnlichkeitsstärke sortieren. Das ist etwas, das wir basierend auf diesen Bewertungen berechnen. Und dann haben wir eine sortierte Liste von Filmen, die jedem anderen Film
ähnlich sind , nur durch diesen einfachen Algorithmus. Das ist also nur eine Möglichkeit, es zu tun. Kümmern Sie sich. Es gibt viele andere Techniken da draußen als gut, aber diese ist einfach und manchmal einfach wie besser. Es liefert gute Ergebnisse, wenn Sie genügend Daten haben. Lassen Sie mich Sie durch den Algorithmus und mehr eine grafische Art und Weise hier. Stellen Sie sich vor, dass N hier sowohl Star Wars als auch The Empire Strikes Back angesehen hat, was die SQL to Star Wars ist, bedeutet, dass Sie beide mögen. Und dann hat Bob hier, der Typ mit einem Mohawk, auch Star Wars und The Empire Strikes Back gesehen und sie beide auch gemocht. Basierend auf diesen Informationen können
wir sagen, dass wir hier ein Paar Filme haben, Star Wars und The Empire Strikes Back. Und beide hatten diese beiden Benutzer gemeinsam, die beide mochten. Also für dieses Paar wissen
wir, dass Benutzer und Benutzer Bob beide mögen und stellen wir uns vor, sie beide gaben ihnen fünf Sterne. Auf dieser Grundlage können wir berechnen, dass es sich um
sehr ähnliche Filme handelt, die auf diesem Nutzerbewertungsverhalten basieren. Von den drei Personen in unserem Datensatz. Zwei von ihnen beide liebten dieses Paar Filme, oder? Das würde also zu einem sehr guten Ähnlichkeitswert führen. Wir könnten uns jedoch dafür entscheiden, das zu messen. Stellen wir uns vor, Ted hier unten kommt vorbei und er sah nur das Imperium schlägt zurück. Vielleicht ist er gerade hierher gezogen und kam aus einem Land, in dem Star Wars keine große Sache ist. Das ist okay. Aber irgendwie weiß er nicht, dass der erste Film, Star Wars, eine New Hope tatsächlich existierte. Also, wie empfehlen wir ihm, was er sonst
interessiert sein könnte , auf der Grundlage der Informationen, die wir hier haben. Nun, wir können sagen, okay, wir kennen Ted, du mochtest Empire Strikes Back. Und wir wissen aus unserer vorherigen Berechnung, dass der ähnlichste Film,
The Empire Strikes Back Star Wars a New Hope, der erste Film ist? Und wieder, diese Ähnlichkeit basierte auf dem Bewertungsverhalten der anderen Benutzer in unserem Datensatz. Also, das ist es auf einem hohen Niveau. Grundsätzlich können wir Filme empfehlen, die den Filmen ähneln, die Sie
geliebt haben , basierend auf dem Bewertungsverhalten der anderen Personen in unserem Datensatz. Und das ist eine objektbasierte kollaborative Filterung auf den Punkt gebracht. Letztendlich empfiehlt das Ted einen guten Film, von dem er vielleicht vorher nicht wusste. Jetzt werden wir uns hier in dieser Aktivität
auf die Ähnlichkeit des Films konzentrieren . Wir werden also keine vollständigen Empfehlungen für Leute machen, aber wir werden diesen Datensatz mit Film-Ähnlichkeiten berechnen. Welche Filme ähneln anderen Filmen basierend auf dem Benutzerverhalten. Das ist irgendwie der schwierige Teil, oder? Denn sobald Sie diese Daten haben, können
Sie sehr
schnell Empfehlungen an Menschen aussprechen, basierend auf den Dingen, die ihnen zuvor gefallen haben. Sie könnten sich also sagen,
wie zum Teufel können wir das in Spark machen? Spark ist in diesen Tagen um ein SQL-Paradigma gebaut, oder vielleicht bestenfalls ein MapReduce. Wie rahmen Sie dies als ein Problem ein,
das in dieses Framework passt und etwas, das Sie parallelisieren können. Nun, du kannst, du musst nur kreativ darüber nachdenken. Und wieder, weißt du, in der Lage zu sein, über
diese Probleme auf kreative Weise nachzudenken , ist das, wofür sie dir die großen Dollar zahlen. Es ist also ein Beispiel dafür, wie Sie
diese Technologie verwenden können , um ein Problem zu lösen, das Sie vielleicht nicht für geeignet gehalten haben. Hier ist der allgemeine Algorithmus, den wir in unserem Spark-Beispiel verwenden werden. Also beginnen wir mit der Auswahl der Benutzer-IDs, Film-IDs und Bewertungen. In diesem Beispiel kümmern wir uns nicht wirklich um die Zeit, obwohl Sie sich eine Welt vorstellen können, in der Sie diese Informationen auch verwenden. Wir finden dann jedes Filmpaar, das vom selben Benutzer bewertet wurde. Und das klingt vielleicht wie eine knifflige Sache, aber es stellt sich heraus, mit einer selbst-adjoint Operation, die sehr viel eine Datenbank-Art ist. Das ist genau das, was es dir geben wird. Grundsätzlich nehmen Sie den Satz von Benutzerfilm- und Bewertungsspalten und verbinden sich, dass auf sich selbst basierend auf der Benutzer-ID. Und das wird Ihnen jedes mögliche Paar von Filmen geben, die von der gleichen Person bewertet wurden. An diesem Punkt können wir unser selbst verbundenes Dataset neu gestalten, um Film eins zu haben, Film zu bewerten und zwei Spalten zu lesen, die uns die Filmpaare und die damit verbundenen Bewertungen
erzählen. Und wieder, an dieser Stelle, wird dies für
jeden einzigartigen Benutzer getan , der diese beiden Filme zusammen bewertet. Wir können dann durchgehen und herausfiltern, während wir dabei sind alle doppelten Paare, weil eine Bewertung von Film eins, um die beiden zu bewegen, dasselbe ist wie Film zu Film eins. Also werden wir eine Heuristik haben, um sicherzustellen, dass wir nur eine dieser beiden Varianten
erfassen. Sobald wir das haben, können wir durch jeden Benutzer gehen, der dieses Paar von
Filmen bewertet hat, und die Kosinus-Score basierend auf diesen Informationen berechnen. Ich möchte nicht in die Mathematik davon eingehen, weil es für die Apache Spark-Entwicklung nicht wirklich relevant ist. Aber wenn Sie neugierig sind, wie Kosinusähnlichkeit funktioniert, ich, es gibt einen anderen Kurs, den ich auf
Empfehlungssystemen habe , der in mehr Tiefe drauf kommt. Aber auf hohem Niveau, wenn Sie einen Blick auf alle Benutzerbewertungen für einen Film werfen, können
Sie sich das als eine Art mehrdimensionalen Vektor vorstellen. Und eine Kosinus-Score wäre im Grunde der Winkel zwischen zwei Vektoren für zwei verschiedene Filme, basierend auf den Benutzerbewertungen, die sie gemeinsam haben. Sobald wir das haben, können wir alles nach dem Film eins gruppieren, zwei Paare
filmen und sicherstellen, dass wir alles
zusammen für ein bestimmtes Filmpaar zusammenfassen , die Kosinusähnlichkeit über alle Benutzer
berechnen, die dieses Paar bewertet haben von Filmen. An dieser Stelle haben wir einen Datensatz, der jede mögliche Kopplung von
Filmen und die Ähnlichkeitsnote zwischen diesen Filmpaaren enthält . Wir können dann einfach filtern und sortieren und die Ergebnisse anzeigen. So können wir diese nach jeder einzelnen Film-ID gruppieren, Dinge
herausfiltern, die unter einer
Art Ähnlichkeitsschwelle liegen, um sicherzustellen, dass wir nur starke Ähnlichkeiten
erfassen und sie
nach diesem Ähnlichkeitswert und zeigen Sie die Endergebnisse. Und das wird uns letztendlich die Ähnlichkeitsnote von jedem Film zu jedem anderen Film geben. Bevor wir also in den Code eintauchen, lassen Sie mich die Idee vorstellen,
Datasets zwischenzuspeichern , da dies in diesem Beispiel auftauchen wird. Wenn Sie komplizierte Dinge wie diese erledigen,
werden häufig ein Dataset mehr als einmal abgefragt oder verwendet. Und wenn Sie das tun, sollten
Sie es explizit zwischenspeichern, wenn Sie können. Andernfalls besteht die Möglichkeit, dass Funken
das gesamte Dataset erneut ein zweites Mal neu bewertet , nur um diesen zweiten Vorgang auszuführen. Und wenn Sie sicherstellen möchten, dass dies nicht geschieht, können
Sie Punktgeld für ein Dataset verwenden, nachdem Sie mit der
Berechnung fertig sind , um sicherzustellen, dass es im Speicher bleibt. Alle nachfolgenden Vorgänge oder Analysen, die
Sie für dieses Dataset durchführen, erfolgen so schnell wie möglich. Es gibt auch nicht bestehen. Persist ermöglicht Ihnen optional, dass nicht nur ein Speicher, sondern auch auf der Festplatte zu fangen. Wenn also ein Knoten ausfällt oder etwas, können
Sie von diesem Punkt aus wiederherstellen und einfach dort aufheben, wo Sie aufgehört haben. So wird Bargeld im Speicher sein, Persists können optional auch auf der Festplatte gespeichert werden. Und damit springen wir zum Code und sehen, wie es aussieht.
39. [Aktivität] Durchführen des ähnlichen Movies mit Sparks Cluster-Manager: In Ordnung, lasst uns hier in den Code springen, um Film-Ähnlichkeiten mit Spark zu berechnen. Öffnen Sie also das Film-Ähnlichkeits-Dataset-Skript hier. Und dies ist ein Fall, in dem die Verwendung eines Datasets mit einer RDD übertrifft. Der wirklich komplizierteste Teil dieses ganzen Algorithmus ist die Self-Join-Operation, bei der wir versucht haben, jedes einzigartige Paar von Filmen zu finden, die von der gleichen Person bewertet wurden. Und das ist eine sehr SQL-Art zu tun, oder? Eine Self-Join-Operation. Dies passt also gut in die Ideen, ein Dataset in Spark SQL zu verwenden. Es ist möglich, dies auch mit RDDs zu tun, aber in diesem Fall übertreffen
Datasets RDDs, was normalerweise der Fall ist. Wir werden uns also auf Datensätze für diesen konzentrieren. Wenn Sie krankhaft neugierig sind, wie man dies mit RDDs macht, gibt es auch hier
ein Film-Ähnlichkeitsskript , das es einfach mit RDDs stattdessen tut. Aber konzentrieren wir uns auf Datensätze. Also, was haben wir hier? Nun, wir fangen an, alles zu importieren, was wir brauchen, wie gewohnt. Und wir deklarieren ein Film-Ähnlichkeits-Dataset-Objekt, das mehrere Fallklassen enthält. Diese definiert die verschiedenen Dateiformate, die wir einlesen und für die Datensätze verwenden, die wir auf dem Weg in unserem Algorithmus verwenden. Wir haben also ein Film-Dataset, das nur das Format der Rohdaten
spiegelt, in denen wir lesen. Es besteht aus einer Benutzer-ID-Ganzzahl, einer Film-ID-Ganzzahl oder einer Bewertungs-Ganzzahl und einem langen Zeitstempel. Wir werden auch ein Film-Namen-Dataset laden, so dass wir
sehr einfach die menschenlesbaren Namen der angegebenen Film-ID anzeigen können . Das wird nur Film-IDs zu Filmtiteln zuordnen. Wir werden auch einen Filmpaare Datensatz auf dem Weg haben, und dies verkörpert ein einzigartiges Paar von Filmen. Dies ist eine Art von der Ausgabe dieser Self-Join-Operation, bei wir jeden Satz von Film erhalten, der von der gleichen Person bewertet wurde. Und das besteht sowohl aus der Film- als auch der
Film-zu-Film-IDs und den Bewertungen, die mit jedem dieser Filme von einem bestimmten Benutzer verknüpft sind. Eine Reihe von Filmpaaren besteht also einem Paar von Filmen und deren Bewertungen von einem einzelnen Benutzer, der sie beide gesehen hat. Hab es. Und dann haben wir auch einen Film Pariser Ähnlichkeitsdatensatz irgendwann, der ein Paar Filme, Film 1,
einen Film zu einem Ähnlichkeitswert im Format mit doppelter Genauigkeit enthält , und die Anzahl der Paare, die in der Berechnung zugeordnet wurden, die Ähnlichkeits-Score. Das wird also widerspiegeln, wie viele Nutzer tatsächlich dieses Paar Filme angesehen und sie zusammen bewertet haben. Lassen Sie uns zur Hauptfunktion überspringen und von dort arbeiten. Wir beginnen damit, unseren Log-Level zu setzen und ein SparkSession-Objekt zu erstellen. Wie immer. Anschließend erstellen wir ein Filmnamen-Schema, das später für die
Strukturierung unseres Datensatzes verwendet wird , um Film-IDs in Filmtitel nachzuschlagen. Es sagt nur, dass unsere Film-ID eine ganze Zahl sein wird, und es wird einen Filmtitel für jede Film-ID, die eine Zeichenfolge ist, haben. Wir werden dann ein Schema für die Daten deklarieren, die Film-Bewertungsdaten selbst. Das wird Benutzer-ID, Film-ID, Bewertung
und Zeitstempel in der Struktur haben , die wir
zuvor gesehen haben , werden dann diese Filmnamen laden. In einem ersten Schritt importieren wir auf Implicits ausgelöst, da wir zunächst einen DataFrame
laden und diesen dann in ein Dataset konvertieren. Um also implizit das Schema eines DataFrames abzuleiten, obwohl wir Ihnen einen zur Verfügung stellen, müssen
Sie trotzdem Spark-Punkt-Implikits für diesen Schritt verwenden. Also sagen wir es, dass bestimmte Datendatei, Sie Punkt Element wird durch ein Pipe Trennzeichen getrennt. Es ist im ISO 8859 Bindestrich ein Zeichensatz. Und es verwendet das Filmnamen-Schema, das wir explizit bereitstellen da es keine Header-Zeile in dieser Datei gibt, die wir verwenden können, um sie abzuleiten. Und wenn wir damit fertig sind, werden wir es explizit in einen Datensatz konvertieren, indem wir die Fallklasse für bewegte Spiele
verwenden, um eine noch bessere Leistung unter Spark zu erzielen. Wir haben uns dann die Film-Bewertungen Daten selbst angesehen, wieder ist ein Datensatz. Dieselbe Idee hier. Diese ist tatsächlich Tab getrennt mit dem Filmschema, das wir oben definiert haben. Und wir werden das auch in einen Datensatz mit der Film-Fallklasse konvertieren. Also an dieser Stelle haben wir ein Film-Namens-Dataset und wir haben ein Film-Dataset, das alle einzelnen Benutzerbewertungen darstellt. Wir werden dann die Informationen auswählen, die uns wichtig sind, nur um zu verhindern, dass wir Informationen, die wir nicht benötigen, herumtragen. So wird unser Bewertungsdatensatz nun nur die Benutzer-ID, Film-ID und Bewertung sein. Abgesehen von der, die Zeitstempelspalte, weil wir diese Informationen nicht wirklich für das brauchen, was wir hier tun. Hier wird es interessant. Dies ist diese Self-Join-Operation, über die wir zuvor gesprochen haben. Also werden wir einen Film-Paris-Datensatz haben. Es ist beabsichtigt, jedes Paar von Filmen zu enthalten, die von der gleichen Person bewertet werden. Die Art und Weise, wie wir das tun, ist zunächst, wir werden unseren Bewertungsdatensatz nehmen. Wir werden ihm einen Alias von Bewertungen eins geben, damit wir es leicht verweisen können. Und wir werden das mit einer anderen Kopie
des Radius-Datasets verbinden , das als Bewertungen bezeichnet wird. Also werden wir einen Join zwischen Bewertungen
eins und Bewertungen machen , zu denen wirklich die gleiche Sache sind. Beide zeigen auf das Bewertungs-Dataset. Deshalb nennen wir dies einen Self-Join. Wir verbinden den Bewertungsdatensatz für sich selbst, und wir werden es basierend auf der Benutzer-ID-Spalte verbinden. Okay, wir sagen also, dass wir nur beitreten werden, wenn eine Benutzer-ID oder eine Bewertung mit Benutzer-ID und Bewertungen übereinstimmt. Dies wird also den Effekt haben, alle Filme, die von derselben Person bewertet wurden,
miteinander zu koppeln . Hab es. Sie müssen irgendwie verstehen, wie Join-Operationen in SQL funktionieren. Und das ist nicht wirklich eine SQL-Klasse, aber das ist, was Sie hier aus diesem Ausdruck herausbekommen. Jedes Paar Filme, die von der gleichen Person bewertet wurden. Und darüber hinaus, während wir dabei sind, wir erzwingen, dass die Film-ID für Bewertungen werden
wir erzwingen, dass die Film-ID für Bewertungen
eins kleiner ist als die Film-ID, die von Bewertungen zu kommt. Und wir tun das nur, um Duplikate zu verhindern. Also wieder, wir wollen keinen separaten Eintrag für Bewertungen, die man mit Lesungen gepaart hat, wie wir es für Bewertungen mit Bewertungen eins tun würden. Indem wir dies tun, stellen wir sicher, dass wir nur eine einzigartige Paarung dort erfassen. Sobald wir das haben, können wir dann Dinge umbenennen, um es einfacher zu bedienen. Also werden wir Bewertungen eine Punkt-Film-ID in Film eins umbenennen, Lesungen heute auf Film ID zu Film zwei,
Bewertungen, wenn ich lese, um ein und Bewertungen zu Punkt lesen 2, Schreiben 2, wieder, nur um es einfacher zu machen, mit. Und darüber hinaus werden wir dies explizit zu einem Datensatz machen indem wir die Filmpaare Fallklasse verwenden, die wir oben definiert haben. Jetzt haben wir hier zur Verfügung, dass Filmpaare Datensatz, der Paare von Filmen und ihre Bewertungen für
jeden einzigartigen Benutzer
schmerzt , der dieses Paar von Filmen bewertet hat. Angesichts dessen können wir jetzt Compute
Cosinus-Ähnlichkeit aufrufen, um unseren Film Paris-Ähnlichkeiten Datensatz zu konstruieren, der für jedes Paar von Filmen
enthalten wird , wie ähnlich sie
einander sind , basierend auf allen Benutzern, die diese Filme bewertet haben zusammen. Bevor wir also weiter gehen und über diese Cache-Operation sprechen, schauen
wir uns an, was die Computing-Cosinus-Ähnlichkeit bewirkt. Das ist hier oben, irgendwo. Da ist es. Also gibt es hier ein bisschen ausgefallene Mathematik. Ich möchte nicht wirklich in die Kosinus-Ähnlichkeitsmetrik
selbst einsteigen , weil das nicht wirklich etwas mit der Spark-Programmierung zu tun hat. Auch wenn Sie mehr darüber erfahren möchten, können
Sie sich meinen Kurs über Empfehlungssysteme ansehen. Aber auf hohem Niveau erstellen
wir hier drei neue Spalten. Xx und XY. Das wird x quadriert, y quadriert und x,
y aus dem Algorithmus berechnen, den wir für die Berechnung der Kosinusähnlichkeit verwenden. Wieder, es ist nur im Grunde ein, ein Winkel zwischen zwei virtuellen Vektoren in diesem Benutzerfilmbereich. Wir können dann diese Ähnlichkeitswerte berechnen. Daher verwenden wir im Grunde diesen neuen Datensatz namens Pariser Partituren. Es hat diese zusätzlichen Bedingungen, es ist angehängt. Und dann nennen wir Ei, um alle Einträge für jedes Filmpaar zusammenzufassen, sie verwenden den folgenden Ausdruck. Also für alle Filmpaare, für alle Benutzer bei bewertet diese zwei Filme zusammen. Wir werden sie alle mit dieser Agg-Funktion übertreffen. Und wir werden die X,
Y Spalten zusammenfassen und nennen, dass der Zähler. Das wird nur der Zähler unseres Ausdrucks für die Berechnung der Kosinusähnlichkeit sein. Und dann für den Nenner, dass Routing Sie, dass der früheste Nenner, der am Ende wird die Quadratwurzel der Summe der XX Spalte und Quadratwurzel der Summe der y, y Spalte zusammen. Und schließlich werden wir die Nicht-Paare haben, die nur zählen werden, wie viele der x-y-Spalte existiert. Das ist nur eine Abkürzung, um herauszufinden wie viele Nutzer dieses Paar Filme tatsächlich bewertet haben. Und das sind Informationen, die wir brauchen, um tatsächlich die tatsächliche Ähnlichkeitsbewertung zu berechnen, was hier in diesem Ergebnisdatensatz landen wird, wir fügen einfach eine neue Punktespalte hinzu. Und was wir tun, ist, dass wir zuerst sicherstellen, dass wir nicht durch 0 dividieren werden. Wir überprüfen explizit, um sicherzustellen, dass der Nenner nicht 0 ist. Ansonsten haben wir nur ein Null-Ergebnis dort. Wenn nicht, dann teilen wir einfach den Zähler durch den Nenner. Und an diesem Punkt haben wir unsere tatsächliche Ähnlichkeitsbewertung basierend auf der Metrik der Kosinusähnlichkeit
berechnet. Wir setzen das dann einfach auf die Spalten, die uns wichtig sind,
was Film eins und Film sein wird, um die Ähnlichkeit zwischen ihnen und die Anzahl der Paare, die diese Partitur unterstützen. Und wir werden das auch in einen Datensatz mit
den Filmpaaren Ähnlichkeit Fallklasse oben zwingen und das Ergebnis-Dataset zurückgeben, das wiederum an dieser Stelle nur Film einen Film enthält, um zu punkten und nicht Paare, die, Ordnung, zurück zu wo das genannt wurde. So haben wir jetzt diesen Datensatz
aller Ähnlichkeitswerte zwischen jedem einzigartigen Paar von Filmen. Und das werden wir wahrscheinlich mehr als einmal verwenden. Also lassen Sie uns voran gehen und das zwischenspeichern, so dass wir das im Speicher haben werden, als praktisch zu gehen. Egal, was wir später damit machen werden. Wir werden dies nicht nur verwenden, um unsere Ergebnisse anzuzeigen, aber Sie könnten sich vorstellen,
wir könnten tatsächlich ein wirkliches artikelbasiertes kollaboratives Filtersystem daraus erstellen, indem wir das Filmpaar-Ähnlichkeits-Dataset im Speicher behalten. Wir können dann die Menge von allem, was jeder neue Benutzer hat gemocht oder geäußert Interesse an dort, oder hoch bewertet, was auch immer Sie als Hinweis auf Interesse verwenden wollen und dann getroffen , dass Film Paris Ähnlichkeit Zustand ist auf sehr eingestellt schnell wieder alle ähnlichen Filme zu den Filmen AP Person Licht. Also wieder, das wäre sehr wichtig, um Geld zu bezahlen, wenn Sie hier ein echtes Empfehlungssystem bauen würden. Aber alles, was wir hier tun werden, ist nur versucht, die Ergebnisse
der Top-Ähnlichkeiten für einen bestimmten Film zu bekommen . Also werden wir überprüfen, ob wir hier ein Argument übergeben. Also die Idee hier ist, dass wir als Argument an dieses Skript übergeben werden, eine Film-ID, die wir daran interessiert sind, alle Ähnlichkeiten zu sehen. Und darüber hinaus werden wir hier einige Schwellenwerte festlegen. Wir werden also sagen, dass
wir es nicht ähnlich genug halten, um interessant zu sein, wenn es keine 97% Ähnlichkeit zwischen zwei Filmen gibt. Und wir werden auch sagen, dass Sie
mindestens 50 Benutzer gemeinsam haben müssen , die beide Dinge zusammen bewertet haben. Das ist also die minimale Unterstützung, die wir brauchen, um
zuversichtlich zu sein, dass dies ein zuverlässiges Ergebnis ist. Sie wollen keine Empfehlung machen, basierend auf dem, was zwei Leute gesagt haben. Idealerweise möchten Sie, dass viele Menschen, die miteinander übereinstimmen, Ihnen ein besseres Ergebnis geben. Also diese Schwellenwerte und ein Wesen wichtig, um
qualitativ hochwertige Ergebnisse zu erhalten , und sie sind eher willkürlich, aber wir werden darauf zurückkommen. Also werden wir diese Filter hier anwenden. Wir filtern das Film-Paris-Ähnlichkeits-Dataset und filtern es nicht nur, um diese Punkteschwellen zu erzwingen, um
sicherzustellen, dass die Punktzahl größer als die Schwelle der Schulpunktzahl war. Und keine Paare sind größer als der Anfangsschwellenwert für das gemeinsame Auftreten. Aber wir werden es auch nach der Film-ID filtern, an der wir interessiert sind. Also für den Film, den wir als Argument übergeben haben, das ist der Film, den wir sehen wollen, ähnliche Filme auch. So erzwingen wir, dass Film eins gleich Film-ID ist oder Film zwei gleich Film-ID ist. Wir wissen nicht wirklich, ob es auf dem Film eins oder auf dem Film an Seite sein wird, es könnte entweder abhängig von der Reihenfolge der Film-IDs sein, oder? Also, wenn einer der Filme im Filmpaar derjenige ist, an dem wir interessiert sind. Wir werden das aufheben und prüfen,
ob auch unsere Qualitätsschwellenwerte eingehalten werden. Sobald wir das haben, werden wir diese absteigend basierend auf dieser Partiturspalte sortieren, um die ähnlichsten Filme zu diesem Film zu bekommen und die Top 10 zu nehmen. Also würden wir dies als Top n Recommender System Sprachgebrauch bezeichnen, weil wir die Top 10 Ergebnisse
nehmen, um unsere Empfehlungen für diesen Film zu machen. Und dann drucken wir es aus und wir sagen einfach die Top 10 ähnlichen Filme für was auch immer dieser Filmname ist, um das für Menschen lesbar zu machen. Wiederum verwenden Sie dieses Film-Namen-Dataset, das wir vor
langer Zeit für diese Film-ID geladen haben . Und für jedes einzigartige Ergebnis, das wir zurückbekommen, durchlaufen wir es und extrahieren diesen ähnlichen Film basierend auf Filmkennung nicht die, die wir als Parameter übergeben haben. Drucken Sie dieses Ergebnis zusammen mit seiner Punktzahl und der Stärke basierend auf der Anzahl der Paare aus, die diese Punktzahl unterstützt haben. Wer? Also hey, es sieht so aus, als sollte das funktionieren. Weißt du, es war eine Menge zu reden, aber wenn man sich den Code für alles anschaut, tut
es das, es ist wirklich nicht so viel Code, oder? So schlimm ist es nicht. Ich meine, es gibt ein paar flippige Sachen, die sicher vor sich gehen. Sie NED, wickeln Sie Ihren Kopf um mit diesen komplizierteren Ausdrücken hier wie diesem Aggregat hier oder der Self-Join-Operation. Aber sobald man das überdauert, ist es nicht so viel Code. Also lassen Sie uns gehen und es laufen und sehen, was passiert, bevor wir es ausführen, aber wir müssen den Parameter übergeben, welche Film-ID wir zurückbekommen wollen, richtig? Um das zu tun, haben wir Ihnen das kleine knifflige und Intelligenz gezeigt. Klicken Sie mit der rechten Maustaste auf Film-Ähnlichkeiten und wir werden sagen, Erstellen Sie Film Ähnlichkeiten. Dadurch wird eine Laufkonfiguration erstellt, die wir explizit einrichten können. Und das hat hier einen Schlitz für Programmargumente. So können Sie die Film-ID, die Sie wollen, hier für jeden Film, an dem Sie interessiert sind, sagen
wir 56, was auch immer das ist. Und wir werden sagen: Okay. Und jetzt hier oben haben wir die Film-Ähnlichkeiten laufen Konfiguration, die wir gerade definiert haben. Und wir können den Play-Button drücken, um es auszuführen. Also lasst uns das loslegen und sehen, was passiert. Ab geht es. Wir haben unsere Filmnamen geladen und jetzt ist es nicht wirklich, diese Ähnlichkeiten zu berechnen. Und dort haben wir unsere Ergebnisse. Das ist also ziemlich gut. Das war eine ziemlich kleine Menge an Zeit für eine sehr komplizierte Operation. Und einen Self-Join auf einem großen Dataset zu machen, ist keine kleine Leistung, oder? Und ja, wir haben die besten Ergebnisse für Pulp Fiction. Es stellt sich heraus, dass es das ist, was Film ID 56 ist, und es ist irgendwie ein gieriger Film. Und das kam mit mehr gritty Filmen zurück. Also schien es tatsächlich zu funktionieren. Ich habe schon mal Rauch gesehen. Ich mag keine Zugspaltung, also bin ich mir nicht sicher, ob ich das selbst sehen will, aber Reservoir Dogs, Dani Brass gehen. Wahre Romantik. Dies sind alle vernünftige Ergebnisse für eine ähnliche Filme wie Pulp Fiction basierend auf anderen Benutzerbewertungen. Also da hast du es. Wenn Sie vorhaben, Leute zu bauen, die diesen Film
mochten auch auf Netflix oder so etwas. Sie wissen jetzt, wie das geht, und Sie könnten das tatsächlich mit Apache Spark skalieren um eine riesige Menge an Bewertungen oder eine riesige Anzahl von Filmen zu verarbeiten. Weil Sie jetzt tatsächlich einen ganzen Cluster darauf werfen können. Also da hast du es. Ein Beispiel für einen Film Ähnlichkeiten und Element-basierte kollaborative Filterung, zumindest die erste Hälfte davon mit Apache Spark. Und wie Sie später sehen werden, gibt es tatsächlich eine integrierte Funktion in der Machine Learning-Bibliothek für Apache Spark, die etwas Ähnliches macht, aber es erzeugt keine Ergebnisse, die mit dem MoveLens-Dataset gut sind. Manchmal ist
die Verwendung der Standard-Tools nicht gut genug, und Sie müssen zurückgehen und irgendwie erfinderisch
sein und
neue Algorithmen mit Spark implementieren ,
die vielleicht noch nie in Spark gesehen wurden , ist, was sie die großen Mäuse für Jungs bezahlen werden. Aber das ist ein gutes Beispiel, und wir werden das einschließen. Bevor wir es aber tun, werde
ich Sie herausfordern, das wirklich besser zu machen. Lassen Sie uns darüber in unserem nächsten Vortrag sprechen.
40. [Übung der Qualität ähnlicher Filme verbessern: Es stellt sich also heraus, dass Film-Ähnlichkeiten ein paar Gründen irgendwie nah und am Herzen liegen. Zunächst einmal war das meiste, was ich während meiner Arbeit bei Amazon.com getan habe im Bereich der kollaborativen Filterung und deren Empfehlungssysteme für Benutzer
tätig. Ich habe lange damit verbracht, diese Systeme dort zu verbessern. Und es war lustiges Zeug. Es, es ist wirklich interessante Arbeit, auch ich habe IMDB für eine Weile ausgeführt. Das ist also eine Art Schnittpunkt aus kollaborativem Filtern und Filmen, die ganze Menge meiner Kurse durchdringt. Meine Herausforderung für Sie besteht also darin, die Ergebnisse besser zu machen. Und es gibt wirklich keine richtige oder falsche Antwort darauf, richtig. Die Sache mit Empfehlungen ist, dass sie oft eher qualitativ sind. Ich meine, Sie können sie messen, basierend darauf, wie Menschen in der realen Welt auf sie reagieren. Aber am Ende des Tages musst
du irgendwie selbst beurteilen, ob sie gut sind oder nicht. Also meine Empfehlung sieht, was ich dort getan habe. Empfehlung, meine Empfehlung an Sie ist, einen Film zu finden, den Sie
leidenschaftlich lieben und feststellen, dass in der MoveLens Dataset Lookup, es ist Film-ID. Und wenn es einen Film gibt, mit dem Sie wirklich vertraut sind, haben
Sie ein gutes intuitives Gefühl, was gut ähnliche Filme wie dieser Film sein könnten. Beginnen Sie also, indem Sie das Skript ausführen, das wir gerade
für die Film-ID hatten , die Sie so gut kennen und lieben. Und urteilen Sie selbst, ob das
gute Empfehlungen sind und darüber nachdenken, wie diese besser sein könnten? Also hier sind einige Ideen von Dingen, die Sie tun können, um
dieses Skript zu ändern , um die Qualität dieser Empfehlungen weiter zu verbessern, eine Idee, es wäre, einfach alle schlechten Bewertungen zu verwerfen. Also, wenn jemand einen Film schreibt, ein oder zwei Sterne, wollen wir wirklich, dass unser Maß beeinflusst, wie ähnlich Film ist? Eine Art von Fallstrick dieses Algorithmus ist,
dass Filme , die ähnlich sind in Bezug auf alle hassten sie würden immer noch als ähnliche Filme erscheinen. Das ist also nicht unbedingt eine gute Sache, wenn Sie versuchen,
gute Filme zu empfehlen , die sie vielleicht sehen wollen. Das ist also eine Idee. Gerade einen anderen Filter eingeführt, der
alle schlechten Bewertungen von Anfang an loswird und sehen, welchen Unterschied, der auf das Ergebnis hat. Sie können auch verschiedene Ähnlichkeitsmetriken ausprobieren. Sie müssten diese jetzt nachschlagen, Grund für Kosinusähnlichkeit, aber es gibt alternative Metriken, wie Pearson-Korrelationskoeffizient, Jaccard-Koeffizient oder einfach nur bedingte Wahrscheinlichkeit. Vielleicht möchten Sie diese nachschlagen und versuchen, das
anstelle der Kosinusmetrik zu implementieren und zu sehen, ob das besser oder schlechter geht. Sie können auch mit diesen Schwellen spielen und es ist wahrscheinlich das einfachste, was zu tun ist. Vielleicht sollten Sie mehr minimale Kuratoren oder
eine höhere Mindestpunktzahl haben , um es in den letzten Schnitt zu schaffen. Das wird einen Kompromiss oder eine Abdeckung haben, wissen Sie, wenn Sie mehr obskure Filme haben, haben
Sie möglicherweise nicht genug Daten, um tatsächlich eine Empfehlung abzugeben, wenn Sie diese Schwellenwerte zu hoch setzen. Oder Sie könnten Ihre eigene neue
Ähnlichkeitsmetrik erfinden , die eine Reihe von Kooperationspartnern berücksichtigt. Vielleicht ist die Anzahl der Leute, die
das Paar Filme gesehen haben , an sich ein Indiz dafür, wie gut diese Filme sind. Vielleicht nur die Tatsache, dass sie populär sind. Und viele Leute haben sie beide gesehen, ist etwas, das Sie berücksichtigen sollten. Vielleicht können Sie das irgendwie normalisieren und das auch in Ihre Ähnlichkeitsmetrik
einführen. Und wenn Sie wirklich ehrgeizig werden wollen, können Sie sogar Genre-Informationen aus der UE Punkt-Items Datendatei und dem Movielens Dataset, das ein Array von
Nullen und Einsen enthält , die angibt, zu welchen Genres und Film gehört. Und vielleicht könnten Sie Filme herausfiltern, die sich in verschiedenen Genres befinden oder die Ähnlichkeit von Filmen
steigern, die viele Genres gemeinsam haben. Also einige allgemeine Ideen gibt und wie man die Ergebnisse besser machen könnte. Auch hier gibt es keine richtige Antwort. Ich kann Ihnen nicht zeigen, wie die richtige Antwort auf diese Aktivität. Ich möchte nur, dass du mit ihm spielst und siehst, ob du die Ergebnisse verbessern kannst. Und wenn Sie das tun, wäre ich sehr neugierig zu hören, was Sie getan haben, entweder in den Kommentaren oder im Q und einem oder einem Mechanismus dem die Plattform, auf der Sie sich diesen Kurs ansehen, gibt Ihnen Feedback. Also haben Sie es, es ist eigentlich eine lustige Aktivität und eine sehr wichtige
zu einer Menge von E-Commerce hängt von Empfehlungen ab. Also, wenn du lernen kannst, wie man das macht, ist es eine gute Sache. Geh los und spiel damit. Und dann kommen wir im nächsten Abschnitt wieder und reden über die Skalierung der Dinge.
41. [Aktivität] spark-submit zur Ausführung von spark-submit: Bisher haben wir in diesem Kurs auf Ihrem lokalen Desktop-PC entwickelt, weil, na ja, das ist billig und einfach, richtig? Ich will nicht einen Haufen Geld ausgeben, wie Sie dieses Zeug unbedingt lernen, aber es ist Zeit, die Dinge zu skalieren. In diesem nächsten Abschnitt werden wir also über die Ausführung von Spark
auf einem echten Cluster B sprechen , den ein Cluster besitzt, den
Sie begleiten, oder einen Cluster, den Sie möglicherweise einen Dienst wie Amazon Web Services
mieten. Es gibt einige besondere Überlegungen, wenn Sie Ihre Treiberskripts für die Verwendung in einem Cluster
schreiben. Und bestimmte Möglichkeiten, wie Sie Ihren Code bereitstellen und Ihren Code verpacken und Ihren Code ausführen, wenn er sich in einem tatsächlichen Cluster befindet. Lassen Sie uns also auf diese Details eingehen und dies sollte Sie mit dem Wissen bewaffnen, das Sie brauchen, um Spark tatsächlich in einer echten Produktionsumgebung im großen Maßstab zu verwenden. Bisher haben wir in diesem Kurs unsere Spark-Anwendungen auf
unserem Desktop innerhalb der Intelligence-Umgebung ausgeführt . Und das ist alles gut und gut für die Entwicklung. Aber wenn Sie tatsächlich eine Spark-Anwendung in der realen Welt ausführen möchten, werden
Sie sie wahrscheinlich irgendwo in
einem Cluster bereitstellen und nicht in IntelliJ a, Sie werden in der Lage sein, dies von irgendeine Art von Cron-Job oder irgendeine Art von Management-System, das
Ihre Scala-Anwendung auf einer Art von Zeitplan starten wird, richtig? Also, wie machen wir das? Nun, lassen Sie uns beginnen, indem wir darüber sprechen, wie Sie
Ihre Anwendung packen und bereitstellen und sie von
außerhalb der Intelligenz und nur von einer Befehlszeile irgendwo ausführen . Also in der realen Welt, auf einem Cluster werden
unsere Skripte mit etwas namens Spark dash submit ausgeführt . Wenn Sie also Apache Spark installieren, kommt
es mit einer Anwendung namens Spark submit. Und seine Aufgabe besteht darin, eine JAR-Datei einzulesen, die
Ihre kompilierte Spark-Anwendung enthält , und diese an Ihren gesamten Cluster zu verteilen, um ausgeführt zu werden. Und es kann all das außerhalb der Intelligenz tun. Es ist alles völlig eigenständig. Bevor Sie dies tun, gibt es einige Dinge, die Sie sicherstellen müssen. zunächst sicher, dass Sie keine Pfade zu
Ihrem lokalen Dateisystem innerhalb Ihres Skripts hinterlassen haben, richtig? So haben wir in unseren Beispielen bisher auf Dateien verwiesen , die auf unserem lokalen Dateisystem auf einem relativen Pfad existieren, von wo sich unser Projekt befindet. In der realen Welt möchten Sie sicherstellen, dass Ihre Datendateien für jeden Knoten auf Ihrem Cluster
zugänglich sind , der Ihre Anwendung ausgeführt wird, richtig? Im Allgemeinen werden Ihre Daten als eine Art freigegebenes Dateisystem bereitgestellt. Vielleicht ist es HDFS, vielleicht ist es Amazons S3, etwas, aber es wird nicht das lokale Dateisystem sein. Denn wenn Sie diesen Code verteilen, Ihnen
dieses lokale Dateisystem nicht unbedingt zur Verfügung. zunächst sicher, dass Siezunächst sicher, dassdie Vergangenheit an Dateien an
ein verteiltes Dateisystem oder zumindest an eine Datei verwendet wird, die überall dort
zugänglich ist, wo Ihr Skript ausgeführt wird. Dann werden wir unser Scala-Projekt irgendwie in eine JAR-Datei packen. Und es gibt ein paar Möglichkeiten, dies zu tun. Moment werden wir beginnen, indem wir einfach ein JAR-Artefakt in Intelligenz hinzufügen, um unseren tatsächlichen Anwendungscode selbst in eine JAR-Datei zu exportieren. Dies hat jedoch Einschränkungen, wenn Sie Abhängigkeiten in Ihrem Skript über die Lager Spark-Bibliotheken hinaus haben, wird
das ein Problem sein, das wir darüber nachdenken müssen, wie diese Abhängigkeiten verteilt werden können. Und später werden wir darüber sprechen, SBT zu verwenden, um dies zu tun. Das haben wir tatsächlich schon die ganze Zeit gemacht. Du wusstest es einfach nicht. Und sobald wir eine JAR-Datei haben, können
wir Spark verwenden, um zu bitten, dieses Treiberskript außerhalb der IDE auszuführen. Das Format ist ziemlich einfach. Sie geben einfach Spark gestrichelt, senden, dash, dash class ein, was auch immer Ihr Klassenname ist, der Sie ausführen möchten, die Ihre Hauptfunktion hat. Wenn Sie Abhängigkeiten für andere JAR-Dateien haben, können
Sie dash verwenden, dash jar ist anzugeben, wo diese gefunden werden können. Und Sie können auch Strichdateien verwenden, um Dateien automatisch neben Ihrer Anwendung zu platzieren. Also für kleine Dateien, die kleine Lookup-Dateien oder so etwas sein könnten, können
Sie damit davonkommen, Dash-Dateien dafür zu verwenden. Und schließlich der Pfad zur JAR-Datei selbst, die den Code enthält, den Sie ausführen möchten. Also damit, lassen Sie es versuchen, wird tatsächlich unser Hallo Welt Beispiel ausführen, das weit zurück zum Anfang
des Kurses geht mit Spark dash außerhalb der Intelligenz einreichen. Also führe ich dich durch, wie man das macht. Bevor wir also versuchen können, unsere Spark-Anwendung außerhalb der Intelligenz auszuführen, benötigen wir
zunächst eine Spark-Umgebung, um sie innerhalb auszuführen. Also werden wir hier eine eigenständige Spark-Umgebung auf unserem Desktop-PC einrichten, die die gleiche Umgebung simuliert, die wir vielleicht haben, wenn wir das auf einem Server in der Cloud irgendwo laufen. Also lassen Sie uns unseren Web-Browser öffnen und gehen Sie über zu Funken dot apache.org. Und hier werden Sie die neueste Version von Apache Spark selbst herunterladen. Sie werden auch 7-Zip benötigen, wenn Sie unter Windows oder Dienstprogramm sind, das tar.gz Dateien dekomprimieren kann. Also okay, wenn Sie unter Windows sind und nicht bereits ein Dienstprogramm haben dem Sie eine Dot tar.gz Datei dekomprimieren können. Ich empfehle, 7-Zip zu installieren, um sich zuerst darum zu kümmern. Also zurück zu Apache Spark. Nun, gehen Sie zu Download Spark, und wir verwenden Spark 3 in diesem Kurs hier. Also werde ich diesen Funken wählen, der vorerst freigegeben wurde. Und wir wollen die vorgefertigte Version für Apache Hadoop 2.7 oder was auch immer es ist. Und lassen Sie uns auf Download Spark 3 wird die vorgeschlagene Spiegelseite verwenden und warten, bis das herunterkommt. Es sind nur etwa 200 Megabyte, so dass es hier nur ein paar Sekunden dauern wird. Sobald das erledigt ist, verwenden wir 7-Zip unter Windows, um es zu dekomprimieren. Oder wenn Sie auf Mac oder Linux sind, können
Sie einfach auf Ihre Befehlszeile gehen und sagen, wissen Sie, den üblichen GAN Zip und dann tar dash X,
vf, was auch immer Befehl Sie brauchen, um das zu dekomprimieren. Ich bin mir sicher, dass Sie mit T, G,
C Dateien bereits vertraut sind, wenn Sie auf Mac oder Linux sind. Alles klar, sieht so aus, als hätte ich heruntergeladen. Gehen wir also zu unserem Download-Ordner und werfen einen Blick darauf. Seit ich 7-Zip installiert
habe, kann ich einfach mit der rechten Maustaste darauf klicken und zu 7 Zip gehen und extrahieren sagen. Und ich glaube, äh, wie man es wieder macht? Ja. So, dass die G Zip-Datei in eine tar-Datei extrahiert. Diese tar-Datei und Turn müssen ebenfalls dekomprimiert werden. Und hier drin sollten wir Spark selbst haben. Ich werde für uns vorkompiliert. Es wurde mit Java erstellt, so dass es tatsächlich eine plattformunabhängige ist. So können wir damit davonkommen, dies größtenteils auf Windows zu fronten. Wie Sie sehen werden, gibt es einige Pannen. Also lassen Sie uns voran und steuern ein und kopieren Sie all das. Control C. Und ich gehe zu meinem C-Laufwerk und erstelle einen neuen Ordner namens Spark und öffne diesen und kopiere ihn und füge ihn dort eher ein. Und wenn Sie auf Mac oder Linux sind, würden Sie dies
natürlich nur mit make dir und
dem Befehl cp tun , um diese Dateien dorthin zu kopieren, wo Sie sie wollen. Stellen Sie sicher, dass Sie sich erinnern, wo Sie sie hingestellt haben. Alles klar, also haben wir 3 installiert. Das war nicht schwer, oder? Also lassen Sie uns tatsächlich eine JAR-Datei erstellen und sehen, ob wir es mit dieser neuen Version von Spark ausführen können, die wir installiert haben. Also zurück zu Intel J. Mal sehen. Was wir also tun werden, ist zu Datei gehen und Projektstruktur zu sagen. Und wir gehen zu Artefakten und klicken auf das Pluszeichen. Und wir werden Jar sagen. Und wir fangen mit einem leeren Glas an. Zuerst geben wir ihm einen Namen. Nennen wir es ausgelöst Kurs. Und wir müssen ihm sagen, was wir in dieses Glas geben wollen. Also lasst uns dieses gelöste Scala-Kursverzeichnis hier öffnen. Und Sie können sehen, dass es alle Abhängigkeiten gibt, die wir von
Spark selbst im log für J importiert haben und alles, von dem es abhängt. Aber da wir bereits eine Spark-Umgebung installiert haben, müssen
wir nicht all diese Abhängigkeiten verpacken. Wir brauchen nur den Code für unser Skript selbst. Und das wird in diesen Funken Gala-Kurs zu leben kompilieren Ausgabe. Dies wird also der kompilierte Bytecode unseres Codes sein, das eigentliche Zeug unter com dot sun dot software dot Spark. Gehen wir also voran und doppelklicken Sie darauf. Und wir haben das zu unserer JAR-Datei hinzugefügt. Lassen Sie uns auch auf Include und Projekt gebaut klicken, um sicherzustellen, dass es tatsächlich erstellt wird. Und wir werden auf OK klicken. Und wir werden erneut auf das Build-Symbol klicken, um es zu erzwingen, das zu erstellen. Okay, damit Sie auf dem Weg sehen können, wie es gebaut ist, Funken sehen, Galakurse aus Artefakten,
Spark Core, Spark Course Dot Jar. Das ist also unsere JAR-Datei, die unseren Code enthält. Lass uns danach suchen. Wenn wir gehen, um Funken Gala Kurs zu sehen. Es gibt unser OUT-Verzeichnis, Artefakte, Spark-Kurs, und es gibt Funkenpferd-Dot Jar. Also 399 Kilobyte. Das scheint etwa die richtige Größe für alle von Code kompilierten in unserem gesamten Projekt hier zu sein. Das schließt also jede Klasse ein, die wir hier haben. Also lasst uns weitermachen und schauen, ob wir es benutzen können. Nun, wie gesagt, müssen Sie sicherstellen, dass alle Dateipfade noch gültig sind. So werden Sie in Hallo Welt sehen, wir haben einen relativen Pfad hier zu Daten Schrägstrich m eins durch k Schrägstrich u Punktdaten. Damit das funktioniert, muss
ich sicherstellen, dass ich das von
der richtigen Stelle aus laufe, an der dieser Pfad zugänglich sein wird. Auch wenn dies eine echte Anwendung auf einem echten Cluster wäre, würde
ich wahrscheinlich sicherstellen, dass sich die Daten stattdessen auf einer
Art freigegebenen Dateisystem befinden. Aber um der Illustration willen, hier auf unserem Desktop
laufen, werden wir es so halten. Öffnen wir eine Eingabeaufforderung. Und wieder, auf Mac oder Linux, verwenden
Sie einfach eine Terminal-Eingabeaufforderung. Navigieren wir zu unserem Ordner „Kursmaterialien“. Also für mich, dass C Doppelpunkt Backslash Funken Scala Kurs Schrägstrich Spark Scala Kurs. Und von hier aus haben wir diesen Datenpfad relativ für uns zur Verfügung. Das ist also gut. Also lassen Sie uns jetzt tatsächlich diese Funken ask submit Befehl
aus unserer Standalone-Umgebung von Spark ausführen , die wir installiert haben. Also, wie Sie sich für mich erinnern, das war C Doppelpunkt Backslash Slash Bin Schrägstrich Spark gestrichelt, einreichen. Was als nächstes müssen wir übergeben, ist der Klassenname, den wir ausführen möchten. Und so werden wir sagen, dash class, com, Dotson Hunds-Software, dot spark dot dot hello, world. Und jetzt müssen wir ihm den Pfad zur
eigentlichen JAR-Datei geben , die wir an Spark senden möchten. Und das wird für mich C Doppelpunkt Backslash sein, Spark Scala Kurs Schrägstrich Spark Scala Kurs Schrägstrich. Es war völlig Artefakte, Spark Kurs, Spark Core Start jar. Okay, also sollte das funktionieren. Was es wieder tun wird, ist, diese JAR-Datei meines kompilierten
Codes zu nehmen und das tatsächlich mit Spark Dash submit in Spark selbst zu übergeben. Es wird nach diesem Klassennamen suchen, den ich angegeben habe, und versuchen, ihn auszuführen. Und wieder, wenn wir hier auf einem echten Cluster wären, würde
eine gezielte Schätzung alles auslösen. Es würde diesen Code über den gesamten Cluster verteilen. Starten Sie unseren Cluster Manager,
tun Sie alles, was er braucht, um das zu verteilen und stellen Sie sicher, dass er tatsächlich erfolgreich läuft. Also lassen Sie uns die Eingabetaste drücken und sehen, was passiert. Nochmals, beachten Sie, dass wir außerhalb der intelligenten vollständig hier sind
wir eine völlig andere Standalone-Spark-Umgebung verwenden. Das ist ziemlich analog zu dem, was du in der realen Welt tun würdest. Ordnung, also haben wir einige beängstigend aussehende Fehlermeldungen, aber ignorieren das vorerst. Wenn Sie hier oben schauen, haben wir unsere Ausgabe bekommen. So heißt es Hallo Welt, die Datendatei hat 100.000 Zeilen. Es hat tatsächlich funktioniert. Das ist fantastisch. Achten Sie nun nicht auf diese Fehlermeldungen. Ich weiß, das klingt wirklich handwellig, aber das ist eigentlich ein Windows-spezifischer Fehler in Scala selbst, der für immer da ist. Es gibt ein Problem mit
Dateiberechtigungen für die temporären Verzeichnisse, die Spark unter Windows verwendet. Und das ist es, worüber es sich beschwert. In der realen Welt. Niemand führt wirklich Produktions-Spark-Jobs unter Windows aus, also hat sich niemand jemals Mühe gemacht, dies zu beheben. Also werden wir es vorerst ignorieren. Wenn Sie dies unter Linux tun, werden Sie das nicht durch Vergrößern sehen, werden
Sie Spark-Jobs unter Linux in der realen Welt ausführen, aber der Prozess wird derselbe sein. Sie werden immer noch Funken-Schätzung verwenden, um es zu starten, selbst wenn Sie sich in einem riesigen Cluster befinden, der einzige Unterschied besteht darin, dass es ausgeführt wird und Sie
diese seltsamen Fehlermeldungen über Dateiberechtigungen nicht erhalten , wenn Sie fertig sind. Also dort haben Sie es tatsächlich mit Spark Dash in einer
brandchinesischen neuen Spark-Umgebung mit Spark drei einreichen , indem wir unseren kompilierten Bytecode verwenden, den wir von Intel J generiert. aber wir laufen nicht tatsächlich innerhalb von Intelligenz noch mehr. Also, wo wir tatsächlich über die Grenzen unserer IDE gegangen sind, was für reale Bereitstellungen wichtig ist.
42. [Aktivität] Packaging mit SBT: Wäre es also nicht großartig, wenn wir alles, was wir brauchen,
all unsere Abhängigkeiten und alles in eine einzelne JAR-Datei packen unddiese
einfach an den Master-Knoten unseres Clusters verteilen und loslegen könnten all unsere Abhängigkeiten und alles in eine einzelne JAR-Datei packen und . Nun, das ist es, was SBT oder das einfache Build-Tool Sie tun können. Lassen Sie uns also ausführlicher über SBT sprechen und wie wir Ihr Skript und alle seine Abhängigkeiten zusammen mit ihm verpacken können. Wenn Sie also mit Java vertraut sind, Sie vielleicht mit Maven vertraut. Man kann denken, dass SBT wie Maven für Scala ist. Und was es tut, ist, Ihren Bibliotheks-Abhängigkeitsbaum für Sie zu verwalten. Wenn Sie also ein Skript haben, das von einer Scala- oder Java-Bibliothek abhängt, einer JAR-Datei, wird
es automatisch ausgehen und herausfinden, nicht nur, wo Sie das bekommen, wie Sie es in Ihre ultimative JAR-Datei packen, die Sie kompilieren. Aber auch alle Abhängigkeiten an diesem Paket haben
zu oft Sie diese komplizierten Bäume von Abhängigkeiten und diese JAR-Dateien haben und was auch immer Paket, auf das Sie sich verlassen, hängt wiederum von anderen Paketen ab, die wiederum von anderen Paketen abhängen. So verfolgen Sie alles, was von Hand ist, dass es ziemlich schnell aus der Hand kommt, aber SBT wird diese Komplexität für Sie verwalten. automatisch heraus, welche Pakete Sie benötigen, damit alles tatsächlich ausgeführt werden kann, und sammeln Sie diese für Sie zusammen und packen Sie sie zusammen. Das ist also wirklich das, was SBT hat. Vier, macht das Leben viel einfacher, wenn Sie viele
Abhängigkeiten haben oder wenn Sie eine Bibliothek haben, die viele eigene Abhängigkeiten hat, ist
es viel einfacher, als diese Abhängigkeiten von Hand zu verfolgen. Und es ist viel einfacher, als es eine Menge von Optionen an den Befehlszeilenparameter von
Bindestrich, Strich Jars zu übergeben , wenn Sie Spark submit ausführen. Anstatt also eine Reihe
spezifischer Abhängigkeiten auf der Befehlszeile mit Spark zu übergeben , senden Sie. Wir können es alle in die JAR-Datei selbst patchen, so dass wir uns nicht wirklich erinnern
müssen , was diese sind und das tatsächlich in der Befehlszeile eingeben müssen. Um SVT zu erhalten Es ist kostenlos, es ist Open Source. Wir können es von Scala dash SBT.org bekommen, und das zeigen wir Ihnen in Kürze. Es zu benutzen ist ziemlich einfach. Sie müssen nur eine Verzeichnisstruktur einrichten, die so aussieht. Auf der obersten Ebene irgendwo haben
Sie ein Projektverzeichnis, in dem es
Sachen kompilieren wird und ein Quellverzeichnis, das, wie Sie vielleicht vermuten,
ist, wohin Ihre Quelle gehen wird. Unter Ihrer Quelle sollte es ein Hauptverzeichnis geben, und unter main sollte es ein Scallop-Verzeichnis geben. Und in diesem Scala-Verzeichnis ist, wo Sie
die eigentlichen Scala-Dateien ablegen , die Sie kompilieren möchten. Sbt passt dazu, das für Sie zu kompilieren und es
zusammen mit allen Abhängigkeiten in Ihre JAR-Datei zu packen , die Sie angeben, um es zu verwenden. Wie ich schon sagte, Sie legen einfach Ihre Quelldateien und den Quellordner ziemlich unkompliziert. Legen Sie es an die richtige Stelle. Und dann in Ihrem Projektordner, werden
wir eine kleine Assembly-Punkt-SBT-Datei erstellen , die nur eine Zeile enthält, die so aussah. Jetzt könnte sich 0.14.10 im Laufe der Zeit ändern. Das ist immer noch ziemlich aktuell. Es gibt jetzt eine 15 0 da draußen, aber es ist noch nicht weit verbreitet. Also für jetzt bleiben wir bei der Version 14 hier des SBT Assembly Plugins bleiben. Aber das ist alles, was du tun musst. Das sagt SBT nur, dass wir dieses Plug-in namens SBT Assembly verwenden werden. Und seine Aufgabe im Leben ist es, diese eigenständige JAR-Datei zu erstellen, die wir wollen. Das eigentliche Herz davon ist jedoch die SBT-Build-Datei. Und das ist ein Punkt SBT erstellen, der neben den Quell- und Projektverzeichnissen im Stamm
Ihres SBT-Verzeichnisbaums platziert werden sollte . Hier ist ein Beispiel dafür, wie man aussehen könnte. Wir geben den Namen des Vaters an, wir erstellen eine Versionsnummer, was auch immer Sie sein wollen. Die Organisation, die diesem Paket zugeordnet ist. Die Scala-Version, von der es abhängt, ist
dies wichtig, um richtig zu kommen. Denken Sie daran, dass verschiedene Versionen von Spark unterschiedliche Versionen von Scala erfordern. In diesem Beispiel geben wir eine Bibliotheksabhängigkeit von Org dot apache, Spark, spark dash core an. Okay, das sagt uns, dass dieses beliebte Filmskript, das wir in Scala haben, vom Spark Core-Paket abhängt. Von Apache Spark. Und wir spezifizieren hier speziell Version 3 mit Spark. Also, weil wir wissen, dass Funken drei erfordert Scala Version 2.12. Deshalb haben wir Scala Version 2.12.3 da oben oder was auch immer, wissen
Sie, die neueste Version könnte sein, die Sie verwenden. Jetzt ist das wichtig, um richtig zu kommen. Zum Beispiel
laden wir in der nächsten Vorlesung unsere JAR-Datei in den Amazon Elastic MapReduce Service hoch
, der ab dieser Aufnahme Spark drei noch nicht unterstützt, sie unterstützen Spark Version 2.4.5, was erfordert Scala Version 2.11. In diesem Beispiel werden wir Spark Core Version
2.4.5 anstelle von 3 und Scala Version 2.11 etwas angeben . Also musst du sicherstellen, dass die passen, sonst funktioniert es nicht richtig? Beachten Sie, dass Bibliotheksabhängigkeiten hier tatsächlich eine Sequenz sind, so dass wir mehr als eine Sache darin
haben können, wenn wir nur eine kommagetrennte Liste von Zeilen dort haben. Außerdem könnten wir SQL- oder Drittanbieter-Bibliotheken ausgelöst haben, selbst was auch immer Sie für die Ausführung Ihres Skripts benötigen, würden
Sie gerade hier aufgelistet und dann würde SBT es abrufen und
afrikanische verwenden , um Ihren Code zu stapeln und auch für Verpacken, die in Ihre endgültige JAR-Datei. Jetzt eine Sache, über die wir insbesondere hier sprechen wollen, ist die vorgesehene Klausel dort. So vorausgesetzt bedeutet, dass wir davon ausgehen können , dass dieses Paket an jedem Ort vorinstalliert wird, von wo aus wir dies ausführen. Also, weil ich dies auf einem Cluster bereitstellen werde, auf dem Spark bereits installiert ist. Es besteht keine Notwendigkeit für mich, den Funkenkern in die JAR-Datei
selbst einzubinden , da das für das System als Ganzes verfügbar sein wird, alles bereit. Indem ich angegeben sage, bedeutet das, dass ich dieses Paket benötige, um meinen Code zu kompilieren, aber ich muss es nicht in meine endgültige JAR-Datei verpacken, da es bereits vorhanden sein
wird, wo ich das ausführen werde. Wenn Sie den Smart Core tatsächlich in die JAR-Datei selbst einfügen wollten, würde
ich das bereitgestellte verlassen und das würde
alles in eine wirklich eigenständige Char-Datei bündeln . Aber da ich Spark bereits installiert habe, wo ich es ausführen werde. Das brauchen wir nicht, wir können das mit der dafür vorgesehenen Flagge auslassen. Als ein weiteres Beispiel, sagen
wir, dass ich mich auf Kafka verlassen muss. Das ist eigentlich nicht Teil von Spark. Ich könnte eine andere Zeile dort in
den Bibliotheksabhängigkeiten haben , die sagt oder Daten Apache Punkt
Spark, Funken Streaming Kafka-Version, unabhängig von der Version dieser Pakete, die Sie benötigen. Jetzt in diesem Fall würde ich nicht sagen, vorgesehen weil ich weiß, dass das nicht auf meinem System vorinstalliert ist, dann werde ich es ausführen von. Das würde also tatsächlich dieses Spark Streaming Kafka jar
in die ultimative JAR-Datei packen , die ich
bereitstellen und in meine endgültige JAR-Datei aufbauen werde . Sobald Sie also alles an Ort und Stelle haben, müssen Sie nur die SBT-Assembly aus dem Stammordner ausführen. Und es wird losgehen und seine Magie wirken. Und es wird losgehen und Ihre, Ihre Skripte kompilieren. Es wird alles zusammen patchen, nachdem alle Abhängigkeiten gesammelt wurden, die es benötigt. Und Sie werden die endgültige JAR-Datei unter den Zielen letzten
Scala Strich finden , egal welche Version von Scala Sie es gesagt haben, gegen zu bauen. Und dann haben Sie eine JAR-Datei, die Sie tun können, was Sie wollen. Und die Schönheit ist wieder, dass es völlig in sich geschlossen ist. Solange Sie diese JAR-Datei zum
Master-Knoten Ihres Clusters erhalten können, von dem aus Sie sie ausführen werden. Alles, was Sie tun müssen, ist als Summit Pfad zu dieser JAR-Datei ausgelöst zu sagen und es ist fertig. Sie müssen die Klasse nicht angeben, keine JAR-Abhängigkeiten, nichts, das ist es. Also lasst uns gehen und es ausprobieren. Okay, also lasst uns zuerst
das Skript überprüfen , das wir hier oben verpacken werden. Also, wenn wir zurück zu IntelliJ und suchen nach einem Film Ähnlichkeiten 1M Datensatz. Das ist, was wir hier oben packen und letztendlich an
Amazons Elastic MapReduce senden , um tatsächlich in einem echten Cluster zu laufen. Also lasst uns durch das gehen, was hier anders ist. Nicht viel,
aber es gibt ein paar Dinge, über die man hier reden kann. Zunächst einmal, für die Filme Punkt DAT-Datei,
beachten Sie, dass wir dies in als einen bestimmten Pfad zu Filmen dot dat übergeben. Das wird erwartet, dass wir neben unserem, wo wir Spark senden ausführen,
sein geht davon aus, dass diese Datei dort auf dem lokalen Dateisystem vorhanden ist. Nun, wie wir vorher gesprochen haben, ist
das normalerweise kein großartiger Plan. Wenn Sie ein verteiltes Dateisystem haben , von
dem Sie das bekommen können, wird das besser sein. Aber in unserem Fall, Filme dot dat ist eine ziemlich kleine Datei. So können wir das ohne jede Menge Ärger um uns herum legen. Im Allgemeinen würden Sie das jedoch auf einer Art verteilten Dateisystem
haben wollen ,
anstatt sich darauf zu verlassen, dass diese Datei überall
vorhanden ist , von wo aus Sie dieses Skript ausführen. Wir stellen jedoch sicher, dass wir die Ratings Punkt DAT-Datei auf einem viel größeren Dateisystem hier haben. Also, das wird auf Amazon sein hat drei, Das ist, was das S3 n Präfix dort bezieht. Also, ähm, also habe ich einen S3-Eimer namens Sun Dog hat Funken, der die Ratings-Punkt-DAT-Datendatei enthält. Und weil das wirklich Big Data per se sind, na ja, wirklich Wir könnten das auf einer einzigen Maschine verwalten, aber für größere Datasets wie diese, möchten
Sie das im Allgemeinen auf einer Art verteilten Dateisystem sicher haben. In diesem Fall haben wir uns die Mühe gemacht, um sicherzustellen, dass es auf Amazon S3 verfügbar ist. Und wir gehen nicht davon aus, dass das auf dem lokalen Dateisystem ist. Nun, dies ist ein etwas anderes Format als wir zuvor für die Analyten 100 K Datensätze gesehen haben. Also lasst uns auch ein bisschen darüber reden. Gehen wir zu Grouplens.org. Und wenn wir zu Datasets gehen, können
wir mehr über diesen spezifischen 1 Million Dataset erfahren oder es gibt jetzt eine 1 Milliarde Dataset zu, na ja, wenn Sie wirklich Big Data wollen, aber es gibt eine, die wir in diesem Beispiel verwenden. Wenn Sie also zu Read Me Punkttext gehen, wird Ihnen das Dateiformat detaillierter erläutert. Scrollen wir nach unten. So die Ratingdatei Beschreibung, zum Beispiel, es sagt Ihnen, dass das Format Benutzer-ID, Film-ID, Bewertung,
Zeitstempel ist , aber in diesem Fall ist es nicht tabulatorgetrennt. Es ist tatsächlich durch diese Paare von Coleman getrennt. Das ist also wichtig zu realisieren. Auch die Film-Dateiinformationen ist wichtig zu wissen ,
auch, dass durch Doppelpunkt wenig ungewöhnlich begrenzt wird. Also müssen Sie sicherstellen, dass Sie
das Format verstehen , mit dem Sie es zu tun haben, bevor Sie Ihren Code schreiben. Wenn wir zur Intelligenz zurückkehren, können
wir sehen, dass wir diesen Doppelpunkt in beiden Fällen als Trennzeichen angegeben haben. Und wir geben auch den Zeichensatz für die Filmnamen an. Das ist auch ISO 8859 dash one. Das ist also ein Unterschied, nur das Format und der Pfad, den wir für diese Datendateien für den MoveLens 1 Million Datensatz
verwenden, wir wechseln zu dem 1 Million Datensatz hier, nur um zu veranschaulichen, dass tatsächlich mit Big Data arbeitet. Dies ist also ein Median von Aufgaben, es auf einer einzigen Maschine zu tun, könnte eine Herausforderung sein. Also sind wir, wir gehen das jetzt an. Was sonst noch anders ist? Nun, nicht viel. Rest des Codes ist ziemlich gleich. Also mussten wir nur sicherstellen, dass wir unsere Daten vom richtigen Ort bekommen, dass sie im richtigen Format sind. Und abgesehen davon ist
es ziemlich der gleiche Code, den wir
im Beispiel für Film-Ähnlichkeits-Datasets früher im Kurs gesehen haben . Also lass uns das schließen, jetzt, wo wir fertig sind, darüber zu reden. Als erstes müssen wir SBT selbst herunterladen. Also, wenn Sie gehen über Scala dash SBT.org. Sie sollten irgendwo einen Download-Button sehen. Ich bin sicher, dass sich diese Website im Laufe der Zeit ändern wird, aber hoffentlich können Sie sie finden. Für Windows. Es gibt ein Windows-Installationsprogramm, also gehen wir weiter und greifen das. Wenn Sie unter Linux oder Mac OS sind, können
Sie hier ein eigenständiges Paket
entweder aus ZIP-Datei oder TGC-Format erhalten , was auch immer Sie bevorzugen. Und Sie können das einfach dekomprimieren und damit fertig sein. Dort finden Sie die ausführbare SBT-Datei. Wenn Sie auf Ubuntu sind und lieber einen Paketmanager verwenden, können
Sie die Dokumentation für ein Scala SBT aufrufen und es wird Ihnen davon erzählen. Gehen Sie einfach zu diesem Link hier und das wird Sie durch, wie Sie sicherstellen können, dass Sie
das richtige Repository an Ort und Stelle haben und wie Sie es mit app.get installieren. Aber ich bin unter Windows, also werde ich nur das Windows-Installationsprogramm ausführen und damit fertig sein. Ja, ja, ich weiß. Lauf sowieso. Dieser Spaziergang durch sie. Und das Schöne daran ist, dass sie SBT für
mich in meinen Weg bringen sollten , damit ich mir keine Gedanken darüber machen muss, wo Gott zwei installiert. In Ordnung, das ist also aus dem Weg. Als nächstes lassen Sie uns tatsächlich unsere SBT-Verzeichnisse bekommen, damit wir etwas zum Verpacken hinzufügen können. Also, wenn Sie Kopf auf über http Medien, Dotson Hunde, Bindestrich, soft.com Schrägstrich Spark, Scala Schrägstrich SPT Punkt zip. Ok. Geh weiter und hol das und dekomprimiere es. Wie auch immer Sie Dinge auf Ihrem Betriebssystem dekomprimieren. Und Sie sollten einen SBT-Ordner haben, der so aussieht. Also lasst uns das einfach irgendwo hin bewegen, wo wir es nicht verlieren werden. Ich schneide das und lass es uns einfach auf mein C-Laufwerk legen. Alles klar, jetzt haben wir einen SBT-Ordner und wenn wir in den Inhalt schauen, sehen
wir, was wir erwarten zu sehen, genau da ist das Projektverzeichnis. Und innerhalb des Projektverzeichnisses ist Assembly nicht SBT. Lassen Sie uns das untersuchen. Und es enthält die eine Zeile, über die wir früher gesprochen haben, nur die Angabe, dass wir das
SBT-Assembly-Plug-in mit dieser Version verwenden werden . Und unter dem Quellverzeichnis haben
wir ein Haupt- und ein Gelehrtenverzeichnis, das die Ähnlichkeiten des Films enthält. Ein m Datensatz Punkt Scala Datei, die wir gerade angesehen. Und schließlich im obersten Verzeichnis hier haben wir unsere magische Build Dot SBT Datei. Und wenn wir das untersuchen, können
wir sehen, dass wir einen Namen haben, der mit unserem ClassName übereinstimmt, welche Versionsnummer wir ihm geben möchten, unseren Organisationsnamen, die Scala-Version, von der wir abhängig sind, und die Versionen von Spark Core und Spark SQL, auf die wir für dieses Skript angewiesen sind. Jetzt wieder, in diesem Beispiel auf Amazon EMR sind sie derzeit auf Version 2.4.5. Also, das habe ich hier angegeben, weil ich das am Ende bereitstellen werde. Und ich weiß, dass Spark 2.4 auf Scala Version 2.11 verlässt. Das ist also die Methode für all diesen Wahnsinn. Und nochmals, beachten Sie, dass ich sage, bereitgestellt, weil ich weiß, dass
Spark Core in Spark SQL auf meinem Amazon EMR-Cluster vorinstalliert wird. Ich muss Spark nicht selbst in meine endgültige JAR-Datei bündeln. Jetzt ist das eine Art uninteressantes Beispiel , weil ich hier keine Abhängigkeiten von Drittanbietern habe. Am Ende ist
alles, was ich wirklich packen werde, die JAR-Datei für mein Skript selbst. Aber das kommt sehr nützlich, wenn Sie einen komplizierteren Abhängigkeitsbaum haben, oder? Zum Beispiel hiermachen
wir nichts Superkompliziertes,
aber so machen
wir nichts Superkompliziertes, würden Sie Ihre Abhängigkeiten verwalten, wenn Sie
ein Drittanbieter-Paket hätten , das nicht auf Ihrem System vorinstalliert war. Du wirst es davor leiten. Sie listen die hier auf. außerdem sicher, dass es durch Kommas getrennt ist und Sie würden nicht sagen, dass für jene spezifischen bereitgestellt wird, in denen Sie möchten, dass es gebündelt wird. Mal sehen, ob es funktioniert. Lassen Sie uns eine Eingabeaufforderung öffnen, und ich werde dies mit Administratorberechtigungen tun, nur um sicher zu sein. Also, wenn ich nach unten gehe und Windows, das wäre unter Windows-System-Eingabeaufforderung, ich werde mit der rechten Maustaste darauf klicken, sagen Sie mehr als Administrator ausführen. Und lassen Sie uns zu diesem SBT-Ordner navigieren. Da ist es. Jetzt können wir einfach SBT Assembly eingeben. Und los sollte es gehen. Und wir müssen tatsächlich ausgehen und
eine Scala-Umgebung und Apache Spark und alles, was es braucht, um das tatsächlich zu kompilieren. Es ist also irgendwie magisch, wie SBT
diese ganze in sich geschlossene Umgebung haben kann , die es von Grund auf neu aufbaut. Und da haben wir es. Es sieht so aus, als wäre es gelungen. Werfen wir einen Blick und sehen, was wir hier haben. Also, wenn wir gehen und hier haben wir jetzt ein Zielverzeichnis. Mal sehen, was wir da drin haben. Und es gibt ein Skelett-11-Verzeichnis und im Inneren befindet sich unsere JAR-Datei. Sehr cool. Es ist also, als ob es Film-Ähnlichkeiten funktionierte, wenn ich Dataset-Dash-Assembly bin, dash 1 Punkt-Jar, nur dort sitzen und darauf warten, dass wir es benutzen. Also in unserem nächsten Vortrag, Lasst uns es benutzen.
43. [Übung] ein Skript mit SBT und Laufen es lokal mit spark-submit: Okay, an diesem Punkt habe ich Ihnen beigebracht, wie Sie Spark
auf einer lokalen Installation von Apache Spark verwenden , um Ihre Skripte auszuführen. Und ich habe Ihnen auch gezeigt, wie Sie sbt verwenden um Ihr Skript in einer eigenständigen JAR-Datei zu bündeln. Ihre Herausforderung besteht also darin, diese beiden Dinge zusammenzufassen. Ich möchte, dass Sie sbt verwenden, um eine JAR-Datei zu bündeln und sie dann lokal mit Spark das submit auf Ihrem lokalen Desktop
auszuführen. Und die Strategie hier, wählen Sie ein beliebiges Skript, das Sie wollen. mir egal, aber ich werde das Min temperaturs-Dataset-Skript wählen. Es spielt wirklich keine Rolle, mit welcher du spielen willst. Und was Sie tun müssen, ist die Build-SBT-Datei in
Ihrem SPT-Verzeichnisbaum zu ändern und sicherzustellen, dass Sie dieselbe Version
von Spark verwenden, die Sie lokal für die Verwendung von Spark submit installiert haben. Und wir müssen auch sicherstellen, dass wir
eine kompatible Version von Scala für diese Version von Spark verwenden. Das wird also ein bisschen online recherchieren. Sie müssen herausfinden, welche Version von Spark Sie verwenden und welche Version von Scala mit dieser Version von Spark kompatibel ist. Und sobald Sie das getan haben, müssen
Sie darüber hinaus herausfinden, was die aktuelle Version von Scala für diese große Revision von Scala
ist. Also möchte ich Ihnen
hier nicht zu viel Anleitung geben , denn als Entwickler in der realen Welt geht es oft darum, diese Art von Forschung selbst durchzuführen und selbst neue Probleme herauszufinden. Sie werden nicht in der Lage sein, zu Ihrem Chef oder
Ihren Kollegen zu gehen , um das Zeug für Sie herauszufinden. Ich meine, das kannst du, aber sie werden das ziemlich
nervig finden und du wirst wahrscheinlich nicht lange halten, wenn du das die ganze Zeit machst. Also möchte ich, dass du etwas Übung machst und dieses Zeug selbst herausfinden kannst. Sobald Sie es jedoch haben, sollte es nur darum gehen,
sicherzustellen , dass Ihr Skript an der richtigen Stelle im Build-Baum für sbt ist. Und auch sicherstellen, dass Sie den richtigen Bill Dot SBT für die richtige Version von Spark und Spark Submit zusammengestellt haben. An diesem Punkt können wir einfach Spark-Assembly verwenden, um es aufzubauen und sicherzustellen, dass wir Spark submit aus dem Verzeichnis ausführen, das das Skript annimmt. Wie Sie sich erinnern, gehen die meisten unserer Skripte davon aus, dass es
ein lokales Datenverzeichnis gibt , das die Daten enthält, die wir auf dem lokalen Dateisystem wollen. Wir müssen also sicherstellen, dass dieses Skript von
der richtigen Stelle aus ausgeführt wird, an der das Daten-Unterverzeichnis existiert. Und damit, geh los und gib ihm eine Chance. Und im nächsten Video
führe ich dich durch, wie ich es gemacht habe.
44. Übung Exercise SBT und spark-submit: Lassen Sie mich Sie also durch, wie ich das Min
Temperatures Dataset-Skript mit SBT komprimiert und lokal mit Spark submit außerhalb der Intelligenz ausgeführt habe. Das erste, was Sie immer tun möchten, ist, einen Blick auf das Skript zu werfen, bevor Sie es packen und sicherstellen, dass nichts
drin ist, was Sie ändern müssen bevor Sie es in einer anderen Umgebung ausführen, richtig? Also zuerst,
beachten Sie, dass wir lokalen Stern verwenden. Wenn ich nun tatsächlich auf einem echten Cluster lief, möchte
ich das wahrscheinlich ausschalten, weil ich auf einem Cluster jeden Kern und jeden Computer in meinem Cluster verwenden möchte , nicht nur den lokalen Computer, auf dem ich das Treiberskript ausführe, aber da meine Absicht ist, dies immer noch auf
meinem lokalen PC auszuführen , der in diesem Fall unverändert bleiben kann. Achten Sie auch auf Dateipfade. Dies wird vorausgesetzt, dass wir gehen, um Daten Schrägstrich 8800 Punkt CSV für unsere Datendatei gibt. Und das bedeutet, dass ich einen Datenordner auf
meinem lokalen Dateisystem haben muss ,
der neben dem gleichen Speicherort ist , an dem ich dieses Skript von Spark submit aufrufe. Also könnte ich das in einen absoluten Pfad umwandeln, wenn ich es wollte. Ich könnte das in ein freigegebenes Dateisystem ändern, wenn ich wollte. Aber wieder, da ich gerade auf meinem lokalen Dateisystem laufe, werde
ich nur sicherstellen, dass ich daran erinnere, dies
neben dem Datenordner auszuführen , in dem ich es bereits installiert habe. Also werde ich hier nichts ändern, aber Sie wollen immer diese Art von
Problemen kennen, bevor Sie ein Skript packen , mit dem Sie lokal gespielt haben, und es für Sie an einen anderen Ort versenden, Es wäre wirklich schrecklich, wenn ich vergessen würde, die Master-Linie dort zu nehmen, richtig, und tatsächlich zu einem Cluster zu verschicken. Ich hatte diesen riesigen Cluster gehabt, und ich würde ihn in diesem Fall überhaupt nicht nutzen. Sei also immer vorsichtig mit dieser Art von Sache. Beginnen wir also mit dem einfachen Teil. Kopieren wir das Skript selbst und legen es in SBT. Lassen Sie uns das in meinem Spark Scala Kurs minimieren, lassen Sie uns diese Datei finden. Es ist unter Quelle, Haupt scala com, paar Hunde Software, ein Funken. Und was war es? Min Temperatur-Dataset, Punkte, Jakobsmuscheln, ich werde das kopieren. Und gehen Sie in mein SBT-Verzeichnis und gehen Sie in die Quell-Haupt-Scala. Und ich füge das hier ein und entferne die Film-Ähnlichkeiten 1 Million Dataset-Datei, die wir in der vorherigen Aktivität verwendet haben. Jetzt muss ich sicherstellen, dass ich dierichtige Version von Spark und die richtige Version von
Scala
verwende richtige Version von Spark und die richtige Version von , damit dies lokal in meiner lokalen Spark-Umgebung ausgeführt werden kann. Also gehen wir zurück an die Spitze von SBT hier und ich werde diese Rechnung bearbeiten nicht SBT-Datei,
verwenden Sie, was auch immer Editor Sie wollen. Für mich habe ich etwas namens Notepad Plus, Plus installiert. Irgendetwas funktioniert, oder? Jeder Texteditor wird den Job hier erledigen. Wir müssen also angeben, welche Version von Spark wir verwenden und welche Version von Scala. Und diese müssen kompatibel sein, nicht nur miteinander,
sondern auch mit dem, was Sie für Spark auf Ihrem lokalen System installiert haben. Beachten Sie, dass wir sagen, dass Spark selbst zur Verfügung gestellt wird, also wird es Spark nicht selbst in unserer resultierenden JAR-Datei verpacken. Es wird die Version von Spark verwenden, die hier auf meinem Dateisystem vorhanden ist. Also muss ich sicherstellen, dass dies gegen
die richtige Version von Spark aufbaut . Fangen wir damit an. Also gehen wir zurück zu meiner Funkeninstallation und überprüfen Sie einfach. Also habe ich Spark installiert, um Spark zu sehen. Und wenn ich mir das Release TextFile dort ansehe, sagt
es mir, dass ich Spark 3 verwende. Okay, das ist also ein Teil des Puzzles. Gehen wir zurück zu meiner Rechnung Punkt SBT Datei unter SBT. Und wir werden Spark Core auf 3 ändern. Und wenn ich Datasets verwende, benötige
ich auch das Spark SQL-Paket. Also lassen wir das auch da drin. Und Sie möchten auch darüber nachdenken, welche anderen Abhängigkeiten Sie in Spark selbst an dieser Stelle oder außerhalb eines Funkens
haben. Und in diesem Fall gibt es nicht mehr. Aber wenn ich zum Beispiel ein maschinelles Lernskript verpacke, möchte
ich vielleicht Spark ML, Spark-Streaming-Dateien einbinden, die ein Bildschirmstreaming-Skript ausführen. Stellen Sie also sicher, dass Sie irgendwelche Abhängigkeiten haben, die Sie dort benötigen. Alles klar, jetzt müssen wir herausfinden, welche Version von Scala mit dieser Version von Spark kompatibel
ist. Um das zu tun, erfordert ein wenig Forschung. Lassen Sie uns einen Web-Browser starten. Und ich bringe hier ein Nukleon-Fenster mit. Also lasst uns gehen, um Punkt apache.org zu funken. Und wenn wir uns Spark Drei-Punkt ansehen, Oh, gehen Sie zum Download Spark Bereich hier, und wir können sehen, dass es uns hier sagt, welche Version von Scala kompatibel ist, welche Version von Spark. Also sagt es nein, dass spark to point x mit 2.11 vorgebaut ist, außer für Version 2.4.2, die mit Skelett 12 gebaut ist. Aber Spark Drei-Punkt-Oh, das ist uns vorgebaut mit Scala auf 0,12. Okay, also weiß ich, dass ich Spark Version 2.12 brauche. Ist das spezifisch genug? Nun, schauen wir mal. Ich möchte auch eine Nebenversion. Ok. Nun, wir werden die 11 zu 12 ändern, aber was kommt nach der 12? Ich weiß es nicht. Lasst uns noch mehr recherchieren. Also wieder, man muss irgendwie einfallsreich sein manchmal. Also lassen Sie uns einfach nach
Scala zu 0.12 suchen und sehen, ob wir herausfinden können, was die aktuelle Version davon ist. Sieht so aus, dass ich eine gestrichelte line.org skaliere, die die offizielle Heimat von Scala ist. Und obwohl ich nicht will, sieht
es so aus, als wäre 2.13 tatsächlich raus, aber wieder muss
ich 2.12 für diese Version von Spark verwenden. Mal sehen, ob mir die Versionshinweise etwas sagen. Ok. Die neueste Version von 2.12 ist also offenbar 2.12.12. In Ordnung, lassen Sie uns damit gehen. Also zurück zu meiner Build-Out-SBT-Datei, werden
wir 2.12.12 angeben und ich werde dies speichern. An dieser Stelle sollten wir bereit sein, das zu verpacken. Gehen wir voran und öffnen Sie eine Eingabeaufforderung. Reinigen Sie die Dinge hier ein bisschen. Also lass uns mal sehen. Ich gehe zum Startmenü. Natürlich würden
Sie auf einem Mac oder einem Linux einfach ein Terminal öffnen. Keine große Sache. Dies wird unter Windows-System-Eingabeaufforderung sein und wir möchten das als Administrator ausführen, nur um sicher zu sein. In Ordnung, also lassen Sie uns zu diesem SBT-Ordner navigieren. Und wir werden nur SBT Assembly eingeben. Und hoffentlich wird es das Richtige tun. Okay, tat etwas sieht aus wie ein gebaut gegen Skelett 0,12. Das hört sich also richtig an. Lassen Sie uns voran gehen und sehen, ob wir diese resultierende JAR-Datei haben. Lasst uns ins Ziel Skelett 12 gehen. Oh, ich habe vergessen, den Namen zu ändern. In Ordnung, gut. Nun, gehen wir zurück zu sbt und bearbeiten die Bill Dot SBT Datei wieder. Sehen Sie, ich habe vergessen, den Namen zu ändern. Also sollte das wirklich sein, was dieses Ding wieder war, Min Temperatur-Dataset. Alles klar, machen wir es noch mal. Sollte jetzt schneller sein, da es all diese Abhängigkeiten heruntergeladen hat. Okay, mal sehen, was wir jetzt haben. Wähle eine Scala auf 12. Da ist es, min temperature dataset assembly dash 1 O. Also lassen Sie uns das kopieren und neben dem Datenverzeichnis, von dem ich es ausführen möchte. Also Control C, offensichtlich könnten Sie
den Befehl cp von einer Eingabeaufforderung aus verwenden , wenn Sie es auch wollten. Und wir werden in sehen Funken-Gala-Kurs gehen. Und dort befindet sich das Datenverzeichnis, angenommen wird
, dass es lokal relativ zum Skript ist. Gehen wir weiter und fügen Sie das hier ein. Und jetzt sollte in der Lage sein, dorthin zu navigieren und Sie es mit Spark senden ausführen. Also lassen Sie uns unser Verzeichnis ändern, um Funken Gala Kurs Slash Slash Spark Scala Kurs zu sehen. Und lassen Sie uns mit Spark einreichen und sehen, was passiert. So übermittelt Funken Pfad war unter C Spark Bin, Spark Desk senden. Stellen Sie sicher, dass es da ist, okay. Und wir sollten in der Lage sein, in Min Temperatur-Dataset dash Assembly dash 1 Punkt char zu übergeben. Ich benutze nur die Tabulator-Taste, um das automatisch zu vervollständigen. Und es sollte funktionieren. Und wir haben eine Reihe von Fehlern beim Herunterfahren bekommen. Aber wieder, das ist normal. Das ist eine Windows-Sache. Wir haben aber tatsächlich unsere Ausgabe bekommen. Also sieh mal, es hat cool geklappt. Wir haben unsere Mindesttemperatur für diese beiden Wetterstationen. Und wir haben eine erfolgreiche Verpackung von das ist gut mit SBT und wir laufen es lokal mit Spark Desk einreichen kümmert sich mit der Version von Spark, die wir installiert hatten und die Version von Scala,
dass, diese Version von Spark hängt davon ab. Also hoffentlich hatten Sie auch etwas Erfolg damit. Wenn nicht, denke ich, dass dir dieses Video wahrscheinlich gezeigt hat, wo die Dinge schief gelaufen sind. Also gehen Sie zurück und versuchen Sie es erneut, wenn Sie müssen. Und damit machen wir weiter.
45. Einführung von Amazon Elastic MapReduce: In dem Moment, auf den wir gewartet haben, werden
wir tatsächlich unser 1 Million Filmbewertungsskript auf
einem echten Cluster mit Amazon Elastic MapReduce Oberfläche und Hadoop ausführen . gibt viele Summen Wörter. Lassen Sie uns über ein bisschen mehr reden, bevor wir es tatsächlich tun. Lassen Sie uns darüber sprechen, wie verteilter Spark tatsächlich funktioniert. So können die gleichen Skripte, die Sie verwendet haben, um diese Spark-Aufträge
lokal auf Ihrem eigenen PC auszuführen , ohne große Änderungen auf einem Cluster verwendet werden. Es liegt also an Spark senden und Spark selbst, um herauszufinden, welchen Cluster-Manager Sie oben ausführen. Und das könnte Funken eingebauten Cluster-Manager sein. Es könnte Hadoops Garn sein, es könnte Mesos sein. Und integrieren Sie diese, um die Arbeit aller Ihrer Mapper
und Reducer sowie eines CAN über den Cluster zu verteilen , den Sie zur Verfügung haben. Also im Grunde läuft das Spark-Treiberskript auf Ihrem Master-Knoten, Ihrem Treiber, okay? Und das kommuniziert mit Ihrem Cluster-Manager, um
die Arbeit, die in diesem Treiberskript ist, tatsächlich an verschiedene Executor Nodes Worker zu verteilen , okay? Und der Cluster-Manager ist verantwortlich für den Umgang mit Fehlern einzelner Knoten und klicken Sie auf die Ergebnisse wieder zusammen, um wieder zu Ihrem Treiberskript zu gelangen, wenn es fertig ist. Jetzt noch ein paar andere Spark Summit Parameter, über die wir sprechen sollten. Und zuerst sollte ich beachten,
dass auf vielen Clustern viele dieser Einstellungen automatisch für Sie vorkonfiguriert werden. Wenn Sie also nichts in Ihrem Skript explizit für das angeben ,
was der Master sein wird oder wenn es nicht in der Befehlszeile angegeben wird. Es gibt auch eine Konfigurationsdatei innerhalb von spark, die so eingerichtet werden
kann, dass alle diese Dinge automatisch für Sie eingestellt werden. Wenn Sie beispielsweise einen Cluster auf Amazon, Elastic MapReduce, einrichten, werden viele dieser Dinge für Sie eingerichtet und nicht bereits optimal. Aber manchmal stößt man auf Probleme, bei denen die Dinge nicht abgeschlossen sind. Sie laufen keine Ressourcen, Dinge beginnen Timeout und Sie müssen diese Dinge ein wenig optimieren,
um die Dinge zuverlässiger laufen zu lassen, damit Sie wissen müssen, dass sie existieren. Die erste Option, über die wir nicht reden wollen, ist Dash, Dash Master. Und das ist nicht etwas, was man zwicken kann. Es ist nur Test, um auf das Richtige für welche Art von Cluster Sie haben eingestellt zu werden. Also, wenn Sie auf einem Hadoop-Cluster laufen und Sie die
Vorteile von Hadoops Garn Cluster Manager nutzen möchten , der auf Garn festgelegt wird. Wenn Sie den eigenständigen Cluster von Spark verwenden möchten, legen
Sie diesen auf den Hostnamen und den Port Ihres Master-Knotens auf Ihrem Spark-Cluster fest. Mesos funktioniert ähnlich. Und wieder, wenn Sie
eine Funkenconf oder irgendetwas in Ihrem Skript selbst haben , das das überschreibt. Es wird ignorieren, was sich auf der Befehlszeile befindet. Also ist die Hierarchie, was in Ihrem Skript ist, Gewässer auf der Befehlszeile und Gewinner in den Konfigurationsdateien für Funken. Vergessen Sie also nie,
Ihre Skripte zu überprüfen , um sicherzustellen, dass Sie nicht schwer sind, einen bestimmten Master zu codieren. Wenn Sie beispielsweise diesen lokalen eckigen Stern haben, wird
die Master-Option hier außer Kraft gesetzt. Und wenn Sie dieses Skript auf einem Cluster ausführen würden, würden
sie den vollen Cluster nicht nutzen. Für die Verwaltung der Ressourcennutzung in Ihrem Cluster gibt es auch Optionen dafür. Num-Executoren geben an, wie viele Executor-Knoten Sie verwenden möchten. Standardmäßig sind das nur zwei. Wenn Sie also auf einem größeren Cluster mit mehr als zwei Knoten arbeiten, sollten
Sie diese Einstellung erhöhen. Wieder, in der Regel wird das für Sie von jemand anderem, von der Verwaltung, aber etwas zu beachten, und stellen Sie sicher, dass das in der Tat irgendwo gesetzt ist. Der Executor Speicher verwaltet, wie viel Speicher für jeden Executor zur Verfügung steht. Und natürlich möchten Sie sicherstellen, dass dies
den physischen Speicher nicht überschreitet , der jedem einzelnen Executor Knoten zur Verfügung steht. Wenn Sie auf einem Cluster in der Cloud ausgeführt werden, handelt es
sich häufig um virtuelle Maschinen, die weniger Arbeitsspeicher haben, als Sie vielleicht denken. also sicher, dass Sie sich des Speichers bewusst sind, der Ihrem Skript auf jedem Executor zur Verfügung steht. Und Sie können sich auch die gesamten Executor Kerne ansehen. Wenn Sie Multicores auf Ihren virtuellen Knoten haben, sollten Sie dies möglicherweise optimieren, um tatsächlich eine Obergrenze zu setzen, wie viele Kerne Ihr Skript verbrauchen kann. Okay, Amazon Elastic MapReduce, das ist, was wir in diesem Kurs verwenden werden. Es ist eine schnelle und einfache Möglichkeit, einen Hadoop-Cluster zu drehen und Sie können tatsächlich sagen, dass Spark auf ihm wie für Sie als auch vorinstalliert ist, mit allem automatisch konfiguriert. So sehr einfache Möglichkeit, um loszulegen und Ihr Skript
auf einem echten Cluster auszuführen , wo Sie nur Zeit mieten und bezahlen für das, was Sie brauchen. Und das ist irgendwie die ganze Prämisse von Amazon Web Services. Sie schreiben nur Zeit und zahlen für die Rechenressourcen, die Sie tatsächlich für alles, was Sie tun, benötigen. Sie werden also grundsätzlich von der Stundeninstanz berechnet, wie viel Zeit Sie für wie viele Computer eines bestimmten Typs aufwenden. Und Sie werden auch für jede Netzwerk-E/O und
jeden Speicherplatz und jede Speicher-E/A berechnet . Also zahlen Sie für das, was Sie verwenden. Und normalerweise ist es nicht eine ganze Menge. Ich denke, ich habe ungefähr 30 Dollar ausgegeben und diesen Kurs in Bezug auf AWS-Gebühren
zusammengesetzt . Aber seien Sie vorsichtig. Ich empfehle, mir das vorerst zu beobachten, es sei denn, Sie haben ein Firmenkonto oder etwas, wo es nicht Ihr Geld auf der Leitung ist. Denn wenn Sie sich vermasseln, ist es sehr leicht zu vergessen, Ihren Cluster zu beenden, wenn Sie fertig sind. Und wenn Sie das tun, wird Ihr Cluster nur für immer weiterlaufen, obwohl Sie es nicht verwenden. Und Sie werden für die ganze Zeit gebaut werden, wenn Sie
es vielleicht nicht einmal erkennen , bis Sie eine Kreditkartengebühr für $1000 sehen. Ich will nicht, dass dir das passiert. Dafür will ich nicht verantwortlich sein. Also, ähm, wissen Sie, wenn Sie mit dem MR herumspielen wollen,
denken Sie daran, Ihre Cluster zu beenden, wenn Sie fertig sind. Wenn du es nicht tust, werden deine Bankkonten dich nicht mögen und du wirst mich nicht mögen, also geh einfach nicht dorthin. Ok. Lassen Sie uns also darüber sprechen, tatsächlich auf einem Cluster zu laufen und bereits über einige dieser Punkte zu
sprechen. Aber wieder, was EMR für Sie eingerichtet, ist ein Hadoop-Cluster und Sie können Spark auf der Garnkomponente von Hadoop ausführen. So vermischen die Leute irgendwie Hadoop und Hadoop-Garn. Manchmal höre ich viele Leute darüber reden, wie Spark schneller ist als Hadoop, aber es ist nicht wirklich das eine oder andere. Ok? Was sie wirklich bedeuten, ist Spark ist schneller als MapReduce, was eine Möglichkeit ist, verteilte Jobs auf Hadoop auszuführen. Aber Hadoop selbst ist nur eine Technologie für die Verwaltung eines Clusters. Und eine Komponente von Hadoop ist Garn, der Cluster Manager, der Funke kann auf gut laufen. Okay, also erinnere dich an die verschiedenen Teile, da ein Spark-Treiber
ein Cluster-Manager ist und dann gibt es die eigentliche Hardware selbst. Hadoop füllt nur dieses kleine Mittelstück für dich aus. Hadoop und Spark schließen sich also nicht gegenseitig aus, was ein häufiges Missverständnis ist. Ok? Eine andere Sache, auf die ich in Bezug auf Best Practices hinweisen möchte, weil das Ausführen auf einem echten Cluster teuer ist. Dies sind teure Ressourcen, mit denen Sie hier potenziell zu tun haben.
Sie möchten immer sicherstellen, dass Sie Ihre Entwicklung und Tests lokal auf Ihrem eigenen PC durchführen, okay. Oder ein Desktop-Computer oder ein einzelner Computer, auf den Sie Zugriff haben, der nicht viel Geld kostet. Und eine Möglichkeit, dies oft zu tun, besteht darin, eine Teilmenge Ihrer Daten zu verwenden, um sich mit zu entwickeln. Wenn Sie also mit einem großen Datensatz zu tun haben, den Sie nur in einem Cluster verwalten können, sollten Sie nur ein Stück dieses Datasets verwenden, um die Breite zu entwickeln und zu testen. Und so ist es wahrscheinlicher, dass Sie
eine erfolgreiche Ausführung haben , wenn Sie tatsächlich Zeit auf dem Cluster selbst mieten, möchten
Sie wirklich die Zeit minimieren, die Sie am Cluster arbeiten, wenn möglich. Okay, in Bezug auf die Einrichtung, müssen
Sie beginnen, indem Sie ein Amazon Web Services-Konto erstellen. Und ich nehme an, du kannst herausfinden, wie das geht. Seitdem will ich nur, dass du mir zusiehst, wie ich das jetzt mache. Der nächste Schritt besteht darin, ein EC2-Schlüsselpaar zu erstellen, so dass
Sie sich tatsächlich bei Ihrem Cluster anmelden können, sobald Sie es auf sichere Weise gesponnen haben. Und Sie benötigen eine Möglichkeit, sich irgendwann bei
dieser tatsächlichen virtuellen Maschine anzumelden , indem Sie etwas wie Putty unter Windows Sie benötigen eine Art Terminal, um sich mit diesen Maschinen zu verbinden und Ihr Skript auszuführen und die Dinge, die Sie für sie brauchen. Also lasst uns anfangen und sehen, wie es funktioniert.
46. So erstellst du ähnliche Filme aus einer Million Bewertungen auf EMR: Also lasst uns das machen. Lassen Sie uns tatsächlich Film-Ähnlichkeiten basierend auf 1 Million Benutzerfilm-Bewertungen generieren und tun es für echte. Folgen Sie einfach hier und ich zeige Ihnen, wie es
mit dem Elastic MapReduce Service von Amazon funktioniert . Jetzt, um die Dinge einzurichten, habe
ich bereits einige Sachen in den S3-Dienst von Amazon geladen, im Grunde ein verteilter Dateispeicher ist, auf dem Sie Speicherplatz mieten. Alles klar, so wie HDFS, aber es ist die Amazon-Version davon. Eine Möglichkeit, darüber nachzudenken. Also habe ich bereits einen Bucket in S3 namens Sunday August Spark erstellt. Und ich habe ein paar Dinge hochgeladen, die ich brauchen werde. Einer ist die Film-Ähnlichkeiten, eine M Jar, Jar Datei. Und das ist dasselbe, was ich früher im Kurs mit SBT generiert habe. Ich habe ihm gerade einen etwas anderen Dateinamen gegeben. Also hat es mein eigenständiges Spark-Treiberskript in eine JAR-Datei gebündelt. Okay, das wird also auf S3 sein. So kann ich es schnell auf meinen Cluster kopieren, sobald ich meinen Cluster aufgeteilt habe, um ihn auszuführen. Die andere Sache, die ich getan habe, ist, dass ich
den MoveLens 1 Million Bewertungsdatensatz hier ebenfalls verschoben habe . Also habe ich einen MNL Dash 1M Ordner hier auf meinem Sohn starb Smart S3 Bucket erstellt. Und das wird sicherstellen, dass dieses verteilte Dateisystem von S3 , das meine 1 Million Filmbewertungen enthält, auch für meinen gesamten Cluster zugänglich ist. Und darin haben wir die verschiedenen Dateien, aus denen die Datensatzbewertungen bestehen. Dot dat ist die tatsächlichen Filmbewertungen selbst und Filme dot dat ist alle Metadaten, die mit den tatsächlichen Filmen verbunden sind. Unsere Strategie, wenn Sie sich erinnern, wird es sein, diese JAR-Datei vom Master-Knoten unseres Clusters auszuführen. Und es wird Filme dot dat neben ihm befinden. Es kann also tatsächlich diese Nachschlagetabelle von
Film-IDs zu Filmnamen aufbauen , wenn es die Ergebnisse ausgibt. Aber alles, was Cluster benötigt, sind die Verschneidungsdaten. Also lasst uns gehen und Dinge aufstellen und einen Cluster bilden. So haben wir unsere schöne glänzende Movielens 1 Million JAR-Datei bereit für die Bereitstellung in unserem Cluster. Aber zuerst brauchen wir einen Cluster, um eine Zwei bereitzustellen und einen zu erstellen. Ich werde dazu den AWS Elastic MapReduce-Dienst verwenden. Jetzt kostet das Geld. Wenn Sie also kein Geld ausgeben möchten oder kein AWS-Konto haben, möchten
Sie wahrscheinlich nur hier zusehen und sich nicht selbst mitverfolgen. Ok? Aber ich habe bereits ein AWS-Konto und ein bisschen Budget, mit dem ich spielen kann. Also werde ich voran gehen und hier auf EMR klicken oder einfach Elastic MapReduce eingeben und Dienste finden. Und machen Sie einen neuen Cluster hier. Also lassen Sie uns einen neuen Cluster erstellen und nennen es Funken Scala Spaß. Ich weiß nicht, ruf an, was du willst. Und wir werden hier sagen, dass wir die neueste Version von EMR verwenden. Das ist wenigstens keine Beta. Und das wird Spark benutzen. Wir möchten hier die Spark-Anwendung auswählen. Und Sie können sehen, dass sie jetzt Spark 2.4.4 anbieten. Sie hatten noch nicht den Mut, einen Funken drei zu schaffen. Aber wenn du dieses Video ansiehst, wird das
vielleicht auch eine Option sein. Aber deshalb packen wir unsere JAR-Dateien speziell für Spark 2.4.4 und Scala auf 0.11. Weil wir wussten, dass dieser Cluster darauf installiert haben wird. Für die Hardwarekonfiguration können wir hier bei den Standardwerten bleiben. Dies wird tatsächlich einen Spark-Cluster von drei Knoten hochlaufen. Typischerweise läuft es Spark auf Hadoop, und das wird alle m5 nächsten Large Instances sein. Die Dinge sind nicht billig, sie sind nicht Frigyes. Also, selbst wenn Sie wie ein brandneues Konto sind, wo Sie über das kostenlose Kontingent sprechen. Hierbei handelt es sich nicht um kostenlose Hardware. Also nochmal, das kostete echtes Geld, um hochzudrehen, kostete mich etwa 30 Mäuse, um dies zu tun, als ich all diese Übungen zusammenstellte. Also nochmal, wenn Sie das quietschend machen, tun Sie das
nicht, schauen Sie einfach zu. Sie müssen auch ein EC2-Schlüsselpaar angeben. Ich habe bereits einen erstellt, der Sun dog EC2 heißt. Und wenn Sie ein neues erstellen müssen, können
Sie einfach diesem Link folgen, um zu erfahren, wie Sie Ihr eigenes brandneues EC2-Schlüsselpaar erstellen. Sie erhalten also einen öffentlichen und einen privaten Schlüssel, den Sie später verwenden können , um eine Verbindung zu diesem Cluster herzustellen.
Sie benötigen diesen, um sich tatsächlich beim Master-Knoten anzumelden und das Skript tatsächlich zu starten. Standardberechtigungen sind in Ordnung. Gehen wir weiter und drücken Sie Cluster erstellen. Und los geht es. Das wird also losgehen und die Hardware bereitstellen, die wir brauchen. Wir brauchen ein paar Minuten, um
die Hardware tatsächlich zu bekommen und alles darauf einzurichten und zu booten. Also kommen wir zurück, wenn das Setup fertig ist. Okay, nach etwa fünf oder zehn Minuten sehen
wir, dass wir jetzt unsere Master- und Core-Maschinen im laufenden Zustand haben. Und mein Cluster wartet nur darauf, dass ich etwas tue. So cool, mein Cluster ist fertig. Also lasst uns etwas damit machen. Um das zuerst zu tun, muss ich mich irgendwie damit verbinden. So können Sie hier unter dem Master Public DNS SEC gibt mir die extern verfügbare Adresse des Master-Knotens. Dann werde ich mein Skript von ausführen. Und wenn ich auf diesen SSH-Link klicke, wird
es Ihnen genau sagen, wie Sie sich damit verbinden. Für Windows können Sie also etwas namens
Kitt für ein Terminalprogramm verwenden . Das benutze ich. Und wenn Sie es installieren müssen, Es gibt eine praktische Dandy Download der Link dort für Sie. Und es sagt Ihnen genau, wie Sie eine Verbindung herstellen. Ich benutze das. Wenn Sie auf Mac oder Linux sind, haben
sie auch Anweisungen für Sie. Aber ich bin auf Windows. Also, was wir tun werden, ist, diese Adresse zu kopieren, damit ich sie schnell reinkriege und Kitt öffnen kann. Geben Sie das in für den Hostnamen ein. Und dann muss ich meine APK-Datei,
meinen privaten Schlüssel angeben, um sich tatsächlich darin anzumelden. Also denken Sie daran, ich gebe bei der Einrichtung eines Clusters an, dass
ich den Sun Dog EC2-Schlüssel verwenden würde. Und da speichere ich die Akte dort. Also, jetzt sollte ich in der Lage sein, einfach Open zu drücken. Und dort sind wir in unserem Master-Knoten eingeloggt. Abhängig von Ihren Sicherheitseinstellungen erhalten
Sie jetzt möglicherweise ein Timeout. Wenn Sie also herausfinden möchten, warum Sie keine Verbindung herstellen können, egal was Sie mit Ihren Firewall-Einstellungen versuchen oder wann immer Sie immer noch nicht durchkommen können. Azar ist auf der Serverseite blockiert. Wenn Sie also auf diesen Quick-Tipp stoßen, können
Sie hier auf die Sicherheitsgruppe für den Master-Knoten klicken. Und sobald Sie dort sind, können
Sie hier auf die eingehenden Regeln klicken und sicherstellen, dass Sie einen SSH-Port geöffnet haben. In diesem Fall musste ich tatsächlich manuell
einen SSH-TCP-Port zu Port 22 zu der IP-Adresse hinzufügen , von der ich mich verbinde. Also, wenn Sie Probleme mit der Verbindung haben, ist
das wahrscheinlich, was Sie tun müssen. Aber gehen wir zurück dorthin, wo wir waren, zurück zur EMR-Konsole. Und jedenfalls sind wir jetzt eingeloggt. Also, jetzt können wir anfangen, ein paar lustige Sachen zu machen. Also zuerst mal sehen, wo wir sind. Wir sollten ein kleines Home-Verzeichnis hier unter dem Hadoop-Benutzer haben. Zuerst werde ich
unser aktuelles Treiberskript in die JAR-Datei kopieren , die wir früher mit SBT erstellt haben. Also lassen Sie uns voran und kopieren, dass über S3, EMR und AWS EC2 Knoten verfügt über eine Reihe von integrierten
Dienstprogrammen namens AWS, die Sie verwenden können, um tatsächlich Dinge aus S3 zu kopieren. Und so was. So kann ich in AWS, S3, CP, Mal sehen, s3 Doppelpunkt Schrägstrich, Sun Dog eingeben. Ich kann es keinem Hundepark sagen. Und wie habe ich die Akte nochmal genannt? Filme Ähnlichkeit ist ein m Dot jar. Die Ähnlichkeiten ein m dot char hier. Okay, und du kannst sehen, dass das funktioniert hat. Die andere Sache, die ich brauche, ist die Film-Punkt-DAT-Datei. Also kann ich tatsächlich das Konstrukt der Nachschlagetabelle machen, die Film-IDs zu Filmnamen macht. Und wieder, ich lege das in den ML Strich ein m Unterordner. Also lassen Sie uns das auch überschreiben. AWS S3 Kopie s3 Doppelpunkt Schrägstrich,
Spark Schrägstrich ML Strich 1M Schrägstrich Filme bekam Anpassung an das lokale Verzeichnis. Also da haben wir es. Okay, ich habe das Fenster hier etwas
erweitert, damit wir unsere Ergebnisse besser sehen können. Und alles, was ich jetzt tun muss, ist Spark Strich
einzugeben, den Namen der JAR-Datei einzureichen, Film-Ähnlichkeiten, ein m dot-jar. Und wenn Sie sich richtig erinnern, benötigt
diese Schrift einen Befehlszeilenparameter
der Film-ID, für die wir Ähnlichkeiten finden möchten. Also weiß ich zufällig, dass Star Wars 260 in dem 1 Million Datensatz ist. Lass es uns loslegen. In Ordnung, also sehen wir hier ein paar einleitende Info-Nachrichten. Und eines der ersten Dinge, die das Skript tut, ist alles außer Fehlermeldungen zu deaktivieren. Wir sollten also nichts anderes als
Fortschrittsnachrichten sehen , da es dies tatsächlich aufbricht und auf den Cluster verteilt. Also warten wir im Grunde darauf, dass es den ersten Aktionsbefehl erhält und die DAG erstellt. Ich habe gerade die Filmnamen geladen und es verbreitet es jetzt aus. So gerade jetzt, wie wir sprechen, berechnen
wir tatsächlich ähnliche Filme für Star Wars mit Million Bewertungen auf einem kleinen Cluster von drei Maschinen. Ziemlich cooles Zeug. Wir sind bereits in Phase 2 und ich erinnere mich, dass die Phasen nach Bereichen der DAG aufgeteilt sind, die nach Daten-Shuffle-Operationen aufgeteilt sind. Und diese Phasen sind wiederum in Aufgaben zerlegt. So können Sie jetzt hier in Stufe zwei sehen, wo chugging durch 32 Aufgaben, es wird eine weitere Stufe nach diesem mit einem 100 für die, ein 100 Partitionen, die wir einrichten. Und in etwa fünf Minuten oder so wird das geschehen. Es dauert nicht so lange, Art von der Macht eines Clusters, der durch eine Million Bewertungen und jede mögliche Permutation von jedem möglichen Paar von Filmen und dann filtert die Ergebnisse, die wir wollen Schüler ein viel Arbeit, aber es wird es ziemlich schnell tun. Kommen wir in fünf Minuten zurück und ich zeige Ihnen die Ergebnisse. Alles klar, wir sind hier fast fertig. Da ist es. Ehrfürchtig. Also haben wir die besten ähnlichen Filme für Star Wars Episode 4 und neue Hoffnung basierend auf einer Million echten Filmbewertungen. Und heute ist das etwas neuer aus dem Jahr 2003. Also wieder, wir werden keine aktuellen Filme sehen, aber die Ergebnisse sehen ziemlich verdammt vernünftig aus. Wir haben eine Star Wars Episode 5 und Power Streiks Unterstützer der verlorenen Arche. Rückkehr der Jedi-Jedi, irgendwie aus diesem Grund wurde
die verlorene Arche höher Rendite der Jedi bewertet. Aber um ehrlich zu sein, glaube
ich, dass ich Raiders der verlorenen Arche mehr genossen hätte als die Rückkehr der Jedi. Das ist vielleicht nicht so verrückt, wie es sich anhört. Und der ursprüngliche Indiana Jones Film, sehr gute Empfehlungen für jemanden, der Star Wars genießt. Und dann fangen wir an, in andere große Filme zu kommen, die gut waren. Die Terminator-Matrix, da sind einige ziemlich gute hier drin, zurück zur zukünftigen Prinzessin Braut, alle appelliert an diese geeky Demographie. Sehr cool. Hey Honig Python und der Heilige Gral, auch das sind eigentlich ziemlich verdammt vernünftige Empfehlungen. Cool, und da hast du es. Also, das sind Filmempfehlungen, ähnliche Filme und Star Wars mit 1 Million Filmbewertungen laufen auf einem tatsächlichen Cluster mit Hadoop Garn und ApachesPark. Es ist, worum es geht. Nun, letzten Schritt, vergessen Sie nicht, den Cluster zu beenden, wenn Sie fertig sind. Also werde ich davon ausgehen, aber das reicht nicht. Und ich muss zurück zum EMR-Armaturenbrett. Und in meinem Cluster Hit beenden. Ja, ich bin sicher, ich bin damit fertig. Wenn du das nicht tust, läuft die Rechnung weiter für dich. Dieser Cluster wird immer noch ausgeführt, und obwohl Sie nichts damit tun, werden
Sie immer noch für die Zeit auf diesem Cluster gebaut werden, dafür alle drei dieser Computer oder sogar mehr, wenn Sie mehr einrichten. Also nochmal, wenn Sie dies auf Ihrem eigenen Cent tun und tatsächlich folgen, denken
Sie bitte daran, Ihren Cluster zu bestimmen, wenn Sie fertig sind. Ich will wirklich nichts davon hören. Wenn Sie eine Rechnung für $1000am Ende des Monats von Amazon erhalten, soll 10, was über das, was diese Kosten ist. In Ordnung. Stellen Sie sicher, dass das erfolgreich beendet wird und es dann sicher ist, es zu schließen. Aber damit, woo hoo, herzlichen Glückwunsch, das ist irgendwie der Höhepunkt dessen, was wir hier gemacht haben. Wir haben tatsächlich einen echten Big Funke, Big Data-Job auf einem echten Cluster erfolgreich ausgeführt und haben einige wirklich nützliche Ergebnisse daraus bekommen. So cooles Zeug. Lassen Sie uns in ein wenig mehr Tiefe über Fehlerbehebung von Spark-Jobs und einige der feineren Punkte des Laufens in Tuning Dinge sprechen.
47. Partitionierung: Also eine Sache, die ich wirklich überholte war diese Zeile hier in diesen Filmen Ähnlichkeit ist eine m Datensatz Punkt Scala Datei hier, über die wir nicht gesprochen haben. Dies unterscheidet sich von unserem ursprünglichen Film-Ähnlichkeits-Dataset-Skript. Diese Zeile hier, repartition num Partitionen gleich 100. Also haben wir das auf unseren selbst verbundenen DataFrame angewendet, bevor wir diesen in ein Dataset konvertieren. Also, worum geht es denn? Worum geht es bei der Neupartitionierung? Warum muss ich das tun? Nun, das ist eine wirklich, wirklich schwere Operation hier, die ich mache, dass Self-Join über eine Million Bewertungen wird wirklich
schnell explodieren und das ist mehr, als Sie wirklich auf einer einzigen Maschine tun können. Also in diesem Fall müssen wir Spark sagen, hey, du willst diese Operation wirklich aufteilen. Und dieser Repartitionsparameter gibt an,
wie viele Möglichkeiten Sie diese Operation aufteilen möchten. Also lassen Sie uns darüber in ein wenig mehr Tiefe sprechen. Also ist Spark in der Regel ziemlich magisch. Es wird automatisch das Richtige tun, um Ihren Job über einen gesamten Cluster zu verteilen. Aber manchmal müssen Sie ihm
einige Hinweise geben und manchmal müssen Sie ein wenig darüber nachdenken,
wie Ihre Daten über die verschiedenen Executoren in Ihrem Cluster partitioniert werden. Jetzt funktioniert das Ausführen dieses Film-Ähnlichkeitsskripts, wie es ohne
diesen Repartitionierungsaufruf war , möglicherweise überhaupt nicht alleine. Das ist Self-Join ist eine wirklich, wirklich teure Operation, und Spark ist nicht immer schlau genug, um das auf eigene Faust auf die richtige Weise zu verteilen. Das ist wirklich der anspruchsvollste Teil dieses Skripts. Und wir müssen Funken einige Hinweise geben, um sicherzustellen, dass uns die
Ressourcen nicht ausgeht, indem wir einen einzelnen Executor bitten, mehr zu tun, als es tun kann. Indem Sie also explizit repartition auf diesem DataFrame aufrufen. Und wenn Sie RDDs verwenden, gibt es eine Partition BY-Funktion, die dasselbe auf RDDs tut. Wenn Sie dies verwenden, bevor Sie eine große Operation ausführen, die von der Partitionierung profitiert, wird sichergestellt, dass die Dinge auf eine Weise aufgeteilt werden, die sinnvoll ist. Nun sind einige Operationen, die von der Partitionierung profitieren,
Join was wir in diesem Beispiel tun. Auch COGROUP Gruppe mit diesem Join, linken äußeren Join, Bisk, jede Art von Join oder GroupBy Operation oder reduziert durch Operation oder kombiniert durch Operation. Auch Lookup kann davon profitieren. Wenn Sie also eine dieser Methoden für ein sehr großes Dataset aufrufen, möchten
Sie vielleicht darüber nachdenken, sie explizit mit der Repartitionierungsfunktion zu partitionieren. Und wenn Sie das tun, werden
die Operationen diese Partitionierung und die Ergebnisse beibehalten. So erhalten Sie auch Ihre Ergebnisse wieder von diesen Partitionen getrennt. Also bedenken Sie das. Wie wählen Sie jedoch eine Partitionsgröße? Woher kam die Nummer 100? Nun, wenn Sie zu wenige Partitionen haben, wird
das Ihren Cluster nicht voll ausschöpfen, richtig? Also, wenn ich weniger Partitionen habe, dann habe ich Executoren. Das wird einige Executoren bei dieser Aufgabe im Leerlauf lassen. Also möchte ich definitiv mindestens so viele Partitionen wie Executoren auf meinem Cluster haben. Sonst verschwende ich nur Ressourcen, richtig? Also, um das real zu machen, wenn ich die Self-Join-Operation nehme, die wir in diesem Skript verwenden. Und ich sage: Aufteilung zwei. Und ich habe fünf Knoten in meinem Cluster, als drei dieser Knoten ungenutzt werden. Das ist sinnlos, weil ich diese Arbeit nur auf zwei Partitionen
verteilen werde . Aber wenn Sie zu viele haben, führt
das zu viel Overhead durch das Mischen aller Daten. Das Verschieben von Daten in Ihrem Cluster ist daher auch eine teure Operation. Das willst du auch nicht zu sehr machen. Also musst du irgendwie diesen Sweet Spot treffen, wo du die Cluster und die Executoren, die du auf deinem, auf deinem Cluster hast, voll ausnutzt . Aber keine lächerliche Menge an Partitionen zu haben, bei denen der Aufwand für die Verwaltung alles unerschwinglich wird. Im Allgemeinen möchten Sie mindestens so viele Partitionen wie Kerne oder
Executoren haben , die in Ihren verfügbaren Speicher für Ihren Cluster passen 100 ist normalerweise ein vernünftiger Startplatz für große Operationen. Das ist, was wir hier verwenden, es funktioniert. Es ist keine verrückte hohe Zahl, die eine Tonne Overhead haben wird. Und es ist wahrscheinlich eine Zahl, die mehr ist als die Anzahl der Executoren, die Sie in einem typischen Cluster haben. Das ist also in der Regel ein guter Ausgangspunkt. Aber wenn Sie mehr als 100 Executoren hätten, würden Sie dort
offensichtlich eine noch höhere Zahl verwenden wollen. Darum geht es bei der Partitionierung. Auch wenn Sie einen sehr großen Join-Vorgang verwenden oder um gruppieren, kann
dies von expliziter Partitionierung profitieren. Manchmal kann das den Unterschied zwischen dem Erfolg
Ihres Auftrags oder dem Auslaufen des Speichers ausmachen. Wenn Sie also auf seltsame Probleme stoßen, bei denen Ihr Skript fehlschlägt und keine Ressourcen mehr haben, obwohl Sie einen riesigen Cluster zur Verfügung haben. diesem Grund müssen Sie möglicherweise zurückgehen und darüber nachdenken, muss
ich diese Operationen explizit mit dem Befehl repartition partitionieren?
48. Best Practices für den Laufen auf einem Cluster: Lassen Sie uns in ein paar weitere Details des Laufens auf einem Cluster eingehen. zunächst sicher, dass Sie immer vermeiden,
eine Konfiguration für Spark im Treiberskript selbst anzugeben . Dazu gehört auch die Angabe Ihrer Master-Konfiguration. Denken Sie daran, dass wir normalerweise Master setzen auf lokalen Stern, um zu sagen, dass Sie lokal auf Ihrem Computer laufen möchten. Offensichtlich würden Sie das nicht auf einem echten Cluster tun wollen. Sie möchten den gesamten Cluster verwenden, nicht nur einen CPU-Kern, auch mehrere CPU-Kerne auf einem einzigen System. Was möchten Sie jedoch tun, ist
die Standardeinstellungen zu verwenden , die Elastic MapReduce eingerichtet hat, wenn Sie auf
Elastic MapReduce ausführen , und dies gilt für die
meisten Cluster, auf denen Sie möglicherweise ausgeführt werden, auf denen Spark vorinstalliert ist, Odds funkeln bereits aus der Box auf
Ihrem Cluster konfiguriert werden , um das Recht zu haben, Konfiguration fallen zu können. Und Sie möchten auch vorsichtig sein bei allen Befehlszeilenoptionen, die Sie von Ihrem Master-Knoten an Spark Desk übergeben, können
Sie diese überschreiben. Auf diese Weise. Die Art und Weise, wie es funktioniert, ist, dass eine Sache in Ihrem Treiberskript Priorität hat. Danach. Alles, was Sie als Befehlszeilenargument an Spark desk submit übergeben, würde Priorität haben. Und schließlich würden die Konfigurationsdateien auf dem Cluster selbst
das letzte Wort in der Befehlskette haben , wenn Sie so wollen. Also generell, wieder, Ihr Cluster wird mit der richtigen Konfiguration eingerichtet werden out of the box. Und das gilt auch für Elastic MapReduce. Daher möchten Sie im Allgemeinen keine
Konfigurationen im Treiberskript selbst oder in der Befehlszeile angeben . Sie sind in der Regel besser dran, nur zu lassen, dass die Konfiguration ihre Magie für Sie tun. Wenn Sie ein Systemadministrator sind und es Ihre Aufgabe ist, diese Konfiguration einzurichten, dann müssen Sie darüber nachdenken. Aber als Anwendungsentwickler werden Sie in der Regel nicht. Es gibt jedoch Situationen, in denen Sie Dinge optimieren müssen wenn Sie feststellen, dass Ihre Executoren fehlschlagen und einen großen Job haben.
Vielleicht müssen Sie den Speicher anpassen, den jeder Executor hat. Wenn Sie also Fehlermeldungen sehen, die darauf hindeuten, dass Ihnen der Speicher auf Ihren Executor-Knoten nicht mehr zur Verfügung steht. Nun, du musst etwas dagegen tun. Eine Möglichkeit besteht darin, nur die Menge an Speicher zu erhöhen, die jeder Executor ihm zugewiesen hat. Zum Beispiel könnten Sie sagen, sparked estimate, dash, dash executor memory one G. Und das würde explizit jedem Executor ein Gigabyte RAM zuweisen. Natürlich wird davon ausgegangen, dass Sie auf jedem Knoten in Ihrem Cluster genügend RAM
zur Verfügung haben , um das zu entfernen. Aber, weißt du, das ist eine Art Brute-Force-Ansatz, richtig? Und vielleicht sollten Sie mehr darüber nachdenken, Ihre Daten effizienter zu partitionieren und aufzuteilen. Außerdem können Sie einen Cluster-Manager in der Befehlszeile angeben. Zum Beispiel können Sie Strich, Strich Master Garn sagen. Wenn Sie explizit mit dem Garn ausführen möchten, ein Cluster-Manager auf einem Hadoop-Cluster. Aber auch hier wird dies wahrscheinlich standardmäßig für Sie eingerichtet. Und auf Elastic MapReduce wird
es nur automatisch schließen, dass der Standardmaster
der Garncluster-Manager ist , da Elastic MapReduce auf Hadoop ausgeführt wird, das den Garn Cluster Manager hat. Sie müssen also nicht wirklich etwas tun, aber Sie können einen Master über die Befehlszeile angeben, wenn Sie diese Flexibilität haben möchten. Und ein paar weitere Best Practices hier, eine Art Erinnerung. Auch hier ist es sehr wichtig sicherzustellen, dass Ihre Skripte in Ihren Daten oder an einem Ort, an dem EMR oder einem beliebigen Cluster, auf dem Sie ausgeführt werden, darauf zugreifen können. Wenn Sie EMR verwenden, werden Sie wahrscheinlich den AWS S3-Dienst verwenden. Das ist ein einfacher Speicherdienst. Und wenn Sie das tun, können Sie einfach das S3,
AN URL-Präfix verwenden , um den Pfad zu Ihrem S3-Bucket anzugeben. Und Sie müssen nur sicherstellen, dass Ihre Dateiberechtigungen für Ihren EMR-Cluster zugänglich
sind. Das kann manchmal eine schwierige Sache mit AWS im Allgemeinen sein, diese Berechtigungen, ich meine,
das einfachste, was zu tun ist, ist, Ihren Bucket einfach öffentlich zugänglich zu machen. Aber wenn es sich dabei um sensible Daten handelt, müssen
Sie über explizitere Berechtigungen nachdenken, bei denen Sie
Dinge speziell an den Speicherort Ihres EMR-Clusters binden . Und ich möchte in diesem Kurs nicht auf die Besonderheiten der AWS-Sicherheit eingehen, das ist ein ganz anderes Thema, aber es ist möglich, wenn Sie alles dort haben, wo es sein muss können
Sie Ihren Cluster mit dem AWS -Konsole oder wenn Sie die API verwenden möchten, ist das auch in Ordnung. Und sobald du den Cluster hochdrehst, fängt die Uhr an. Und denken Sie daran, sobald Sie den Cluster hochdrehen, beginnt
die Uhr mit der Abrechnung, es spielt keine Rolle, dass Sie es nicht benutzen, Sie werden stundenweise dort in Rechnung gestellt. Und für einen Cluster, der große Maschinen enthält und viele von ihnen, die extrem teuer werden können, extrem schnell. Also vergewissern Sie sich, dass Sie wissen, was Sie da drin tun. Sobald du den Cluster aufgesponnen
hast, musst du, du musst eilen, denn Zeit ist Geld, richtig? Sie müssen also den externen DNS-Namen für diesen Master-Knoten abrufen. Melden Sie sich mit dem Hadoop-Konto und Ihrer privaten Schlüsseldatei an, die Sie beim Einrichten des Clusters verwendet haben. Sobald Sie in Kopie über Ihre Treiber JAR-Programmdatei und alle Dateien, die Sie auf dem Treiber des Skripts selbst benötigen. Sie können den AWS S3 cp Befehl verwenden, um Dinge zu kopieren, die Sie ihn im Voraus in S3 hochladen, und dann die Sparked Schätzung ausführen, und hoffentlich funktioniert es. Und noch einmal, denken Sie daran, Ihren Cluster zu beenden, wenn Sie fertig sind. Wenn Sie vergessen haben, Ihren Cluster herunterzufahren, nachdem Ihre Arbeit erledigt ist , werden
Sie am Ende des Monats eine
sehr, sehr, sehr böse Überraschung auf Ihrer Kreditkartenrechnung bekommen . Und es ist übrigens möglich, mit EMR Dinge so einzurichten, dass
ein Skript automatisch ausgeführt wird , sobald es hochgedreht wird und automatisch heruntergefahren wird, sobald es fertig ist. Also, sobald Sie die Fehler aus Ihrem Skript herausgearbeitet haben und Sie können es zuverlässig ausführen. Sie können die Dinge so einrichten, dass, sobald Sie drehen , dieser Cluster automatisch startet Ihren Job. Und es ist, diesen Cluster runter zu drehen, wenn du damit fertig bist. In manchen Situationen macht das Sinn. In anderen Situationen kann Ihr Unternehmen genug Geld haben, um nur diesen Cluster laufen die ganze Zeit zu halten und es für seinen Entwickler zugänglich zu halten 24, 7. Aber für die meisten von uns haben
wir diesen Luxus nicht zur Verfügung. Sie müssen also darüber nachdenken, dass Sie beobachten, wie lange Ihr Cluster 4 ausgeführt wird. Und der beste Weg, um diese Kosten zu minimieren, besteht darin, die Knicke in Ihrem Skript lokal zu debuggen und auszuarbeiten. Zuerst, bevor Sie versuchen, es auf einem tatsächlichen Cluster auszuführen. Das haben wir während dieses Kurses gemacht. Wenn Sie also ein großes Dataset haben, das Sie nicht auf
einem Computer ausführen können , verwendet
zunächst eine Teilmenge dieser Daten, um die Knicke in Ihrer Anwendung zu ermitteln. Und wieder, stellen Sie sicher, dass alle Datendateien, die Sie benötigen jede Executor Notiz auf jedem Computer, der sich möglicherweise in Ihrem Cluster befinden,
zugänglich sind. Alles, was tatsächlich referenziert oder von
einem verteilten Executor gelesen werden könnte , muss über den Ort hinaus
zugänglich sein , an dem Ihr Treiberskript ausgeführt wird. Also, solange Sie vorsichtig mit diesem Zeug sind und Sie wieder vorsichtig sind, keine Konfiguration
anzugeben, die spezifisch für die Ausführung auf
einem einzelnen Computer in Ihrem endgültigen Treiberskript ist , sollten
Sie in der Lage sein, die Dinge ziemlich nah an zuverlässig ausgeführt bevor Sie mit dem Experimentieren auf dem Cluster selbst beginnen.
49. Fehlerbehebung und Überlegenheit: Lassen Sie uns also etwas tiefer über die
Fehlerbehebung Ihrer Aufträge eingehen , sobald sie auf einem Cluster ausgeführt werden. Leider ist es ein bisschen eine dunkle Kunst. Es kann sehr schwierig sein,
diese Arten von Fehlern zu finden, wenn sie innerhalb der Komplexität
von Spark selbst und darüber hinaus auf
die Komplexität der Verteilung auf mehrere Knoten ausgeführt von Spark selbst und darüber hinaus auf werden. Jetzt wird Ihr Master eine Konsole auf Port 4040 ausführen, mit der Sie
einige Informationen darüber sehen können, was in passiert, die
manchmal zu einigen Einblicken darüber führen können , warum Ihr Job fehlschlägt. Aber wenn Sie Fehlermeldungen in Ihren Protokollen sehen, wird
es ziemlich schwierig sein, sie für eine Sache aufzuspüren. Zuallererst werden Sie diesen tiefen Aufrufstapel
in Ihren Protokolldateien sehen , wenn Sie einen Fehler haben,
denn denken Sie daran, dass Sie Ihren Scala-Code ausführen, der bis zu Java-Code kompiliert wird. Und durch all diese Ebenen der Kompilierung ist
es leicht, sich irgendwie in der Lage zu verlieren, wo Dinge laufen. Normalerweise werden Sie Dinge sehen, wie tief im Rahmen von Spark selbst sterben. Und wenn Sie hart genug aussehen, sollten Sie schließlich
eine Fehlermeldung oder eine Art
Ausnahme sehen eine Fehlermeldung oder eine Art , die Sie zu dem tatsächlichen Problem in Ihrem Skript führt, aber Sie haben nicht immer so viel Glück. wir jedoch einen Blick auf die Master-Konsole hier, um zu sehen, welche Informationen sie uns jetzt gibt. Und wieder, das ist, dass dies selbst schwierig sein kann, weil ein Elastic MapReduce, es praktisch unmöglich ist, tatsächlich eine Verbindung mit dem von außerhalb Ihres Clusters herzustellen. Wenn Sie also von
Ihrem Desktop aus eine Verbindung zu dieser Konsole herstellen möchten , der außerhalb Ihrer EMR-Umgebung ausgeführt wird. Das ist eine schwierige Sache zu schaffen. A kann durch Dinge wie Proxy-Hosts und solche Dinge getan werden. Aber es ist hart. Wenn Sie jedoch einen eigenen Cluster haben, Ihrem eigenen Netzwerk
läuft, wird
das Leben viel einfacher in dieser Hinsicht für Ihr Ohr sein, diese Sicherheitsprobleme sollten etwas sein, das Sie ein wenig leichter durcharbeiten können. Werfen wir einen Blick auf die Konsole, die auf
unserem eigenen lokalen Computer läuft , als eine Möglichkeit, loszulegen. Und wir werden die Informationen untersuchen, die es Ihnen gibt. In Ordnung, also lasst uns die Spark-Konsole erkunden, über die ich gesprochen habe. Jetzt leider wird es nur verfügbar sein, während Spark selbst läuft. Also, wenn ich nicht tatsächlich
eine konstante Datenbankschnittstelle betreibe , um oder so etwas zu funken. Ich werde nur in der Lage sein, es zu erreichen, während mein Funken-Skript tatsächlich ausgeführt wird. Um der Illustration willen, lassen Sie uns hier ein wirklich fleischiges Funken-Skript starten, das für ein paar Minuten laufen wird, also haben wir Zeit, es in den Kursmaterialien zu erkunden. Es gibt einen Film-Empfehlungs-Dataset, ein lokales Skript. Und dies ist so eingerichtet, dass Sie hier das ML 1 Million Dataset lokal auf Ihrem Rechner verwenden. Sie müssen das also nicht unbedingt mit mir ausführen, aber wenn Sie möchten, werden Sie sehen, dass ich das ML dash 1M-Dataset
hier im Datenordner meiner Kursmaterialien installiert habe. Und dieses Skript ist dazu gedacht, das zu benutzen. Also, sobald ich das abfeuere, wird
das für ein paar Minuten laufen, um herauszufinden die ähnlichsten Filme wie Star Wars. Und während es das tut, können
wir die Konsole erkunden. Und ich habe hier einen Webbrowser, der bereit ist, dafür zu gehen. Richten Sie bis 127 Punkt 0 ein, das ist 0 Punkt ein Doppelpunkt 4040, 127, 100, 000 Punkt eins ist die IP-Adresse unseres lokalen Hosts. Und da ich Spark lokal auf meinem Desktop hier laufe, wird
das die IP-Adresse sein, die ich für die Spark-Konsole treffen werde. Und 40, 40 ist der Port, auf dem es läuft. Also werde ich das loslegen. Und sobald Spark läuft, werde ich diese Seite neu laden und wir sollten eine Konsole sehen. Also gehen wir zurück zu IntelliJ und wir starten das. Und ich gebe ihm ein bisschen Zeit, sich zu drehen. Wir wollen sicherstellen, dass es tatsächlich Zeit hat, anzufeuern. Es sind Vollstrecker. Ich glaube, wir sind da. Gehen wir zurück zu unserem Dashboard und laden Sie es neu. Und ich werde voran gehen und jedes von ihnen in einem neuen Tab öffnen, damit wir diese erkunden können. Und wenn Sie zu Jobs gehen, können Sie sehen, dass wir hier jede einzelne Job-ID durchbohren können. Und Sie können Dinge tun, wie visualisieren Sie den gerichteten azyklischen Graphen. Das ist ziemlich cool. Sie können das Gleiche von Stufen aus tun. Graben Sie sich wieder in jede Phase ein, die Sie wollen. Dieser hier, Nehmen wir es zum Beispiel, dass man noch nicht begonnen hat. Also lasst uns den ersten probieren. Und Sie können sehen, das gibt uns auch eine Menge mehr Informationen. Auch hier steht eine DAG-Visualisierung zur Verfügung. So kann das einfach weiterlaufen und seine Sache tun, während wir dies an dieser Stelle erkunden. Also gehen wir zurück auf die Registerkarte Jobs hier. Sie können sehen, dass es Ihnen eine Art grafische Darstellung der Ereignis-Timeline gibt. Also haben wir den Fahrer an dieser Stelle gestartet und es wurde
versucht , diese letzte Take Aktion auszuführen und herauszufinden was er tun muss, um diese letzte Aktion zu erfüllen, die wir im
Treiberskript haben , um die Top Ten Filme Ähnlichkeiten zu erhalten Star Wars. Das zeigt Ihnen den Fortschritt, da es alle Aufgaben durchläuft, um das zu erreichen. Und wenn Sie auf den Bühnen-Tab gehen, können
Sie sehen, es zeigt Ihnen Ihren Fortschritt entlang dieser Linie. Und denken Sie daran, dass Phasen
jeden Punkt innerhalb der Ausführung darstellen , an dem Daten gemischt werden müssen. Es ist also gut, etwas zu visualisieren, wie viele Phasen
wirklich in die Erfüllung der gewünschten Aufgabe involviert sind . Weil mehr Etappen schlecht sind. Jedes Mal, wenn Sie eine Phase haben, muss sie Daten im gesamten Cluster mischen. Und das ist eine sehr teure Operation. Wenn Sie also weniger Etappen sehen, ist das eine gute Sache. Und wieder können Sie in eine individuelle Phase bohren. Ich denke, es ist wirklich fertig, also können wir uns das ansehen. Lass uns weitermachen und das Drehbuch nochmal loslegen. Okay, wir haben ein paar Ergebnisse, um eine Neugier zu machen. Hey, das hat ziemlich gut geklappt. So funktionierte unser ähnlicher kollaborativer Filteralgorithmus ziemlich gut. Sagte das Top-Ergebnis für Episode für Star Wars, Episode 5, Star Wars, Es ist wie wir in unseren Folien hatten. Also, das ist cool zu sehen. Strahlen der verlorenen Arche, Star Wars Folge 6, Indiana Jones. Alle tollen Empfehlungen für Star Wars, aber lassen Sie uns das noch einmal starten, damit wir mit der Konsole noch mehr spielen können. In Ordnung, also zurück zum Bühnen-Tab. Ich glaube, da haben wir gespielt. Auch hier können Sie auf eine einzelne Bühne klicken. Ich sollte das neu laden, um mehr darüber zu erfahren, was darin los ist. Und es sagt dir allerlei Sachen. Wie lange dauert es, bis diese Daten herumgeschlitzt werden. Denken Sie daran, dass Phasen mit Shuffling-Daten verbunden sind. Wir können den gerichteten azyklischen Graphen, den es entwickelt hat, visualisieren. Also, das ist ziemlich cool zu sehen. Wenn Sie also versuchen, die Leistung Ihres Auftrags zu optimieren, können Sie
dies einige
Einblicke in das geben , was Sie gebeten haben. Und manchmal kann das zu einer besseren Strukturierung
Ihres Treiberskripts führen , um effizienter zu sein. Was können wir sonst noch sehen? Der Speicher wird wahrscheinlich leer sein. Ich verstecke nichts. Environment gibt Ihnen einige Informationen über die Laufzeitumgebung. Lassen Sie uns das auch auffrischen. Und Sie können sehen, dass wir unter dem JDK laufen und unter JDK 14 auf meinem C-Laufwerk laufen. Mit dieser Java-Version, dieser Scala-Version, nur einige allgemeine Informationen. Wir können auch Systemeigenschaften betrachten. Wenn Sie also mehr Informationen über
die Umgebung erhalten möchten , in der Ihr Skript ausgeführt wird, können Sie das tun. Sie stehen unter Vollstreckern. Dies zeigt Ihnen, wie viele Executoren laufen, und das selbst ist interessant. Also läuft gerade nur ein einziger Executor. Das sagt mir zum Beispiel,
dass, obwohl ich hier mehrere CPU-Kerne auf meinem Rechner habe, es es nicht wirklich benutzt. könnte also die Art der Natur sein
, mir zu sagen , dass ich Dinge nicht so geschrieben habe, wo es
parallelisiert werden kann , oder es könnte etwas
falsch mit meiner Konfiguration sein , das zu diesem Problem führt. Wenn ich das auf einem echten Cluster ausgeführt habe und nur einen Executor während der gesamten Laufzeit davon ausgeführt habe. Das würde mir wahrscheinlich einen ziemlich starken Hinweis geben,
dass etwas wirklich nicht mit der Konfiguration in meinem Cluster stimmt, dass ich herausfinden sollte. Das ist also eine Art Überblick über die Dinge, die Sie mit der Spark-Konsole sehen können. Lassen Sie uns damit über ein wenig mehr Tiefe
über die Fehlerbehebung sprechen , sobald Sie es haben. Wenn nun Dinge schief gehen, werden
Ihre Protokolle im Standalone-Modus auch in dieser Web-Benutzeroberfläche verfügbar sein. Aber wenn Sie auf dem Garncluster Manager laufen, wie wir es mit EMR tun. Diese Protokolle werden auf jeden einzelnen Knoten in Ihrem Cluster verteilt. Jetzt können Sie sie nach der Tatsache mit Garn Protokolle Strich sammeln, Strich Anwendung ID. Sie können die Anwendungs-ID Ihres Auftrags ermitteln, der dort ausgeführt wird. Wenn Sie also
im eigenständigen Spark Cluster Manager laufen , kann das Leben ein wenig einfacher sein. Es wird genau dort in der Benutzeroberfläche für Sie sein. Aber wenn Sie auf Hadoop laufen, werden die
Dinge kompliziert, um diese Protokolle tatsächlich zu finden. erneut betont, wie wichtig es ist, diese Probleme
lokal auf Ihrem eigenen Computer zu debuggen , bevor Sie versuchen,
sie in einem Cluster zu debuggen , in dem es schwieriger ist, diese Informationen zu erhalten. Jetzt, während Ihr Treiberskript ausgeführt wird, protokolliert
es selbst Fehler wie Executoren, die keine Heartbeats ausgeben. Das ist also ein gutes Zeichen dafür, dass Ihr Executor irgendeinem Grund auf einem entfernten Knoten
fehlschlägt und abstürzt. Manchmal kann Ihre Treiberskripte Ausgabe Ihnen einige Hinweise geben, was passiert. Wenn Sie solche Fehler sehen, bedeutet das
wahrscheinlich, dass Sie zu viel von jedem Executor fragen. Vielleicht brauchen Sie mehr von ihnen, vielleicht benötigen Sie nur mehr Maschinen in Ihrem Cluster, um die Arbeit zu bewältigen, die Sie tun. Vielleicht müssen Sie jedem Executor mehr Speicher geben. haben wir in der vorherigen Lektion behandelt. Wie macht man das? Das kann nur ein zusätzlicher Befehlszeilenparameter auf Spark submit sein. Oder vielleicht müssen Sie PartitionBy oder repartition verwenden, um weniger Arbeit von Ihren einzelnen Executoren zu verlangen, indem Sie kleinere Partitionen verwenden. Das Werfen von mehr Maschinen-Editor oder mehr Speicher ist eine Art Brute-Force-Lösung für Probleme wie diese. Aber manchmal, wenn Sie nur explizit
repartition verwenden , um den Job in kleinere Teile zu zerlegen, können
Sie mit weniger Hardware oder weniger Speicher auskommen. Es wird nur mehr Zeit dauern, um den Job zu beenden. So oft ist das eigentlich das Richtige zu tun. Also sehen Sie nicht nur no go werfen mehr Hardware auf das Problem, wenn Sie es nicht brauchen. Wenn Sie große Joint-Operationen in Ihrem Skript oder große GroupBy Operationen ausführen oder Operationen reduzieren. Sie können diese Probleme wahrscheinlich nur durch vernünftige Verwendung
des Befehls repartition lösen, um Dinge in kleinere Stücke zu zerlegen. Und denken Sie noch einmal daran, Ihre Executoren nicht unbedingt auf derselben Box laufen wie Ihr Treiberskript. Sie können also nicht davon ausgehen, dass Daten im Speicher über den gesamten Cluster zugänglich sind. Sie müssen sicherstellen, dass das der Fall ist. Wenn Sie Daten außerhalb Ihrer RDDs freigeben müssen, müssen
Sie Broadcast-Variablen verwenden, um dies zu tun. Sie können das nicht einfach lokal in Ihrem Treiberskript speichern und erwarten, dass es funktioniert. Wenn Sie eine Art Java- oder Scala-Paket benötigen, das nicht auf Ihrem Cluster vorinstalliert ist, sicher, dass Sie sie in Ihrem Jar bündeln, das Sie mit der SBT-Assembly ausführen. Oder Sie können dash, dash jars mit Spark submit verwenden, um
einzelne Bibliotheken hinzuzufügen , die sich auf
dem Master-Knoten befinden und die sie automatisch an die ER-Executoren verteilen. Aber das kann wirklich
schnell kompliziert werden, da die Gläser, die Sie
selbst einschließen möchten, oft JAR-Abhängigkeiten haben und Sie alle diese Abhängigkeiten zusammen mit ihm angeben müssen. Viel einfacher, nur sbt zu verwenden, um alles zusammen in das Glas selbst zu verpacken. Und wissen Sie, wirklich nur zu versuchen,
obskure Pakete zu verwenden , die Sie überhaupt nicht wirklich brauchen ist wahrscheinlich der beste Rat. Denken Sie daran, Zeit ist Geld auf Ihrem Cluster und wenn Sie keine Zeit
damit verschwenden mit den Problemen über die Verteilung dieser JAR-Pakete in Ihren Executoren zu experimentieren. Nun, umso besser. Wenn Sie also nur die Kern-Pakete und wenig mehr verwenden können, wird
das wahrscheinlich die beste Strategie zur Vereinfachung der Dinge sein. Denken Sie daran, eine einfache ist gut, wenn es um Software-Engineering im Allgemeinen geht. Und damit, denke ich, wir haben darüber gesprochen, auf einem Cluster in der Tiefe zu laufen. Gehen wir also zu unserem nächsten Abschnitt über.
50. MLLib vorstellen: Dieser nächste Abschnitt ist ziemlich spannend für mich, weil ich maschinelles Lernen sehr mag. Das ist ein großer Teil von dem, was ich in der Vergangenheit getan habe. Und wir werden darüber sprechen, wie man maschinelles Lernen auf Spark nutzt. Und das ist super spannend, weil die Leistung von
maschinellen Lernalgorithmen in der Regel auf eine einzige Maschine beschränkt ist. Viele Male entwickeln die Leute diese einfach auf einem einzigen PC, auf dem irgendwo ein Notebook läuft, oder? Aber wenn Sie einen massiven Datensatz haben, was tun Sie dann? Nun, Spark hat tatsächlich eine Lösung für viele beliebte maschinelle Lernalgorithmen. Lassen Sie uns also eintauchen und sehen, wie die Sparks ML-Bibliothek es Ihnen ermöglicht,
Datenrahmen über einen gesamten Cluster auf
Spark anzuwenden Datenrahmen über einen gesamten Cluster auf , um komplizierte Machine Learning-Probleme zu lösen. Ziemlich mächtiges Zeug. Lasst uns eintauchen. Lassen Sie uns über Sparks Machine Learning Library sprechen, die erstaunlich genug genannt Sparks ML-Bibliothek, kreativer Name. Es ist wirklich cool, weil es Ihnen ermöglicht, die Verarbeitung von
massiven Datensätzen zu verteilen und
anspruchsvolle maschinelle Lernalgorithmen auf sie in großem Maßstab anzuwenden . Es gibt also einfachere Möglichkeiten, diese Algorithmen und Techniken auf
Daten auf einer einzigen Maschine anzuwenden , nur mit Python Code und Jupiter Notebooks. Aber wenn es an der Zeit ist, dieses Zeug tatsächlich über
einen gesamten Cluster zu verteilen , weil Sie ein wirklich massives Dataset haben. Nun, diese Werkzeuge, die so häufig verwendet werden, fallen auseinander und wir müssen es so
etwas wie Spark ML drehen , um diese Arten von Aufgaben im großen Maßstab bewältigen zu können. Es muss ein wenig schwer sein, darüber zu sprechen, was ML tut, ohne einen Hintergrund im maschinellen Lernen zu haben. Und wenn Sie neugierig auf diese Algorithmen sind, ermutige
ich Sie definitiv dazu,
einen speziellen Kurs für maschinelles Lernen zu nehmen , um zu erfahren, worum es bei ihnen geht. Ich werde Ihnen hier einen sehr hohen Überblick über sie geben und
wie, so gut ich in einer einzigen Folie zumindest tun kann. Also die grundlegenden Funktionen von Sparks ML-Paket oder Feature-Extraktion, die etwas namens TF-IDF enthält, das ist Begriff Frequenz inverse Dokument Frequenz. Und das sind Analysen, die hauptsächlich für die Suche verwendet werden. So können Sie herausfinden, welche Begriffe für ein Dokument am relevantesten sind. Sehr einfache Art, das zu tun. Es hat auch einige grundlegende Statistiken Zeug integriert. Wenn Sie möchten, wie einfach
Korrelationskoeffizienten oder Chi-Quadrat-Tests und solche Dinge berechnen . Es kann das im Maßstab tun. Und dann kommen wir selbst in die eigentlichen maschinellen
Lernalgorithmen ein, die interessanter sind. So kann es lineare Regression und logistische Regression tun. Die lineare Regression passt nur im Grunde eine Linie an einen Satz von Daten an. So können Sie sich beispielsweise vorstellen, dass Sie ein Dataset haben , das die Höhen der Personen ihrem Alter zuordnet. Und indem Sie eine Linie an die beobachteten Daten anpassen, können
Sie tatsächlich neue Datenpunkte an diese Linie anpassen, um ihren tatsächlichen Wert vorherzusagen. Wenn ich also eine Linie habe, die Alter als eine Funktion der Höhe definiert, kann
ich tatsächlich neue Höhen an diesem Modell schlagen, das noch nie zuvor gesehen hat, und ihr Alter
vorhersagen, indem ich es über diese Linie extrapoliere. Das ist eine lineare Regression. Logistische Regression ist irgendwie die gleiche Idee unter der Haube, aber es ist für Klassifizierungszwecke. Also, wenn ich sagen will, ob jemand
zum Beispiel Demokrat oder Republikaner ist, könnten Sie logistische Regression verwenden, um das zu tun. Wenn ich vorhersagen möchte, ob ein Auto ein Sportwagen oder eine Limousine ist, basierend auf einigen Attributen. Das könnte ein weiteres Beispiel für logistische Regression sein. Wir wenden wieder eine sehr einfache mathematische Funktion an, um Klassifizierungen im Gegensatz zu tatsächlichen Werten
vorherzusagen, was Sie mit linearer Regression tun werden. Es kann auch Vektormaschinen unterstützen. Dies sind eine andere Art
, Klassifizierung zu machen , die ein wenig anspruchsvoller ist, wenn Sie so wollen. Es funktioniert in diesen höherdimensionalen Räumen und kann
komplexere Unterteilungen zwischen Klassifikationen finden , die nicht unbedingt linear sind. Es kann auch Naive Bayes Klassifizierung. Das Plakat Kind einer Bewerbung für eine Naive Bayes ist Spam-Klassifizierung. Ein sehr häufiges Beispiel für naive Bayes ist, ihm einen Korpus von
E-Mails zu füttern und ein Trainingsset zu haben, das als Spam und nicht als Spam markiert ist. Und Sie können diesen Naive Bayes-Klassifikator trainieren, um neue E-Mails zu nehmen, die es noch nie gesehen hat, und vorherzusagen, ob ihre Spam oder nicht auf diesem naiven Bayes-Modell basiert. Es kann auch Entscheidungsbäume tun, die über einen gesamten Cluster verteilt sind, was wirklich cool ist. Ich mag Entscheidungsbäume sind nur Spaß zu sehen, ihre, wie sie klingen. Es ist im Grunde dieser Baum der Entscheidungen. Also im Grunde werden Sie mit einer Entscheidung beginnen, wie, ich weiß nicht, ist dies die Temperatur außerhalb über 72 Grad oder unter 72 Grad. Wenn es über 72 Grad ist, gehen Sie
vielleicht zu einem anderen Entscheidungsblock. Und vielleicht diese nächste Entscheidung. Und der Entscheidungsbaum ist, regnet es oder nicht? Und vielleicht könnte das dich letztendlich zu einer Entscheidung führen, ob du heute nach draußen gehen und spielen
solltest, wenn es ein schöner Tag ist oder nicht, oder? Das ist ein sehr einfaches Beispiel für einen Entscheidungsbaum. Offensichtlich können Sie viel komplizierter werden und es kann in
beliebigen Situationen funktionieren , in denen Sie viele Funktionen haben, die numerisch sind, die mit einigen eingestellten Werten verglichen werden können. Und wenn Sie Entscheidungen in der Reihenfolge zwischen diesen verschiedenen Merkmalen Ihrer Daten treffen, können
Sie mit einem Entscheidungsbaum zu einer Entscheidung gelangen. K-bedeutet Clustering, nur eine Möglichkeit, Daten basierend auf ihren Attributen zusammenzufassen, basierend darauf, wie ähnlich die Dinge einander sind. In einem sehr einfachen Mittel. Das nennen wir „unbeaufsichtigtes Lernen“, dem wir kein Modell basierend auf bekannten Werten trainieren. Wir versuchen, Dinge nur zusammenzufassen, basierend auf ihren natürlichen Eigenschaften und wie ähnlich die Dinge einander sind. Und es kann auch Hauptkomponentenanalyse durchführen, bekannt als PCA für kurze und singuläre Wertzerlegung, kurz SVD. Dies sind, was wir Dimensionalitätsreduktionstechniken nennen. Manchmal haben Sie dieses Problem, wenn Sie Daten
haben, die viele verschiedene Funktionen haben. Weißt du, verschiedene Dinge, die wir für verschiedene Objekte messen. Und es wird, es verursacht, was wir die kursive Dimensionalität nennen. Dies ist im Grunde ein dünnes Datenproblem, bei dem Sie zu viele Funktionen haben. Dies sind Möglichkeiten, diese auf die wichtigsten Merkmale zu kochen. Vielleicht sind es synthetische Eigenschaften, die überhaupt nicht in der realen Welt existierten. Es handelt sich jedoch um eine Möglichkeit, höherdimensionale Feature-Daten in
niedrigere Dimensions-Feature-Daten zu kochen , wodurch die Arbeit etwas einfacher wird. Und schließlich kann es Empfehlungen
mit einer Technik namens Alternating Mindest Squares tun . Und das werden wir sehr bald noch tiefer eingehen. Als ist cool. Es gab eigentlich vor langer Zeit einen Wettbewerb, der von
Netflix gesponsert wurde , um ein besseres Empfehlungssystem als ihr eigenes zu entwickeln. Und einer der gewinnenden Einträge, die sie Teil ihrer Lösung sind, war die Verwendung von ALS. So, so ist das auch für Sie in Spark ML verfügbar. Jetzt ist es eine Art begrenzte Liste von dem, was Sie tun können. Ich meine, es gibt unzählige weitere maschinelle Lernalgorithmen da draußen, aber nicht alle von ihnen eignen sich wirklich gut dafür, über einen Cluster verteilt zu werden. Bis zum heutigen Tag gibt es viele Algorithmen
für maschinelles Lernen bei denen wir sie nur vertikal skalieren. Wir können sie nur auf einer einzigen Maschine ausführen. Und wir sind irgendwie zurück zu den alten Zeiten großer monolithischer Datenbanken, wo die einzige Möglichkeit ist, diese Dinge zu tun, ist eine wirklich große Maschine
zu haben, auf
der sie mit vielen GPUs und viel Speicher und all dem guten Zeug ausgeführt werden können. Aber spärliche Art ebnet den Weg zur horizontalen Skalierung des maschinellen Lernens. Und es ist wirklich aufregend. Jetzt gab es eine vorherige API, die in Spark eins und in Spark zu ML Lib gab. Und das war eine API auf niedrigerer Ebene, die RDDs verwendet, und eine spezielle Datenstruktur ist, diese Algorithmen auszuführen. Jetzt in Spark 3 ist
das veraltet und Teile davon funktionieren überhaupt nicht mehr. Und ehrlich gesagt, den Betreuern von Spark ist es
egal , weil es sich an dieser Stelle nur im Wartungsmodus befindet. Sie möchten also wirklich, dass Sie in die neue ML-Bibliothek wechseln. Der Unterschied besteht hauptsächlich darin, dass es DataFrame für alles verwendet. Anstatt also RDDs und diese spezialisierten Datenstrukturen zu übergeben, werden
Sie Datenrahmen und Datasets verwenden, was wirklich die API ist, auf die sie jeden drängen möchten. Der Vorteil ist, dass
Sie durch die Verwendung von DataFrame in allen verschiedenen Komponenten von Spark DataFrame in allen verschiedenen Komponenten von Sparkdiese DataFrame nahtlos von einer Komponente an eine andere weitergeben können. Also, das ist irgendwie eine größere Vision. Sie möchten in der Lage sein, einen DataFrame zu nehmen, der aus Spark ML kommt und ihn vielleicht an Spark SQL und vielleicht an GraphX weiterzuleiten. Wer weiß es richtig? Diese Interoperabilität, die durch diesen Allzweck-DataFrame spannend wird. Das ist eine Art Lingua Franca all
dieser Spark-Komponenten einschließlich maschinellem Lernen. Wenn Sie mehr Tiefe wollen, Es gibt ein Buch namens Advanced Analytics mit Spark von O'Reilly veröffentlicht, wahrscheinlich ein wenig veraltet jetzt,
Ich weiß nicht, ob sie eine aktualisierte Version für die neue ML-Bibliothek haben, aber es ist eine ziemlich gute Ressource. Alles von O'Reilly ist in der Regel eine gute Lektüre. Die aktuelleren Beispiele oder werden immer im Spark SDK selbst sein. Es gibt ein Beispielverzeichnis im SDK. Und wenn Sie dort eintauchen, finden
Sie ein Beispiel für jeden dieser Algorithmen, der tatsächlich verwendet wird. Und wieder, für mehr Tiefe auf die tatsächlichen Algorithmen und wie sie zu verwenden und wie sie funktionieren. Ich werde Sie auf einen anderen Kurs verweisen, nicht auf diesen Kurs zum maschinellen Lernen im Allgemeinen. Damit, Lassen Sie uns es in die Praxis umsetzen. In unserem nächsten Vortrag werden wir tatsächlich Filmempfehlungen
mit dem ALS-Modul generieren , über das wir in Spark ML gesprochen haben. Und es ist wirklich aufregend, weil es wirklich, wirklich einfach zu bedienen ist. Empfehlungssysteme sind also wirklich komplizierte Dinge und alternierende kleinste Quadrate verwendet diese Matrixfaktorisierungsmethode. Es ist eine sehr Hardcore-Mathematik unter der Haube hier. Aber um es tatsächlich auf Spark zu verwenden und tatsächlich über einen gesamten Cluster zu verteilen, ist
dies alles, was Sie tun müssen. Wie ist das nicht genial? Also lasst uns das ein bisschen durchgehen. Alles, was wir hier tun, ist das Laden einer Datendatei, die unser Movielens Bewertungsdatensatz aus u dot Daten
sein wird. Wir ordnen das dann in eine Rating-RDD mit den niedrigeren Level-APIs zu, weil wir hier irgendwie einfache Transformationen machen. Und dann konvertieren wir das in einen DataFrame, um es mit Spark ML kompatibel zu machen. Wir erstellen dann einfach ein neues ALS-Objekt aus der ML-Bibliothek. Wir legen fest, was man ein paar Hyperparameter nennt. Dirty kleines Geheimnis des maschinellen Lernens ist eine Menge dieser Algorithmen sind nur so gut wie die Hyperparameter, die Sie in sie gesetzt. Also die maximale Anzahl von Iterationen, der Regularisierungsparameter. Dies sind zwei Beispiele für Hyperparameter mit dem ALS-Algorithmus. Und die meisten Algorithmen für maschinelles Lernen haben mehrere von ihnen. Und wie gut sie funktionieren, hängt von diesen Parametern ab. Und die schmutzige kleine Wahrheit ist, dass es weitgehend noch eine Frage von Versuch und Irrtum ist,
die Parameterwerte zu finden , die am besten für ein bestimmtes Problem funktionieren. Wir denken also gerne, dass wir diese Modelle sehr tief verstehen, aber in Wirklichkeit ist viel davon immer noch Rätselraten. Aber sobald wir diese Werte dort haben, um damit zu beginnen, können wir
zumindest ein neues ALS-Objekt erstellen. Wir sagen Ihnen, wo sich die Benutzer-ID, Film-ID und Bewertungsinformationen in unserem DataFrame befinden. Und dann können wir das ALS-Modell einfach als fit bezeichnen. Und das wird losgehen und trainieren ein Modell mit all diesen MoviElens-Daten. Und an diesem Punkt können wir einfach dieses Modell verwenden, um
Vorhersagen für neue Benutzer zu machen , die wir noch nie gesehen haben. Also ist es einfach. Lasst uns damit spielen. Lass es uns laufen.
51. [Aktivität] Verwendung von MLLib zum Produzieren von Filmempfehlungen: Lassen Sie uns also
den Alternating Mindest Squares Recommender-Algorithmus verwenden , der in die ML Lib
integriert ist , der Teil von Spark ist. Und wir werden uns die Filmeempfehlungen ALS-Dataset-Skript für diese zu betrachten. Nun, bevor wir in das einsteigen, was wir getan haben, um dies zu testen, ist
eine Art gefälschte Persona eines Benutzers zu schaffen , dessen Geschmack ich
zumindest ein wenig verstehen kann , das mir qualitativen Sinn gibt, ob die Empfehlungen sind gut oder nicht. Um das zu tun, habe ich tatsächlich in
mein MO 100 K-Dataset gegangen und die u dot Datendatei bearbeitet. Und was ich getan habe, ist in drei Zeilen für einen gefälschten Benutzer 0 hinzugefügt, Benutzer 0 war zuvor in diesem Dataset nicht vorhanden. Und das ist eine sehr einfache Person hier. Grundsätzlich habe ich gesagt, dass diese Benutzer-ID Artikel 50,
Film-ID 50 und Film-ID 172 sehr mag . Er gab ihnen beide fünf Sterne. Und diese entsprechen dem Film Star Wars Episode 4 und Star Wars Episode 5. Eine neue Hoffnung im Imperium schlägt zurück. Also haben wir festgestellt, dass diese Person einen wirklich großen Star Wars Science-Fiction-Fan hat. Und im Gegensatz dazu habe ich auch gesagt, dass für Film 133, die mit dem Wind verweht ist, Das war nur ein Stern. Also habe ich hier eine sehr einfache Persona geschaffen. Jemand, der Star Wars und Science-Fiction vermutlich liebt, aber wirklich kein Fan alter romantischer Dramen ist, oder? Und das ist jemand, den ich mit mir selbst in Verbindung bringen kann. Das gibt mir also eine Art persönliches Gefühl oder Sinn, ob diese Ergebnisse gut sein werden oder nicht. Jetzt gibt es Möglichkeiten, objektiv zu messen, wie gut eine Reihe von Empfehlungen sind. Aber oft ist es eine Art qualitatives Ding. Sie können versuchen, vorherzusagen, ob Ihr Algorithmus
spüren kann oder nicht, ob jemand
tatsächlich einen Film gemocht hätte , den er zuvor ausgestrahlt hat. Aber am Ende des Tages geht es
Empfehlungen darum, Dinge zu empfehlen, die eine Person vorher noch nicht gesehen hat. Und das ist schwer zu messen, ob das ein gutes Ergebnis ist oder nicht. Also, um der Demonstration willen, werden
wir diese Bewertung nur qualitativ halten. Ich werde sehen, ob die Empfehlungen, die ich daraus herauskomme, Sinn
für jemanden macht, der Star Wars liebt und vom Wind verweht hasst. Gehen wir also durch den Code selbst und sehen, wie er aussieht. Ziemlich einfach zu bedienen. Also importieren wir ML dot Empfehlung, alles darunter und das übliche Zeug. Wir haben unser Objekt eingerichtet und wir haben hier zwei Fallklassen. Eine für die Suche nach Filmnamen, die wir gerade verwenden werden, um
Film-Namen für Film-IDs zu suchen , um am Ende menschenlesbare Ergebnisse zu erhalten. Und wir haben auch unseren kleinen Datensatz für Bewertungen, die eine Benutzer-ID enthält, sind Film-IDs und Bewertungen,
beachten Sie, dass wir die Zeitstempel emittieren, weil es für diesen Algorithmus keine Rolle spielt. Lassen Sie uns hier zur Hauptfunktion gehen. Beginnen Sie mit der Einstellung unseres Log-Levels. Also denke ich mit Spark-Sitzung, wie wir es immer tun, und wir beginnen mit dem Laden dieses Film-Namen-Dataset. Wir bieten ein Schema, das besagt, dass es ganzzahlige Film-IDs und String-Filmtitel hat. Und während wir dabei sind, sagten wir das Filmschema auch für die tatsächlichen Bewertungsdaten, die wir auch einlesen werden, wir importieren Funkenpunkt-Implikate, weil wir DataFrame zunächst
laden werden und nicht einen Datensatz. Wir lesen in den EU-Pot-Item-Ordner, der diese Filmnamen
enthält, unter Verwendung des Filmnamen-Schemas. Und wir wandeln das in das Film-Namen-Dataset unter Verwendung der Filmnamen Groß-/Kleinschreibung. Das überschwemmen, weil wir das
schon eine Million Mal früher im Kurs gemacht haben , richtig? Wir haben das dann tatsächlich wieder in Scala in einem Namenslistenobjekt gesammelt. An diesem Punkt haben wir Spark tatsächlich nur verwendet, um diese Daten zu laden und zu analysieren. Kopieren Sie das tatsächlich wieder in unser Treiberskript selbst. Jetzt können wir damit durchkommen, weil es einfach nicht so viele Filme auf der Welt gibt, oder? Wir können das sicher in den Speicher in unsere Treiberskripte einfügen. Das ist also keine verrückte Sache, für die wir eigentlich tun müssen, also werden wir das einfach
in eine Scala-Karte zurückwerfen , um nach denen zu suchen, wenn wir diese am Ende anzeigen. Die Film-Bewertungsdaten möchten jedoch
verteilt bleiben und diese als Datensatz auf unserem Cluster behalten. Und das ist, was wir hier tun, ist das Laden mit
dem Schema, das wir bereitgestellt haben, das Tab-Trennzeichen. Und wir werden das als Bewertungsdatensatz
mit der Bewertungsfallklasse, die wir oben definiert haben, umwandeln . Und wieder, dies wird nur die ersten drei Spalten extrahieren, die Benutzer-ID, Film-ID und eine Bewertung selbst. Wir lassen den Zeitstempel aus. Werfen Sie danach einen Blick darauf, wie einfach es ist, ML Lib zu verwenden. Also haben wir hier unser Modell aufgebaut. Also sagen wir einfach neue ALS für Alternating Mindest Squares als kommen aus der ML Lib Recommender Algorithmusbibliothek dort. Und wir sagten ein paar Hyperparameter. Also setzen wir unsere maximalen Iterationen auf fünf. Wir setzen unseren Regularisierungsparameter auf 0,01. Und Sie wollen vielleicht dorthin, woher wir diese Zahlen haben. Nun, ich pflücke sie einfach irgendwie aus der Luft basierend auf Beispielen, die ich online gesehen habe, Sie werden feststellen,
dass in der Praxis das dreckige kleine Geheimnis des maschinellen Lernens im Allgemeinen ist, dass es darum geht Hyperparameter-Optimierung. Und das ist eine sehr ausgefallene Art zu sagen, wir werden nur raten, was die richtige Nummer ist, bis wir es richtig haben. Es ist also eine sehr gängige Praxis, nur diese riesigen Jobs zu haben, die viele, viele,
viele verschiedene Werte
dieserHyperparameter wie Max Iterationen und Regularisierungsparameter ausprobieren viele verschiedene Werte
dieser und nur sehen, welche die besten Ergebnisse liefern experimentell. Es gibt oft keine wirkliche Anleitung, was der beste Wert sollte verzeihen Dataset werden und es variiert stark von Dataset, dem Dataset. Das Problem, hier die richtigen Parameter herauszufinden, ist also wirklich
der Kern dafür, gute Machine Learning Ergebnisse in der Praxis zu bekommen. Die andere Sache, dass der Kern nur Ihre Daten säubert, aber das ist kein maschineller Lernkurs, also werde ich nicht zu viel darauf hineinkommen. Wir sagen ihm, was die Spaltennamen für die Benutzer-ID, die Artikel-ID und die Bewertung sind. Das ist alles, was der Algorithmus braucht. Wir müssen also nur darauf hinweisen, was diese Datensatzspalten tatsächlich benannt sind, damit es weiß, woher diese Informationen abgerufen werden sollen. An diesem Punkt müssen wir nur sagen, dass der Punkt auf dieses Modell
passt, das diesen Bewertungsdatensatz übergibt. Und das ist es, dass dieses Modell tatsächlich auf unseren Daten ausgeführt wird und ein Modell
konstruiert, das
Empfehlungen für neue Nutzer von Filmen vorhersagen kann , die sie mögen. Und an diesem Punkt ist es irgendwie eine Blackbox, richtig? Der ALS-Algorithmus macht also etwas aus. Wir wissen, dass es alternierende kleinste Quadrate verwendet, um es geht. So erstellen Sie ein Modell, das
eine neue Benutzer-ID aufnehmen und Filme empfehlen kann , die dieser Benutzer basierend auf dem bewertet hat. Also lasst uns das machen. Lassen Sie uns voran und ziehen Sie aus dem Befehlszeilenargument heraus. Die Benutzer-ID ist eine Person, für die wir Empfehlungen erhalten möchten. In unserem Fall übergeben wir die Benutzer-ID über die Befehlszeile. Wir erstellen dann einfach einen wirklich einfachen DataFrame, der nichts als diese Benutzer-ID enthält. Und wir übergeben das in die Modelle empfehlen für Benutzer Teilmengenmethode
, die diesen gefälschten Benutzer DataFrame eines einzelnen Benutzers übergeben , von dem wir keine Ergebnisse waren. Und wir könnten tatsächlich mehrere Benutzer übergeben und Empfehlungen für viele Menschen auf
einmal erhalten , wenn Sie es wollten. Und wir sagen, wir wollen nur die Top 10 Empfehlungen für jeden Benutzer, die wir in diesem Benutzer DataFrame übergeben. An diesem Punkt haben wir unsere Ergebnisse, wir müssen sie nur anzeigen. Und seltsamerweise ist das eigentlich der schwierigste Teil von all dem,
herauszufinden, wie man diese Informationen extrahiert. Die Empfehlungen DataFrame, die wir zurück. Also das ist, was wir hier tun und diese kleine Schleife Hiergehen
wir durch jede Empfehlung in
den Empfehlungen DataFrame, gehen
wir durch jede Empfehlung in die wir von der empfohlenen Gefrierschrank Teilmenge zurückbekommen haben, extrahieren
wir die Benutzer-ID und die Empfehlungen selbst. Wir müssen Scala sagen, was dieses Ding ist. Also müssen wir dieses Ergebnis explizit als veränderbares umbrochenes Array vom Zeilentyp umwandeln, was wir zurück bekommen, wenn ein DataFrame. Wir können dann jedes einzelne Empfehlungsergebnis durchlaufen, den Film
extrahieren, die Bewertung extrahieren. Und dann können wir diese Film-ID in einen Filmnamen mit
unserer Funktion „get movie name“ übersetzen und die Ergebnisse ausdrucken. Schließlich beenden wir die Sitzung, wenn wir fertig sind, und wir sehen, was passiert. Schneller Blick auf die Funktion „get movie benannte“. Es führt nur eine Filterinformation auf dem Filmnamen-Array aus, das wir übergeben haben, und
versucht , die Film-ID zu finden, die mit der
gesuchten übereinstimmt , und gibt den damit verknüpften Filmtitel zurück. Auch hier wird kein Dataset verwendet. Dies ist eigentlich nur ein Array, das wir aus dem Datensatz durch
die kollektive Operation zurückerhalten haben . Also lassen Sie es uns laufen und sehen, was passiert. Klicken Sie mit der rechten Maustaste darauf Wir müssen aber einen Umfang dafür einrichten. Also werden wir sagen, Bearbeiten Sie Film-Empfehlungen und sitzen in einem Programm-Argument ist 0, weil ich Benutzer-ID Nullen Empfehlungen wollen. Jetzt kann ich OK drücken, und es sollte in der Lage sein, das jetzt auszuwählen und auszuführen. Alles klar, es ist aus dem Training dieses Modells jetzt basierend auf diesen 100.000 Bewertungen und es gibt unsere Top 10 Ergebnisse. Also ja, diese Ergebnisse sind irgendwie seltsam. Es sagt, dass für jemanden, der Star Wars liebt und nicht mit dem Wind verweht mag. Mein Top-Ergebnis mit einem Film von 1994, von dem
ich noch nie gehört habe, aber es heißt The Endless Summer 2. Ich denke, das ist kein Science-Fiction-Film. Ziemlich sicher, dass es sein oder nicht sein, von 1942 ist entweder nicht, noch ist ball2. Ich meine, hier drin gibt es einige Dinge, die irgendwie Sinn macht „Lost im Space“. Transformatoren Ich schätze, das macht Sinn für einen Star Wars-Fan, aber sie könnten, ich hatte einfach Glück. Diese scheinen mir zufällig Empfehlungen zu sein. Die Ergebnisse hier ergeben also für mich keinen Sinn. Nun, lasst uns untersuchen, warum das sein könnte. Wie bereits erwähnt, neigen
diese Algorithmen dazu, sehr empfindlich auf die Hyperparameter zu reagieren, die Sie wählen. Oft braucht es viel Arbeit, um den optimalen Satz von Parametern
für das Dataset zu finden , das Sie verwenden, um gute Empfehlungen daraus zu erhalten. Eine Technik besteht also darin, etwas namens Zugtest zu verwenden, bei dem wir einen Teil unserer Bewertungsdaten beiseite legen und diese für Testzwecke verwenden. Also halten wir einige Benutzer aus
unserem Datensatz heraus und wir verwenden das geschulte Modell für die verbleibenden Benutzer und sehen, ob unser resultierendes Modell erfolgreich
vorhersagen kann , welche Filme die Leute im Testset tatsächlich genossen haben, was sie mochten, was sie gut bewertet. Und Sie können das verwenden, um eine Art quantitative Maßnahme zu bekommen ,
wie gut die Empfehlungen sind. Und sobald Sie das haben, können Sie verschiedene Kombinationen von
Hyperparametern ausprobieren und sehen, welche Kombination die besten Ergebnisse
liefert und versuchen, die Dinge auf diese Weise zu optimieren. Aber das wird mit Empfehlungen zwielig. Ich meine, ist eine gute Empfehlung wirklich an
deiner Fähigkeit gemessen , Dinge vorherzusagen, die jemand schon gesehen hat? Oder ist es eine gute Empfehlung, wenn es etwas ist, das sie bei der Verwendung historischer Daten noch nicht gesehen haben, es gibt keine Möglichkeit, das zu wissen, richtig? Empfehlen Sie also, Empfehlungssysteme ist eine Art von diesem seltsamen Fall, in dem es schwierig ist,
die Ergebnisse wirklich abgesehen von Live-Experimente mit echten Menschen zu messen . Aber ich habe etwas Zeit damit verbracht. Also habe ich verschiedene Parameterwerte ausprobiert. Ich konnte keine besseren Ergebnisse aus diesem Ding bekommen, egal was ich getan habe. Also denke ich irgendwie, dass das Ding nicht so funktioniert, wie es sollte. Also bin ich nicht einmal davon überzeugt, dass dieses Ding intern richtig funktioniert. Zumindest für dieses Dataset funktioniert
dieser Algorithmus einfach nicht gut. Und die Lektion, die man hier lernen muss, ist, dass das Vertrauen in eine solche Blackbox ein zwielichtiger Vorschlag sein kann. Sie müssen verstehen, was im Algorithmus vor sich geht und verstehen, ob er zu den Daten passt, die Sie erhalten. Es kann sein, dass unser Datensatz einfach zu klein ist. Es kann sein, dass es etwas daran gibt, das diesen Algorithmus
nicht besonders gut geeignet ist. Ich habe einige offensichtliche Dinge wie die Normalisierung der Bewertungen auf 0 zu eins ausprobiert. Das hat auch nicht geholfen. Manchmal ist das, was Sie tun müssen, aber wir haben tatsächlich viel bessere Ergebnisse, nur mit unserem Beispiel für die Ähnlichkeit des Films früher im Kurs, richtig? Wenn wir nur die objektbasierte kollaborative Filterung mit Kosinusähnlichkeitsmetriken verwenden, wie wir es zuvor getan haben, hätten
wir viel bessere Empfehlungen mit einem viel einfacheren Ansatz erhalten. Und das hat geklappt. ALS ist also ein komplizierterer Algorithmus, aber manchmal kompliziert ist nicht immer besser. Dies ist ein gutes Beispiel dafür. Und so, wissen Sie, immer die Ergebnisse messen, stellen Sie
sicher, dass Sie die Ergebnisse erhalten, die Sie erwarten. Joe sagt, vertrauen Sie nicht nur blind den Ergebnissen wenn Sie versuchen, Datenanalysen für große Datasets durchzuführen. Weil kleine Probleme in den Algorithmen große werden
können, wenn Sie mehr Daten darauf werfen. Und sehr oft ist das eigentliche Problem die Qualität Ihrer Eingabedaten. In unserem Fall ist das nicht das Problem. Die Daten, die wir eintragen, wurden bereits gesäubert. Es sind also qualitativ hochwertige Daten. Aber oft gilt hier das Sprichwort
Müll rein, Müll raus, richtig? Also, wenn Sie ungefilterte Daten übergeben, die eine Reihe
von falschen Informationen von Robotern und solchen Dingen enthalten ,
oder Menschen, die keine echten Menschen sind oder Leute, die versuchen, das System zu spielen. Das wird auch Ihre Ergebnisse vermasseln. Aber das geht mehr in die Praxis des maschinellen Lernens ein als alles andere. Die Lektion hier ist jedoch, obwohl spark einige spannende Algorithmen enthält, werden
sie nicht immer die richtige Passform für Ihre Daten sein. Setzen Sie also nicht nur blind Ihr Vertrauen in das, was funken in ML Lib bietet. ML Lib ist jedoch immer noch sehr nützlich im Allgemeinen. Irgendwie begann dort mit einem schlechten Beispiel, weil ALS sowieso eine zwielichtige Sache mit ihm für das MoveLens Dataset ist. Aber der Rest der Algorithmen sind einfacher und sie werden tun, was Sie erwarten. Gehen wir also und schneiden Sie eine Verschiebung zu einer höheren Note mit Sparks ML Lib und zeigen Sie ihm etwas, für das es besser geeignet ist.
52. Lineare Regression mit MLLib: Lassen Sie uns also zu einem zuverlässigeren Algorithmus in der Spark ML-Bibliothek,
dem linearen Regressionsalgorithmus, wechseln , es ist ziemlich einfach. Was ist lineare Regression? Nun, wenn Sie neu in der Welt des maschinellen Lernens sind, könnte
das ein neuer Begriff für Sie sein. Kurz gesagt, die lineare Regression passt nur eine Linie an ein Dataset an. Und sobald Sie diese Linie haben, ist
das eine Art beste Anpassungslinie für eine Reihe von Beobachtungen. Sie können diese Zeile verwenden, um neue Werte für Dinge vorherzusagen, die Sie noch nie gesehen haben. Zum Beispiel haben wir auf dieser kleinen Illustration hier Messungen der Gewichte und ihrer Höhen aneinander gezeichnet. Sie können sich also vorstellen,
jemanden auf der Grundlage ihres Gewichts vorherzusagen , wenn Sie tatsächlich diese Linie haben, die rote Linie, die an diese Beobachtungsdaten angepasst ist. Grundsätzlich nehmen Sie alle beobachteten Datenpunkte der Sache, die Sie vorhersagen wollen. In diesem Fall, Höhe basierend auf einem Attribut, das in diesem Fall wäre Gewicht. Und wenn Sie all diese zusammen plotten und
die Linie finden , die zu diesen Daten am besten passt. Sie können dann die Gleichung dieser Linie verwenden, um die Höhen neuer Menschen nur basierend auf ihrem Gewicht
vorherzusagen. Das endet also mit einer Art Punkt-Neigungsformel hier für die Linie, richtig? Also im Grunde sagen wir, dass wir eine Steigung von 0,60 plus einen Y-Abfang von 1,23 haben. Und wir können diese Attribute verwenden, um Vorhersagen für die Zukunft zu machen. Warum nannten sie es Regression? Es ist irgendwie verwirrend, um ehrlich zu sein. Regression impliziert, dass Sie in der Zeit rückwärts gehen, aber das ist nicht wirklich, worum es geht. Es gibt eine Geschichte hinter diesem Begriff, aber versuchen Sie nicht, sich daran zu hängen. Grundsätzlich passt die lineare Regression nur eine Linie an historische Daten an. Vielleicht können Sie sich das als Regressionsteil vorstellen und diese Linie verwenden, um
neue Datenpunkte für neue Dinge vorherzusagen , die Sie noch nicht gesehen haben. Wie funktioniert es? Nun, normalerweise verwendet es etwas, das als kleinste Quadrate bezeichnet wird. Es ist eine mathematische Technik für eine Minimierung der quadrierten Fehler zwischen jedem Punkt und der Linie. Wenn wir also eine Linie zu diesen beobachteten Datenpunkten passen,
gibt es für jeden Punkt einen Fehler zwischen dem, wo dieser Punkt wirklich ist und wo die Linie sagt, dass er sein sollte. Und unser Ziel bei der Erstellung dieser Linie ist es den quadratischen Fehler zwischen jedem Punkt und dieser Linie
zu minimieren. Es ist quadriert, weil auf diese Weise positive oder negative Fehler keinen Unterschied macht. Es ist alles dasselbe. Also ist es mathematisch interessant, wenn man
darüber nachdenkt , wie das in zwei Dimensionen funktioniert. Wenn Sie sich also an die Neigungsabfang-Gleichung einer Linie erinnern, die y gleich mx plus b ist, wobei m die Neigung und b der y-Schnittpunkt ist. Weg zurück zur High School gibt es für viele von Ihnen, stellt sich heraus, dass die Steigung als Korrelation zwischen denbeiden Variablen mal
derStandardabweichung in y geteilt durch die Standardabweichung in x ausgedrückt werden kann beiden Variablen mal
der . Und das ist ein Haufen statistischer Mumbo-Jumbo für viele von euch. Aber ich denke nur, es ist irgendwie interessant, wie einige dieser statistischen Konzepte wie Standardabweichung eine echte mathematische Bedeutung
haben, die für
etwas so einfaches wie eine Anpassung einer Zeile an Daten verwendet werden kann . Es ist also nicht so, dass die Standardabweichung ein willkürlicher Cutoff ist, den jemand ausgedacht hat. Es hat tatsächlich eine echte mathematische Bedeutung, die für mich zumindest interessant ist. Und Sie können den Abfang auch als
nur den Mittelwert von y minus der Steigung mal des Mittelwerts von x berechnen . Das ist
also eine andere Möglichkeit, das zu berechnen. Angesichts dieser mathematischen Erkenntnisse ist
es also ziemlich einfach, eine Zeile tatsächlich in zwei Dimensionen an eine Reihe von Daten anzupassen. Wenn Sie es nur mit x und y zu tun haben, werden die
Dinge etwas komplizierter, wenn Sie mehr Dimensionen in den Mix hinzufügen. Es ist also eine Art von einem erstellten Beispiel, nur ein Attribut basierend auf einem
anderen Attribut wie der Höhe basierend auf dem Gewicht vorherzusagen . der Praxis beschäftigen Sie sich normalerweise mit mehreren Attributen. Also könnten Sie versuchen, jemandes Größe vorherzusagen, basierend auf ihrem Gewicht, wo sie leben, wie alt sie sind, was auch immer es ist, richtig? Also das in der Regel mehr als eine Sache. Und das kommt in wie all diese multidimensionale Seltsamkeit. Und eine Möglichkeit, damit umzugehen, ist der stochastische Gradientenabstieg. Es ist ein weiterer Algorithmus, den Sie in
der Welt des maschinellen Lernens und auch im Deep Learning viel sehen. Und im Grunde möchte ich nicht in die Details darüber eingehen, wie es funktioniert, aber es sucht irgendwie nach diesen Konturen in höheren Dimensionen, wenn Sie so wollen. Es findet also iterativ die Art der besten Anpassungslinien in diesem mehrdimensionalen Raum für Sie. Also dasselbe Konzept, nur ein bisschen komplizierter. Aber mit Spark dot HTML, Es ist überhaupt nicht kompliziert. Sie müssen sich keine Sorgen darüber machen, wie es funktioniert, denn alles tut es für Sie. Alles, was Sie tun müssen, ist Val zu sagen und einen Wert auf ein neues lineares Regressionsmodell zu
setzen, eine Reihe von Hyperparametern wie den Regularisationsparameter oder den elastischen Netzparameter, die maximale Anzahl von Iterationen, die Konvergenztoleranz zu setzen . Und wie immer ist maschinelles Lernen schmutziges kleines Geheimnis, dass es nicht
immer eine gute Möglichkeit gibt , zu erraten, wie dieser Wert für einen bestimmten Datensatz sein sollte. Oft kommen Sie durch Versuch und Irrtum zu den richtigen Werten. Sobald Sie jedoch ein lineares Regressionsmodell eingerichtet und konfiguriert haben, trainieren
Sie einfach das Modell und machen Vorhersagen mit Tupeln, die
aus einer Beschriftung und einem Vektor der Features bestehen , die zur Vorhersage dieser Beschriftung verwendet werden. In diesem Fall wäre das Label der Wert, den Sie vorhersagen möchten. Normalerweise rahmen wir unsere Y-Achse ein. Ein Feature befindet sich auf der X-Achse oder den anderen Achsen. Das sind die Dinge, die Sie verwenden, um zu versuchen, diese Vorhersage zu machen. Also im Grunde trainierst du das Modell mit einer Reihe von bekannten Punkten. Und dann versuchen Sie, neue y-Beschriftungswerte für
gegebene Xs oder Feature-Werte mit dieser Linie für das erstellte Modell vorherzusagen . Und Sie müssen sich keine Gedanken darüber machen, was diese Linie ist. Sie können es bekommen, wenn Sie wollen, aber wissen Sie, es ist wie jedes andere Modell, Sie erstellen einfach das Modell und sobald es trainiert ist, verwenden
Sie das, um Vorhersagen zu machen. Es ist alles sehr unkompliziert. Und es kann, wie gesagt, mit mehr als zwei Dimensionen
arbeiten, wenn Sie
mehrere Funktionen haben und das ist, wo die Macht davon wirklich ins Spiel kommt. Jetzt gibt es einige Fehler, die SGD-lineare Regression verwenden, was dies verwendet. Eine davon ist, dass die Feature-Skalierung nicht gut behindert Daher wird davon ausgegangen, dass Ihre Daten einer Normalverteilung ähnlich sind und wie sie angelegt sind. Wenn dies nicht der Fall ist, sollten Sie diese Daten normalerweise so skalieren, dass sie
in einen Bereich passen , der mit Ihrer Standardglockenkurve hier vergleichbar ist. Und Sie möchten sicherstellen, dass alle Ihre Features ähnlich skaliert sind. Wenn Sie also eine Funktion haben, die riesig ist und eine andere Funktion ist, ist das ein kleiner Wert. Sie müssen alles auf diese ähnliche Skala im
ähnlichen Bereich skalieren , damit der Algorithmus gut funktioniert. Das bedeutet, dass Sie
Ihre Daten nach unten skalieren und dann wieder sichern müssen , wenn Sie fertig sind. So trainieren Sie Ihr Modell basierend auf diesen skalierten Feature-Daten. Und dann müssen Sie daran denken, es mit den Inversen
dieser Beziehung wieder nach oben zu skalieren , wenn Sie tatsächlich
die endgültigen Werte anzeigen , die von diesem Modell vorhergesagt werden. Außerdem geht der Algorithmus davon aus, dass Ihr Y-Abfang
0 ist , es sei denn, Sie rufen fit intercept true auf. Wenn Sie es mit einer Situation zu tun haben, in der Sie nicht denken, dass Ihre beste Anpassungslinie den Ursprung 0,
0 durchläuft , müssen Sie fit intercept true nennen, um gute Ergebnisse zu erzielen. Also lasst es uns ausprobieren. Was wir tun werden, ist ein paar gefälschte Daten für durchschnittliche
Seitengeschwindigkeiten und Einnahmen, die aus Sitzungsdaten in einem Online-Shop generiert werden. Das war etwas, was wir wirklich bei Amazon tun mussten. Es gab eine Hypothese vor vielen, vielen, vielen, vielen, vielen, vielen, vielen Jahren, diese Seitenladezeit hatte eine sehr direkte Beziehung darauf, wie viel Geld der Kunde ausgegeben. Und wir wissen jetzt, dass das wahr ist, und das ist eine Art gemeinsame Weisheit in der ganzen Branche. Aber damals mussten wir das rausfinden. Also werden wir das in letzter Zeit herausfinden, gefälschte Daten. Wir werden also wissen, dass es da eine Beziehung gibt, weil wir sie hergestellt haben. Aber angesichts der Tatsache, dass wir versuchen werden, ein lineares Regressionsmodell mit
Spark ML zu erstellen und zu sehen, ob wir Umsatz basierend auf Page Speed mit diesem linearen Modell vorhersagen können. Also lasst uns eintauchen und es ausprobieren.
53. [Aktivität] Führen einer linearen Regression mit Spark: Lassen Sie uns also durch unser Beispiel für die Verwendung von
linearer Regression in Spark gehen und sehen, ob es funktioniert, öffnen Sie das lineare Regressionsdataframe-Dataset-Skript. Und bevor wir in den Code eintauchen, schauen wir uns zuerst die Daten an, mit denen wir es zu tun Das ist immer ein guter erster Schritt, oder? Also, wenn wir in unsere Kursmaterialien gehen und gehen Sie in den Datenordner, Regression Punkt txt Datei hier. wir uns einfach mit dem vertraut, was drin ist. Nun, wie Sie sich erinnern, versuchen wir vorherzusagen, wie viel Menschen auf Basis von PageSpeed ausgeben. Also das, was wir vorhersagen wollen, wird angekündigt ausgegeben und der Betrag, den wir sind, unser Feature, das wir vorhersagen wollen, dass auf PageSpeed ist. In dieser ersten Spalte diese Zahlen den ausgegebenen Betrag dar, aber es ist normalisiert und nach unten skaliert. Dies ist also normalisiert, um in eine Glockenkurvenverteilung zu passen. Deshalb sehen Sie hier Dinge wie negative Werte. Auch wenn Sie keinen negativen Betrag sehen würden ausgegeben wurde, wenn jemand eine Rückerstattung hat oder so was, richtig? Wie wir in den Folien gesagt haben, müssen
Sie sicherstellen, dass Sie Ihre Daten in diesen konsistenten Bereich skalieren. Und dann denken Sie daran, das wieder nach oben zu skalieren, wenn Sie fertig sind. Diese zweite Spalte entspricht unseren Feature-Daten. In diesem Fall wird das die Seitengeschwindigkeiten sein. Wieder haben wir dies normalisiert und skaliert es auf das, was in eine Glockenkurvenverteilung passen würde. Diese Zahlen selbst sind also keine Rohwerte. Sie waren nach unten skaliert worden und das ist eine Art Feature-Engineering , das wir es in der Welt des maschinellen Lernens nennen, ist ein sehr wichtiger Schritt und gute Ergebnisse zu erzielen. Viele Machine Learning-Modelle erfordern, dass Ihre Funktionen und Ihre Labels alle in ähnliche Bereiche skaliert werden, und manchmal sogar genauer, um 0 oder zwischen 01
zentriert werden. Es muss irgendwie die Dokumentation für den Algorithmus lesen, den Sie verwenden, um sicherzustellen, dass Ihre Daten im richtigen Format vorliegen. Sonst wird es nicht funktionieren. Sie werden wirklich seltsame Ergebnisse bekommen und es wird sich fragen, warum. Also vergiss das nicht. In Ordnung, also lasst uns in den Code eintauchen. Unser Regressionsschema wird also unseren zwei Spalten doppelter Genauigkeit entsprechen. Dort haben wir das Etikett, das wiederum unserem ausgegebenen Betrag entspricht und unsere Funktionen unterstreichen RA, was unseren Seitengeschwindigkeiten entspricht. Und wieder werden diese auf eine Normalverteilung skaliert. In Ordnung, wir lösen unsere Logger-Einstellungen aus, wir haben unsere SparkSession gesprochen, nichts Neues da. Und wir definieren ein Regressionsschema, das mit der Fallklasse übereinstimmt, über die wir gerade gesprochen haben. So können wir das von der Festplatte mit einer DataFrame-Schnittstelle importieren. Also sagen wir einfach Funkenpunkt lesen mit einem Komma-Trennzeichen, das dieses Schema verwendet. Und wir haben aus der
Datenschrägschrägungs-Regressions-Punkt-TXT-Datei geladen , die wir gerade angesehen haben, und es dann mit der Regressionsschema-Fallklasse
gegossen. Jetzt werden die Dinge interessant. Das Format, das von diesem Algorithmus in der ML-Bibliothek erwartet wird, ist also sehr spezifisch und oft müssen Sie sich auf
den Beispielcode beziehen , der mit Spark geliefert wird, um genau herauszufinden, was er will. So habe ich diesen Code bekommen, um ehrlich zu sein. Was es erwartet, ist, dass Sie ein VectorAssembler-Objekt erstellen, das auch Teil der maschinellen Lernbibliotheken ist. Und Sie möchten in seinen Eingabespalten als Array Ihrer Featurespalten festlegen. Jetzt haben wir in unserem Fall nur eine Feature-Spalte, sie heißt Features unter der Punktzahl roh. Also übergeben wir einfach ein Array mit diesem einen Spaltennamen Features Unterstrich roh. Wenn Sie mehr als ein Feature hätten, würden
Sie bei einem mehrdimensionalen Problem auch die zusätzlichen Features hier übergeben. Und dann wird dieser Vektor-Assembler in eine neue Spalte ausgegeben, etwas namens Features. Und das ist es, was wir in unser Modell übergehen werden. Sobald wir also diesen Assembler haben, das ist dieses Vektor-Assembler-Objekt, werden
wir Transformation darauf aufrufen, der in diesem Datensatz unserer Rohdaten füttert. Und es wird das in diese Feature-Ausgabespalte verwandeln. Daraus wählen wir die Labelspalte und die Feature-Spalte aus, die erzeugt werden. Jetzt haben wir einen DataFrame namens df, der nur Labels und Funktionen enthält. Und Etiketten entsprechen wieder unserer Menge ausgegeben und Spalten auf der PageSpeed. Also nochmal, ich werde auf eine einheitliche Skala hinabskalieren. In Ordnung, jetzt, da wir das haben, werden wir
tun, um die Leistung
dieses Algorithmus zu messen , diese Daten in zwei Sätze aufzuteilen. Wir werden die Hälfte dieser Daten für die Schulung unseres Modells beiseite legen. Und wir werden die andere Hälfte beiseite legen, um das Modell zu testen. Die Idee hier ist also, dass wir
dieses Modell mit nur der Hälfte der Daten trainieren werden , die wir haben. Und dann werden
wir mit diesem geschulten Modell sehen, wie gut es die bekannten korrekten Werte auf der anderen Hälfte der Daten vorhersagen kann. Und wir werden diesen Fehler messen, um ein Gefühl zu bekommen, wie gut unser Modell wirklich ist, das uns darüber informieren kann, ob wir
zum Beispiel verschiedene Hyperparameter ausprobieren oder nicht, oder unsere Daten besser reinigen müssen , richtig? Also extrahieren wir die erste Teilung davon aus zufälligen Splits und nennen das Training DataFrame. Und der zweite Testblock dort wird der Test DataFrame sein. So teilt zufällige Split nur einen DataFrame mit einem Array von Prozentsätzen auf, die Sie ihm geben. In diesem Fall 5050. Wir nehmen das erste resultierende DataFrame und nennen es Training Tf und den zweiten resultierenden DataFrame und nennen es Test df. Und das basiert nur darauf, jede Zeile
von d f in einem oder zwei dieser Datenrahmen zuordnen . Also, jetzt haben wir alles. Wir müssen tatsächlich unser lineares Regressionsmodell erstellen. Und wir werden weitermachen und es schaffen. Und die lineare Regression nennen wir sie LIR. Und wir haben alle Hyper-Parameter gesagt. Wieder denke ich, ich habe diese gerade aus
der Dokumentation für Orte gepflückt , an denen Sie vielleicht mit den Proben beginnen möchten. Auch in der realen Welt möchten Sie diese iterieren und finden, welche Kombination von Parametern die besten Ergebnisse liefert. Sobald wir unser Objekt haben, nennen wir fit auf es vorbei in unserem Training DataFrame den Weg, den wir für das Training des Modells beiseite gelegt. Und dann nehmen wir das geschulte Modell und machen Vorhersagen darauf. Also nehmen wir unser Modell und wir nennen es transformieren, indem wir unseren Test DataFrame übergeben. Und das wird eine neue vollständige Vorhersagen DataFrame erstellen, die
prognostizierte Menge enthalten ausgegeben basierend auf der PageSpeed im TestdataFrame-Set gesehen. Nun, was hier interessant ist, ist, dass wir dann unsere vorhergesagte Menge ausgegeben mit
dem tatsächlichen Betrag vergleichen können , der in
unseren TestdatenFrame-Werten in den Labels lebt , die wir dort haben. Beachten Sie, dass ich es hier fange. Nicht unbedingt notwendig für dieses einfache Beispiel, aber wenn Sie Dinge tun würden, die dieses vollständige Vorhersage-Dataset wiederholt verwenden, würden
Sie das zwischenspeichern wollen, um das zu beschleunigen, oder? Sobald Sie also ein geschultes Modell und eine Reihe von
Vorhersagen haben , die darauf basieren, werden
Sie wahrscheinlich diese Ergebnisse zwischenspeichern wollen, damit Sie sie wiederholt verwenden können, oder? In diesem Fall werden wir nur die Vorhersagen und
Etiketten herausreißen , nachdem Sie auf diese zurück aus den vollständigen Vorhersagen DataFrame geklickt haben. Und wir werden diese Vorhersage und Bezeichnung nennen. Und dann verbinden wir das einfach mit dem Skript und drucken sie alle aus. So können wir einfach einen Blick darauf werfen, was die tatsächlichen prognostizierten und tatsächlichen Werte, wo für jeden Punkt, können
Sie wahrscheinlich erraten, was eine gute Übung für den Leser hier wäre, das wäre, tatsächlich die Arbeit von diese prognostizierten Werte mit den tatsächlichen Werten zu vergleichen und diesen Fehler aus dem TestdataFrame tatsächlich zu messen. Aber im Moment werden wir uns nur die Ergebnisse ansehen weil dies nicht wirklich ein korrespondierendes maschinelles Lernen ist. Es geht natürlich um die Verwendung von Spark. Lassen Sie uns also mit der rechten Maustaste auf den linearen Regressionsdataframe-Dataset klicken und
es erneut ausführen . Und es hat funktioniert. Auch hier haben wir keine oder zumindest haben wir nicht
die Arbeit getan , um zu wissen, ob dies vernünftige Vorhersagen sind oder nicht. Aber das sind Vorhersagen. So können Sie die Ausgabe hier sehen. Auch hier werden diese auf
den Skalierungsfaktor skaliert , den wir bei der Vorverarbeitung der Daten verwendet haben. Um das gut nutzen zu können, müssten
wir es wieder skalieren. Aber es sieht so aus, als hätte es funktioniert. Diese sehen aus wie reale Werte und innerhalb eines vernünftigen Wertebereichs. Also da hast du es. Lineare Regression in einem Dataset mit Apache Spark. Auch hier besteht die Stärke darin, dass Sie ein wirklich massives Dataset aufnehmen und eine lineare Regression
durchführen können und
ein Modell mit der vollen Leistung des gesamten Clusters erstellen können. Also ist der Himmel die Grenze hier, so ziemlich buchstäblich. In Ordnung, also das ist maschinelles Lernen in Spark. Kurz gesagt, Sie werden feststellen, dass die meisten Modelle in ähnlicher Weise funktionieren. Sie erstellen nur ein Modellobjekt mit einer Reihe von Hyperparametern. Sie passen dieses Modell an einige Trainingsdaten an. Und dann können Sie dieses Modell mit Daten transformieren, für die Sie Vorhersagen machen möchten. Und es ist ziemlich einfach zu bedienen. Das war's also. Lasst uns weitermachen.
54. [Übung vorsehen: Also für Ihre nächste Herausforderung, werden
wir Spark mit einigen realen Daten hier verwenden, werden wir
versuchen , eine Immobilienwerte mit Entscheidungsbäumen vorherzusagen,
was eine weitere Machine Learning Technik ähnlich der Regression ist. Es kann auch für Regressionszwecke verwendet werden. Und Apache Spark in der Lage zu sein, es zu skalieren, wenn wir mussten. Daher erhalten wir unseren Datensatz auf eine Reihe von Daten, die den Preis pro Flächeneinheit haben. Sie nennen es Pings, woher das kommt, basierend auf einer Reihe von Attributen von Häusern. Und das kommt aus Taiwan, aus New Taipeh City. Es sind echte Daten und hier ist der notwendige Kredit für die, die mit diesem Datensatz gekommen sind. Und wenn Sie mehr über das Dataset selbst erfahren möchten und mehr über sein Format erfahren möchten. Folgen Sie dem zweiten Link, der aus dem UCI-Daten-Repository kommt. Das ist ein sehr nützliches Repository von maschinellen Lern-Datasets,
sodass Sie zum Experimentieren und Herumspielen und Lernen mit verwenden können. Das ist also eine gute Ressource, Kerzen und andere auch, wenn Sie nach
mehr Quellen von Datasets mit realen Daten suchen . So sehen die Daten aus. Ich habe es tatsächlich ein wenig für Sie gesäubert, nur um ihm
vernünftigere Spaltennamen zu geben und es in
CSV-Format zu konvertieren , um Ihr Leben für diese Übung ein wenig einfacher zu machen, es besteht aus mehreren Spalten mit Daten im CSV-Format. Die erste Spalte wird nur Nummer genannt ist die Nummer, die mit diesem Haus verbunden ist. Und dann haben wir für jedes Haus das Transaktionsdatum, als es verkauft wurde, das Alter des Hauses, die Entfernung zu MRT, das ist eigentlich die Entfernung zum öffentlichen Nahverkehr. Die Anzahl der nahe gelegenen Convenience-Stores, die ich denke, ist eine große Sache in Taiwan es scheint, und der Breiten- und Längengrad des Hauses selbst. Und schließlich die Sache, die wir vorhersagen wollen, der Preis der Flächeneinheit. Und natürlich ist das eine lokale Währung. Also lesen Sie nicht zu viel in das, was das eigentlich bedeutet. Ihre Herausforderung besteht darin, den Preis pro Flächeneinheit basierend auf dem Hausalter, der
Entfernung zu den öffentlichen Verkehrsmitteln
und derAnzahl der nahegelegenen Lebensmittelgeschäfte vorherzusagen Entfernung zu den öffentlichen Verkehrsmitteln
und der . Nur um dies ein wenig einfacher zu machen, werde
ich einige der Daten wegwerfen, die schwieriger zu analysieren wären wie den tatsächlichen Standort und solche Dinge. Offensichtlich ist die tatsächliche Nummer der Transaktion, das ist nicht wirklich wichtig, noch das Datum für unsere Zwecke. Also werden wir es einfach halten und uns hier nur mit numerischen Daten befassen. Ihre Strategie wird sein, einen
Entscheidungsbaum-Regressor anstelle eines linearen Regressionsobjekts von Spark dot SML zu verwenden , sie funktionierten sehr ähnlich. Wenn Sie möchten, können Sie sich die Dokumentation in der Spark-Dokumentation online ansehen, aber es ist ziemlich dieselbe Syntax, nur ein anderer Name. Während die lineare Regression durch die Berechnung dieser Steigungen und Abfänge für Linien funktioniert, arbeitet
ein Entscheidungsbaum mit einer anderen Strategie. Grundsätzlich konstruiert es diesen Baum von Entscheidungen, den er trifft, wo an jedem Punkt im Baum steht, ist dieses Attribut kleiner oder größer als ein Wert? Und es arbeitet seinen Weg nach unten, diese Entscheidungen basierend auf diesen binären Entscheidungen zu treffen, um zu versuchen, zu einer endgültigen Vorhersage zu gelangen, was Ihr endgültiges vorhergesagtes Label sein wird. Also nur eine andere Art, am Ende des Tages die gleiche Art von Ergebnis zu erhalten, der Grund, dass wir mit Entscheidungsbäumen gehen, ist zweifach. Erstens, nur um Sie einem weiteren ML-Algorithmus auszusetzen, der in Spark verfügbar ist. Und auch, weil Entscheidungsbäume weniger empfindlich
gegenüber Daten sind , die in unterschiedlichen Maßstäben sind. Wir müssen uns nicht wirklich darum kümmern, alle unsere Daten nach unten zu skalieren, um normalisiert zu werden und im gleichen Bereich, um die besten Ergebnisse mit einem Entscheidungsbaum zu erzielen, es kann viel besser umgehen. Beginnen Sie also mit einer Kopie des linearen Regressionsdataframe-Datasets Scala-Klasse , die wir uns zuvor angesehen haben. Und das wird ein sehr nützlicher Ausgangspunkt sein, indem Sie das nur ein wenig ändern, sollten
Sie in der Lage sein, dies abzuziehen. Und beachten Sie auch, dass wir eine Header-Zeile in dieser CSV-Datei haben, so gibt es keine Notwendigkeit für Sie, harten Code ist Schema zum Lesen, dass in, wir können nur den Funkenleser, das automatisch zu tun, wenn wir sagen, dass Header existiert, einige nützliche Snippets, die wir durch diese bekommen. Zunächst einmal hatten
wir in unserem vorherigen Beispiel nur eine Sin Single-Feature-Spalte und Sie müssen nicht nur eine haben. Sie können tatsächlich mehrere Eingabespalten in einem Vektor-Assembler haben. Also denken Sie daran, Sie können auch sagen, Set Input Calls Array, und dann eine Liste von Spalten, nicht nur eine einzelne Spalte, wenn Sie mehrere Funktionen haben, wie wir hier tun. Und denken Sie daran, wenn Sie die Datei einlesen, anstatt ein tatsächliches Schema anzugeben, können
Sie einfach header true sagen und das Schema true ableiten. Und wir werden alles lesen, solange diese Header-Spaltennamen mit dem übereinstimmen, was Sie in Ihrer Fallklasse haben, wird
alles gut funktionieren. Die einzige Sache am Entscheidungsbaum-Regressor, Sie werden nicht alle zusätzlichen Hyperparameter benötigen, die wir in
den linearen Regressionsentscheidungsbäumen angegeben haben, haben einen anderen Satz von Hyperparametern, aber es ist in Ordnung, einfach sie und gehen Sie mit den Standardwerten. - Das ist in Ordnung. So können Sie all diesen zusätzlichen Code im Beispiel für die lineare Regression entfernen. Und beachten Sie auch, dass es eine Set-Label-Col-Funktion gibt. Und damit können Sie eine Beschriftungsspalte angeben, die nicht mit dem Namen label versehen ist. In unserem Fall ist es nicht Label genannt. Es ist der Preis der Einheit Fläche oder so etwas genannt. Das sollte also alles sein, was du brauchst. Also geh los und gib es mal. Und in der nächsten Vorlesung werde
ich Sie durch meine Lösung führen und sehen, wie nah Sie sind.
55. Übung aufhalten: In Ordnung, lassen Sie uns meine Lösung durchlaufen, um den Wert eines Hauses für
Fläche vorherzusagen , basierend auf einigen eher ungewöhnlichen Attributen dieser Häuser in Taiwan. Wie immer beim maschinellen Lernen sollten
Sie damit beginnen, die Art der Daten zu studieren, die Ihnen zur Verfügung gestellt werden. Und für unsere Zwecke, da der Status bereits bereinigt wurde, wollen
wir dies hauptsächlich nur für einen praktischen Verweis auf diese Spaltennamen haben. Weil es sehr wichtig sein wird, diese genau zu vergleichen, da wir
unser kleines Skript hier schreiben , um es zu laden und in das Format zu konvertieren, das unser Algorithmus erwartet. Und wissen Sie, es ist immer eine gute Idee, die Daten
zu überprüfen, um sicherzustellen, dass nichts Unerwartetes darin ist. Wir gehen davon aus, dass dies alle Zahlen sind. Also ein schneller Scan, nur um sicherzustellen, dass diese Zahlen alle scheinen in
mehr oder weniger demselben Bereich zu sein und keine seltsamen wie
fehlende Werte oder Täler im falschen Format haben , wie zufällige String-Werte hier und da. Das erspart Ihnen Ärger. Dieser Datensatz wurde jedoch bereits für Sie gesäubert. Also ist der harte Teil des maschinellen Lernens bereits in diesem Fall erledigt, mit dieser Liste gehen Sie zum Code. Also habe ich gerade damit begonnen, die lineare
Regressionsdataframe-Dataset-Punkte Scala Datei zu kopieren und ich nenne es stattdessen eine Immobilien-Punkt-Gala. Die Hauptänderung hier. verwenden
wir einen anderen Algorithmus für die Regression. Wir importieren oder dot-apache-dot spark dot html dot regression dot Decision tree regressor dieses Mal, genau wie wir Ihnen einen Hinweis in den Folien gegeben haben, wenn Sie eine lineare Regression noch verwenden wollten, würde es tatsächlich noch funktionieren. Aber wieder, wir wollen Sie nur einem neuen aussetzen. Und Entscheidungsstrukturen sind weniger empfindlich gegenüber
unterschiedlichen Wertebereichen in den Features und den Beschriftungen. Also deklarieren wir hier ein neues Regressionsschema. Und wie Sie sehen können, ist es viel komplizierter. Alle unsere Funktionen haben unterschiedliche Namen und es gibt jetzt mehr als einen von ihnen. Also haben wir tatsächlich jede der Spalten in diesen Eingabedaten, die hereinkommen. Und das haben wir auf diese Weise abgebildet. Also haben wir den Spaltennamen NO
, der für Nummer steht. Wir gehen davon aus, dass dieses ganzzahlige Transaktionsdatum. Wir werden dieses Doppelhaus nennen,
Alter von Doppel, und et cetera, et cetera, et cetera. Diese Namen korrelieren nur mit diesen Spaltennamen im CSV-Header selbst. Alles klar, weitermachen. Da ist nichts anderes. Wenn wir tatsächlich in die Datei laden und wir werden
Option Header true und Option im ersten Schema true sagen , anstatt es ein hartcodiertes Schema
zu geben, das es ermöglicht , diese Header-Zeile in der CSV-Datei zu nutzen. Das macht das Leben dort ein bisschen einfacher. Wir müssen dieses Schema nicht zweimal codieren, was irgendwie nervig ist, wenn das passiert. Als nächstes konstruieren wir unseren VectorAssembler wie zuvor. Und der Unterschied hier ist, dass anstelle eines einzigen Features, oder ich denke, wir nennen es rohe Funktionen oder Funktionen Ron, Ich denke, ursprünglich haben wir tatsächlich drei verschiedene Funktionen und dieses Beispiel, Hausalter, Entfernung zu MRT und Nummer Convenience-Geschäfte. Auch hier passen wir das bis zu diesen Groß-/Kleinschreibung Klassennamen wie hier an. So war die Problemaussage, um den Preis der Einheit Fläche basierend auf Hausalter vorherzusagen, Entfernung zu MRT eine Reihe Convenience-Stores. Also werfen wir die zusätzlichen Spalten weg, du brauchst sie nicht. Wir setzen nur die Eingabespalten auf diejenigen, die uns wichtig , die wir tatsächlich als Features verwenden möchten, um eine Vorhersage zu machen. Und wir werden die Ausgabe-Spalte der Features aufrufen, wenn wir fertig sind, das ist in Ordnung. Und wir werden außerdem den Preis der
Flächenspalte auswählen , weil das unsere Etiketten sein wird. Also an diesem Punkt, was wir am Ende werden, ist eine Spalte namens Preis der Einheit Fläche. Das wird die Sache sein, die wir vorhersagen wollen, die Etiketten. Und eine Feature-Spalte, die nur eine Liste von Features enthält. Diese Spalte enthält also im Listenformat
das Hausalter, die Entfernung zu MRT und die Anzahl der Convenience-Stores. Und das ist genau das Format, das unser Modell erwartet. Also müssen wir uns dem anpassen. Nach wie vor teilen wir dies in ein Trainingsset und einen Testdatensatz auf. Und jetzt werden wir unser Modell konstruieren, das als Entscheidungsbaum-Regressor bezeichnet wird. Ich nehme an, ich hätte den Namen der Variablen in
etwas anderes als LIR ändern sollen, ich denke, es hätte sein sollen. Aber was auch immer, was du tun willst, ist in Ordnung. Wir haben explizit die Namen der Feature-Spalte und Beschriftung der Spaltennamen hier festgelegt. Features sind die Standardeinstellung, also musste ich das technisch nicht tun, aber der Standard für Label ist nicht der Preis der Einheitenfläche beschriftet. Also musste ich meinem Modell explizit sagen, dass
der Name meiner Labelspalte der Preis der Einheitenfläche ist, damit das funktioniert. Danach funktioniert alles auf die gleiche Weise. Also sagen wir einfach fit, vorbei in unserem Training DataFrame. Und wir machen eine Reihe von Vorhersagen, indem wir diese mit unseren Testdaten transformieren. Und nach wie vor gehen wir einfach durch und wählen es aus. Wir haben den Spaltennamen der Etiketten hier wieder geändert und diese wieder gesammelt und durchlaufen und alle ausgedruckt. Und was dies tun wird, wie ein Kommentar sagt,
ist, den prognostizierten Wert und den tatsächlichen Wert für jedes Haus in unserem Testdatensatz auszudrucken. Mal sehen, ob es funktioniert. Klicken Sie mit der rechten Maustaste auf Immobilien und laufen. Und wir haben Ausgang. Cool. Also nur durchblättern,
viele davon sehen ziemlich vernünftig aus. Wir haben vorausgesagt, dass 50 zu was auch immer ist, und es ist wirklich 55. Und zum größten Teil funktionierte das Modell ziemlich gut. Ich meine, es gibt offensichtlich Möglichkeiten zu quantifizieren, wie gut das Modell Metriken wie RMSC verwendet. Aber dies ist kein Data Science oder maschinelles Lernen Kurs. Also werde ich nicht darauf hineinkommen. Ich habe aber einige von ihnen wild falsch gemacht. Also für diesen, prognostizierte
es einen Wert von 36, aber der tatsächliche Wert war ein 117. So eindeutig gibt es mehr zu dem, was
den Wert eines Ortes festlegt , außer wie nah an einem Convenience Store Sie sind in. Dinge wie nahe Sie zum nächsten Bahnhof sind. Also nicht zu überraschend, dass es kein großartiges Modell ist, weil wir ihm nicht viele tolle Daten gegeben haben, aber es funktioniert überraschend gut tatsächlich in, durch Vergrößern, es kam ziemlich nahe an die meisten dieser so interessanten Ergebnisse. Also, da hast du es, hoffe, du hast es durchgemacht. Auch hier ist dies nur eine Möglichkeit, dies zu tun. Wenn Sie einen anderen Ansatz gewählt haben, ist das auch in Ordnung. Stellen Sie einfach sicher, dass Sie eine ähnliche Ausgabe haben und wir werden es gut nennen.
56. Die DStream für Spark: Und immer häufiger werdende Anwendungsfälle Spark beschäftigt sich mit Streaming-Daten. So haben
wir bis zu diesem Punkt im Kurs über die Batch-Analyse von Offline-Datensätzen gesprochen. Also haben wir diese Pilotdaten und wir wollen sie analysieren oder irgendwie verarbeiten. Aber in der realen Welt hören Daten nie auf, oder? Hier kommt Spark Streaming ins Spiel. Es ermöglicht Ihnen, Datenströme in Echtzeit zu erfassen. Beispielsweise können Sie eine Flotte von Servern haben, die Protokollinformationen generieren, in Ihren Spark-Cluster eingeleitet und analysiert
werden, sobald er eingeht. Vielleicht transformieren Sie diese Daten und speichern sie irgendwo anders in einer anderen Datenbank. Vielleicht aggregieren Sie es im Laufe der Zeit und
suchen nach Dingen, auf die Sie gewarnt werden möchten, wenn sie geschehen. So oder so, Streaming ist heutzutage ein sehr wichtiger Anwendungsfall in der Geschäftswelt. Lassen Sie uns also eintauchen und sehen, wie Spark Streaming verwendet werden kann, um Daten so zu analysieren, wie sie erstellt werden, und Maßnahmen zu ergreifen, wenn es notwendig ist. In diesem Abschnitt stellen wir Ihnen Spark Streaming vor. Dies ist ein sehr häufiger Anwendungsfall für Apache Spark in diesen Tagen, wo wir es mit Streaming-Datenquellen zu tun haben und nicht nur eine Reihe von Daten auf einmal in einem Batch-Prozess zu transformieren, sondern ständig eingehende Daten zu überwachen und etwas zu tun, um es in Echtzeit, wie es empfangen wird. Ein gängiges Beispiel dafür wäre die Verarbeitung protokollierter Daten, die von einer Website oder einem Server stammen, oder vielleicht einer ganzen Flotte von Servern, die eine Website betreiben. Dass Daten nie aufhören, oder? Es gibt also keinen wirklich einfachen Satz von Protokolldateien. So können Sie zeigen und sagen, Hey, gehen Sie analysieren diesen Teil von Protokolldaten. Es kommt immer wieder rein, es gibt immer neue Informationen, die ständig gesammelt werden. Und vielleicht möchten Sie das in einem
bestimmten Intervall oder Fenster von Informationen aggregieren und analysieren , oder? Vielleicht möchten Sie eine Art Alarm einrichten bei dem, wenn Sie eine Reihe von Fehlern auf Ihrer Website sehen, etwas automatisch benachrichtigt wird, oder? Statt nur auf eine nächtliche Analyse dieser Daten zu warten, analysieren
wir diese Daten kontinuierlich, wenn sie eingehen und machen etwas damit. Diese Daten müssen nicht aus einer Rohdatei stammen, die von einem Port
stammen kann , der TCP-Daten empfängt. Es kann vom Amazon Kinesis-Service stammen. Es kann von einem HDFS oder einem verteilten Dateisystem kommen, das von Kafka
kommen kann, von Flume kommen und alle Arten von anderen Datenquellen so dass Spark Streaming in eine Reihe von verschiedenen Systemen integriert werden kann, nicht nur Textdateien und dass Daten, wie sie hereinkommen. Und es geht vielleicht nicht nur darum, Daten zu analysieren und zu aggregieren. Es könnte darum gehen, es zu transformieren und es einfach woanders zu schicken. Vielleicht nimmt alles Spark Streaming in Ihrem Fall eingehende Protokolldaten, extrahiert die Informationen, die Sie interessieren, strukturiert diese Daten und speichert sie dann irgendwo in einer Datenbank. Das ist auch ein vollkommen gültiger Anwendungsfall für Spark-Streaming. Und das Schöne an Spark Streaming, stattdessen, es hat eine Checkpointing Funktionen. Wenn Ihr Stream also heruntergeht Ihr Cluster aus irgendeinem Grund heruntergeht, hat
es eine einfache Möglichkeit, automatisch an der Stelle abzuholen, an der er automatisch aufgehört hat. Also, das ist sicher ein nettes Feature. Lassen Sie uns also anfangen, über die alte DStream API für Spark Streaming zu sprechen. Grundsätzlich hat Spark Streaming eine geschichtliche Geschichte, wenn Sie so wollen, die ursprüngliche Schnittstelle, wo es dStreams genannt wurde, und es basierte auf der alten RDD-Schnittstelle. Und weil es auf RDDs basierte, konzentrierte
es sich um das, was wir Mikrobatches nennen. Es befasste sich also nur mit diesen Datenblöcken, die als RDDs dargestellt wurden. Und es hat diese kleinen Brocken ganz verarbeitet. Technisch gesehen war es kein richtiges Streaming. Es funktionierte nicht tatsächlich auf Daten auf einer Feld- oder Zeilenbasis. Es hat Dinge in das zerbrochen, was wir Mikro-Batches nennen. In der realen Welt ist das normalerweise kein Problem, wenn Sie
eine Latenz von wenigen Sekunden haben , im Gegensatz zur sofortigen Verarbeitung für die meisten Anwendungen, das spielt eigentlich keine Rolle. Aber das war eines der wichtigsten Dinge, die
dazu führen, dass sie sich im Laufe der Zeit von dieser Schnittstelle entfernen. Und nun, Deckungen aus historischen Gründen hier. Aber wir werden danach auf die modernere Structured Streaming API gehen. Wie auch immer, hier ist ein Beispiel dafür, wie de Streaming aussehen könnte. Sie würden also einen Streaming-Kontext im Gegensatz zu einem SparkContext einrichten. Und das ist Sekunden eins dort bedeutet, dass es Dinge 1 Sekunde nach dem anderen verarbeiten wird. Diese Mikro-Batches enthalten also 1 Sekunde neue Daten, die wir als Teil unseres Skripts verarbeiten werden. Wir können dann sagen, Stream Dot Sockel Textstrom. Und das wird es sagen, Port
8888 für Textdaten zu hören , die an diesem TCP-Port gesendet werden. Und dann wird alles, was es tun wird, ist
die eingehenden Zeilen nach Zeilen zu filtern , die das Wort Fehler enthalten. Und wenn es eine Zeile sieht, die das Wort Fehler enthält, wird es ausdrucken. Sobald Sie das eingerichtet haben, müssen Sie nur Stream Dot Start aufrufen, um es tatsächlich zu starten und eine Woche Kündigung gestreamt, um darauf zu warten, dass jemand es stoppt. Es ist also ein bisschen magisch, ein bisschen seltsam, deinen Kopf um dieses Paradigma zu wickeln, oder? Sie müssen also daran denken, dass wir nicht einen einzigen Datenblock verarbeiten. Dieses gerichtete azyklische Diagramm, das wir hier konstruieren, um
diese Daten in aufgenommenen Daten zu verarbeiten und sie herauszufiltern und auszudrucken, wenn es
diesen Filter übergibt , dies wiederholt für
jede 1 Sekunde angewendet wird Wert von Daten, die automatisch empfangen werden. Wir müssen nicht irgendwo eine Schleife schreiben, die besagt, dass Sie dies alle 1 Sekunde wiederholt tun. Spark Streaming macht das für Sie. Also, diese Syntax hier mag zunächst ein wenig seltsam und magisch erscheinen, weil sie irgendwie nur im Stream funktioniert. Man muss nicht zu viel darüber nachdenken, aber es funktioniert. So funktioniert es
auf hohem Niveau . Ein paar Mist. Denken Sie also daran, dass Ihre RDDs nur einen kleinen Teil eingehender Daten enthalten. Nun, was Sie tun können, sind Fensteroperationen. Mit einem fensterförmigen Vorgang können
Sie Ergebnisse aus
mehreren Stapeln über ein Schiebezeitfenster automatisch kombinieren . So gibt es Funktionen wie Fenster oder reduziert durch Fenster oder ReduceByKey und Fenster. Diese Fensterfunktionen ermöglichen es Ihnen, eine Reduktion über einige Zeit zu tun, die in der Vergangenheit zurückgeht. Also könnte ich sagen, gehen Sie für die letzte Minute zurück, gehen Sie zurück für die letzte Stunde, gehen Sie zurück für den letzten Tag, was auch immer es ist, und reduzieren Sie meine Informationen basierend auf diesem Fenster der Informationen. So muss dieses Fenster nicht Ihrer Stapelgröße entsprechen, die viel größer
sein kann, und es wird automatisch verfolgen diese RDD-Ergebnisse, diese Mikrobatches, und wenden Ihre Operation über das Zeitfenster an, das Sie definiert. So behält es automatisch diese Informationen herum, so dass Sie sie analysieren können, während Sie gehen. Außerdem ist etwas, worüber es sich lohnt, den Aktualisierungsstatus für Schlüssel zu sprechen. Auf diese Weise können Sie einen Status beibehalten, der sich im Laufe der Zeit über viele Chargen erstreckt. Wenn Sie also eine Art Laufstatus verfolgen müssen während Sie diese Informationen über Windows oder über Batches hinweg verarbeiten, können
Sie dies mit Aktualisierungsstatus für Schlüssel tun. Ein gutes Beispiel dafür wäre, eine Art Zähler und eine
laufende Zählung eines Ereignisses im Laufe der Zeit seit dem Start des Skripts auszuführen. Also, wenn Sie etwas im Auge behalten müssen, da das Skript
als Ganzes ausgeführt wird , im Gegensatz zu über ein Zeitfenster. Aktualisieren Sie den Zustand nach Schlüssel, können Sie das tun. Lassen Sie uns hier in ein einfaches Beispiel eintauchen. Wir werden es ein Spark-Streaming-Skript ausführen, das nur Live-Tweets von Twitter überwacht. Und wir werden die beliebtesten Hashtags verfolgen, wenn wir neue Tweets erhalten. Um dies zu tun, müssen wir zuerst ein Twitter-Entwicklerkonto einrichten. Nun, einige Leute haben Probleme,
dies hängt davon ab, welches Land oder wie Sie das Formular ausfüllen. Welche Art von Stimmung für Twitter ist in ganz ehrlich, Also bin ich nicht sicher, ob Sie wirklich durch diese selbst gehen wollen. Sie können, wenn Sie einfach auf Apps gehen wollen dot twitter.com und beantragen Sie dort ein Entwicklerkonto, wenn Sie wollen, entlang folgen. Ehrlich gesagt, ich denke, du solltest mir nur zusehen, wie ich diese nächste Aktivität mache, denn wie gesagt, DStreams sind irgendwie datiert. Nun, wenn Sie gerade diese Klasse zum Zweck einer Zertifizierung nehmen, kann
ich Ihnen versprechen, dass es nicht in der Zertifizierungsprüfung sein wird, also möchten Sie vielleicht nur zusehen, wie ich diese folgende Aktivität mache, anstatt mitzuverfolgen. Aber wenn Sie dies tun, können Sie einfach zu apps dot twitter.com Anmelden für Entwicklerkonto gehen. Und dann können Sie die API-Schlüssel und Zugriffstoken erstellen, die Sie benötigen, um Twitter abzufragen und das in Spark-Streaming zu pippen. Um diese Informationen und
ihre Anmeldeinformationen zu speichern , müssen Sie eine Twitter-Punkt-TXT-Datei erstellen. Und ich zeige Ihnen, wo das ist, wenn wir es durchlaufen, es wird nur einen Namen Ihres Verbraucherschlüssels haben und Zugriffstoken Informationen in jeder Zeile und unserem Treiberskript, wir lesen das in und verwenden es, um sich mit Twitter. Unsere Gesamtstrategie hier, sobald wir diesen Twitter-Stream eingerichtet haben, werden
wir nur die Nachrichten selbst extrahieren. Es gibt eine Reihe von Metadaten, die Twitter Ihnen auch gibt. Aber wir werden einen Twitter utils dot erstellen Stream erstellen, der
eine Bibliothek von Drittanbietern verwendet , die ich in den Kurs aufgenommen habe, um Twitter
tatsächlich zu verbinden und es wie ein DStream aussehen zu lassen. Und dann rufen wir Tweets Punktkarte auf, um
das Textfeld auf, dass durch Aufrufen des Statuspunkts GetText extrahieren . An dieser Stelle haben wir also eine neue RDD, einen Mikro-Batch, der nichts als die Statusmeldungen von jedem erhaltenen Tweet enthält . So zum Beispiel, vielleicht sagt ein Tweet „Vote for hashtag bulimic fett“. Und jemand könnte ein Buch sagen, denn ich mag große Stiefel und ich kann nicht lügen und keine Stimme für Hashtag. Welcher Eisberg? Und jemand anderes könnte sagen, was bist du verrückt? Hashtag, Bodhi MAC, mutig den ganzen Weg. Und wenn du dich fragst, wovon ich hier rede, war
das vor einigen Jahren gemein. Grundsätzlich ein, Ich vergesse, was Marine es war, aber sie führten einen Online-Wettbewerb, um das Internet ihr neues Schiff benennen zu lassen. Und das war natürlich eine schreckliche Idee. Der Gewinner war natürlich podium mic mudface, die sie nicht verwendet haben. Aber ich glaube, sie steckten es auf eine kleine Zusammenfassung oder etwas, das auf dem Schiff war oder so. Wie auch immer, dieses Beispiel versuchen wir, den Überblick über die beliebtesten Hashtags zu behalten, oder? Also in diesem Fall hätten wir Hashtag Boolean mit beiden Gesicht als Zahl angezeigt, das Ergebnis Nummer eins mit zwei Auftritten und Hashtag, welcher Eisberg wäre das zweite Ergebnis mit einem Aussehen. Also haben wir unseren Stream von Statusmeldungen eingerichtet. Als nächstes können wir Flatmap verwenden, um das in seine einzelnen Wörter aufzuteilen. Also, indem wir FlatMap auf diesem Status Micro Batch aufrufen, werden
wir das dann in
eine größere RDD ausblasen , die eine Zeile für jedes einzelne Wort hat, das erscheint. So
würde zum Beispiel die Nachrichtenabstimmung für ihre Hashtag-Buddy-Makrophase nur in drei separate Zeilen aufgeteilt werden. Stimmen Sie für den Hashtag unten von Buffets. Und da alles, was uns wichtig ist, die Hashtags sind, ist das das einzige, was wir messen. Wir können dann Filter aufrufen, um alle Zeilen herauszufiltern, die nicht mit dem Hashtag-Symbol beginnen. Das reduziert die Dinge auf nur die Hashtags, die angezeigt werden. Und an diesem Punkt können wir unseren alten Trick von weit zurück in Abschnitt eins oder Abschnitt zu was auch immer es war, wo wir diese in eine RDD von Schlüsselwertpaaren konvertieren können, wobei der Schlüssel der eigentliche Hashtag ist und der Wert die Nummer eins ist. Das wird uns erlauben, später eine
Reduction-Operation durchzuführen, um sie alle mit genau dem zu zählen, was hier vor sich geht. Und wir machen das über ein Schiebefenster, um die Dinge interessant zu machen. Die Reduce-Operation addiert also alle diese zusammen und gibt uns eine Gesamtzahl für wie oft dieser Hashtag erscheint. Aber wir benutzen hier einen Stream, also werden wir nicht sagen, „Reduzieren“ nach Schlüssel. Wir müssen sagen, über welchen Zeitraum. Und um das zu tun, sagen wir ReduceByKey und Fenster, um
die Operation über ein bestimmtes Fenster und Dia-Intervall zu reduzieren. Also werden wir sagen ReduceByKey und Fenster, im Grunde alles addieren. Und wenn Sie dies übergeben, müssen
Sie ihm explizit eine Funktion zum Hinzufügen und Entfernen von Elementen geben, während es geht. Das ist, was hier in dieser Syntax vor sich geht. Und wir werden sagen, dass wir das über ein 300-Sekunden-Fenster anwenden werden. Das sind die letzten fünf Minuten mit einer 1-Sekunden-Folie. Also werden wir unser Fenster alle 1
Sekunde über eins schieben und uns die Daten der letzten fünf Minuten ansehen. Also, was dies tun wird, ist, diese Reduktion neu zu berechnen , die COUNTIF Hashtags jede Sekunde, gehen für fünf Minuten zurück. Und wir sollten ein Ergebnis bekommen, das so aussieht, wenn das unsere tatsächlichen Beispieldaten waren. Also schließlich müssen wir nur die Ergebnisse sortieren und ausgeben. Wir werden eine Transformation aufrufen, um diese RDD basierend auf dem zweiten Feld,
das die Zählung ist, zu sortieren und auszudrucken. Und das sollte es so ziemlich sein. Also lass uns gehen und es in Aktion sehen. Beachten Sie, dass wir einige zusätzliche Bibliotheken haben, die wir verwenden, einige Bibliotheken von Drittanbietern. Ich zeige dir, wie das aufgebaut ist. Und ja, lasst uns einfach in den Code eintauchen und sehen, ob er funktioniert. Könnte interessant sein.
57. [Aktivität] Echtzeit-Überwachung der populärsten Hashtags auf Twitter: Alles klar, also lassen Sie uns durch das Beispiel der Verwendung der alten DStream API gehen und diese
verwenden, um die beliebtesten Hashtags auf Twitter im Moment herauszufinden. Und wenn Sie wollen, entlang folgen, Sie können versuchen, wenn Sie Kopf über apps dot twitter.com oder Entwickler dot twitter.com, Sie werden auf dem Entwicklerportal für Twitter landen. Und wenn Sie noch nicht über ein Entwicklerkonto verfügen, wird
es Sie durch den Prozess der Bewerbung für ein Entwicklerkonto führen. Und wieder, ich bin mir nicht wirklich sicher, ob es sich lohnt, das durchzugehen. Zunächst einmal machen sie es heutzutage schwieriger und schwieriger, ein Entwicklerkonto zu bekommen weil so viele Leute sie benutzen, um böse Dinge mit Bots und so zu tun. Aber wenn Sie es durchmachen wollen, wenn Sie nur sagen, dass Sie es für
Bildungszwecke für einen Online-Kurs tun und den Namen dieses Kurses auflisten. Sie werden dir wahrscheinlich ziemlich schnell einen geben. Also, wenn Sie das tun wollen, gehen Sie voran und bewerben Sie sich für ein Konto. Sobald Sie das haben, können Sie beide einen Satz von Zugriffsschlüsseln erstellen. Schauen wir uns an, wie das aussieht. Wenn Sie also auf Schlüssel und Token klicken, bringt Sie
das zu einem Ort, an dem Sie sowohl Ihre Verbraucherzugriffsschlüssel, den öffentlichen und geheimen auch eine Reihe von Token für eine Anwendung erhalten können. Und sobald Sie diese haben, werden
Sie Ihre
Twitter-Punkt-TXT-Datei in Ihrem Kursmaterial öffnen und sie dort einfügen. Also meins sieht so aus. Offensichtlich habe ich die eigentlichen Schlüssel verwischt, weil ich meine nicht verwenden möchte. Aber fügen Sie einfach Ihren Verbraucherschlüssel und Ihr Verbrauchergeheimnis und Ihr
Zugriffstoken und Zugriffstoken Geheimnis hier für Ihr eigenes Konto ein, wenn Sie folgen. Und dann der Code, wir nehmen das einfach auf und verwenden ihn, um sich bei Twitter zu authentifizieren. Seien Sie jedoch vorsichtig, stellen Sie sicher, dass Sie keine zusätzlichen Zeilen haben, keine zusätzlichen Leerzeichen vor oder nach diesen Dingen haben, die die Dinge durcheinander bringen werden. Nummer eins, das die Leute mit diesem Thema haben. Sobald Sie das haben, gehen wir zurück zur Intelligenz und öffnen beliebte Hashtags. Und lasst uns durch das gehen, was hier vor sich geht. Also wieder, dies verwendet einige ältere APIs hier, DStreams und RDD. Also haben wir hier eine separate Funktionen, um unsere Log-Level hier
zu behandeln, um dies in ein wenig ausführlicher Weise zu tun. Es wird Deal geben. Wir nennen unsere Hauptfunktion. Das erste, was wir tun, ist Anruf Setup Twitter. Alles, was tut, ist, diese Twitter-Punkt-TXT-Datei zu öffnen und alle diese Authentifizierungsschlüssel zu extrahieren. Es legt also nur die Systemeigenschaften fest, die der Client von
Twitter benötigt, damit Sie sich mit Twitter verbinden können. Und unter der Haube verwendet dies Bibliotheken
von Drittanbietern, die ich in den Kursmaterialien enthalten habe. Dies ist wahrscheinlich ein guter Zeitpunkt zu erwähnen, dass dies alles mit SBT unter der Haube in Intelligenz gebaut wird. Wenn Sie hier tatsächlich auf SBT aufbauen, können
Sie die Pakete sehen, die wir tatsächlich für die Kursmaterialien selbst enthalten. Also hier sagen wir explizit, wir verwenden Scala Version 2.12, Spark Version 3. Wir importieren Spark Core Spark SQL, Spark, MLLib, Spark Streaming. So hat alles auf magische Weise so weit durch den Kurs funktioniert. So haben wir Spark tatsächlich zur Verfügung gestellt. Auch wenn wir Spark nicht explizit installiert haben. Sbt ist rausgegangen und hat das automatisch für uns bekommen. Und auch wir bekommen die Twitter für J core und Twitter für J Stream-Pakete. Dies sind nur Twitter JAR-Dateien, die es Ihnen ermöglichen, Twitter-Daten von der Twitter-API
zu streamen. Sobald Sie diese Umgebungsvariablen auf ein Aufzählungszeichen gesetzt haben, wird es für Sie authentifiziert. Indem wir dies in unseren Bibliotheksabhängigkeiten festlegen, wird automatisch die korrekte Version der Twitter-Bibliotheken abgerufen,
damit wir diese Daten für die angegebene Version, die wir hier wollen, verbinden und streamen können. Es gibt auch eine separate Bibliothek, die wir diesen Twitter-Stream von der Twitter-API in einen D-Stream für Spark-Streaming konvertieren . Und das haben wir gerade in die Lib aufgenommen. Und das schließen wir einfach in die Bibliotheken ein, die hier im Projekt enthalten sind. Wenn Sie hier nach oben gehen und in den lib-Ordner gehen, ist
das, was diese dStream dash Twitter Jar Datei auch da ist. Es wurde explizit gegen die spezifische Version von Spark und Scala und Twitter erstellt, die wir in dieser SBT-Datei angeben. Und die Art und Weise SBT funktioniert, ist, dass, wenn sich etwas im lib-Ordner befindet, es es einfach automatisch als eine lokale Abhängigkeit einfügt. So funktioniert alles unter der Haube. Zurück zum Code. Also statt Twitter hat die gesamte Authentifizierung eingerichtet, die es benötigen, um eine Verbindung herzustellen. Und sobald wir das haben, können wir unseren Streaming-Kontext
mit einer 1-sekündigen Batchgröße von Daten einrichten . Wir richten unsere Protokollierung ein, um die Protokollebene festzulegen. Und dann nennen wir Twitter-Utils. Das ruft in die lokale Bibliothek auf, die wir dort eingeschlossen haben. Und wir werden create stream darauf aufrufen, um
einen DStream von Twitter mit dieser Drittanbieter-Bibliothek zu erstellen , wir übergeben einfach unseren Streaming-Kontext und einen optionalen Parameter, den wir nicht brauchen. Sobald wir das haben, können wir einfach Status zum
Statuspunkt GetText aufrufen und diese als unsere Kartenfunktion auf diesem DStream verwenden. Also alles, was tut, ist das Textfeld aus jedem Tweet zu extrahieren. Es ist uns also egal, wer es getwittert hat. Uns ist egal, wie spät sie es getwittert haben. Alles, was uns wichtig ist, ist der Tweet selbst. Und das ist es, was in unseren neuen Status geht, D-String. Und hier, sobald wir das haben, verwenden
wir flatmap, um das in
einzelne Wörter zu blasen , nachdem wir sie basierend auf dem Leerzeichen geteilt
haben, filtern wir alles heraus, was nicht mit einem Hashtag beginnt. Jetzt sind wir nur noch mit Hashtags übrig, die
in unseren Tweets erschienen sind, die durch diesen Stream hereinkommen. Wir ordnen das dann zu diesen Tupeln des tatsächlichen Hashtags selbst und der Nummer 1. Und dann können wir ReduceByKey und Fenster verwenden, um alle 1 Sekunde zu überprüfen, gehen fünf Minuten zurück, um all diese
für jeden einzelnen Hashtag zu addieren und es um diesen Hashtag-Schlüssel zu reduzieren. Auch hier ist dies ein Format, das wir noch nicht mit ReduceByKey gesehen haben. Manchmal wollen sie beides in Betrieb haben, um
etwas in einer Operation hinzuzufügen , um etwas herauszunehmen. Also in diesem Fall, wenn Sie etwas hinzufügen, möchten wir es hinzufügen. Wenn du etwas rausnehmen willst, subtrahieren wir es. Normalerweise wird das der Fall sein, aber es gibt seltsame Anwendungsfälle, in denen Sie etwas komplizierteres tun möchten. Sobald wir das haben, sortieren wir es einfach und zeigen die Ergebnisse an, drucken Sie die Top 10 aus. In Ordnung, um es zu starten, sagten wir ein Checkpoint-Verzeichnis. Darüber haben wir in den Folien nicht sehr gesprochen. Aber das setzt tatsächlich einen Checkpoint-Ordner auf meinem C-Laufwerk. Wenn Sie sich auf einem anderen Betriebssystem befinden, möchten
Sie dies wahrscheinlich in einen Pfad ändern, der
auf Ihrem Betriebssystem sinnvoll ist, der natürlich nicht unter Linux oder Mac funktioniert, aber Sie könnten dies ändern, um Benutzer zu schrägen, was auch immer Ihr Benutzername ist, Ihr Home-Verzeichnis, wenn Sie Check Point mit einem Schrägstrich versehen möchten. Und das würde auch funktionieren. Dort speichert es einen Speicher die Daten, die es braucht, um dort aufzuheben, wo es aufgehört hat. Wenn diesem Skript unerwartet etwas Schlimmes passiert, während es ausgeführt wird, so kann es von diesem Checkpoint aus fortgesetzt werden. Sobald wir dieses Setup haben, starten wir einfach unseren Streaming-Kontext und lassen ihn seine Sache tun. Es wird nur ständig tun, was wir ihm gesagt haben. Reduzieren Sie in den letzten fünf Minuten alle 1 Sekunde, was der beliebteste Hashtag ist, und wir werden das weiter tun, bis jemand das Skript explizit beendet. Mal sehen, ob es funktioniert. Klicken Sie auf beliebte Hashtags, klicken Sie mit der rechten Maustaste und führen Und hier kommt. Und jedes Mal, wenn ich das mache, werde ich daran erinnert, dass Twitter eine globale Plattform ist. Wir sehen eine schreckliche Menge von fremdsprachigen Sachen und kulturellen Referenzen, die mir nichts bedeuten. Überall auf der ganzen Welt. Wir betrachten jeden Tweet, der
zumindest öffentlich erscheint und addieren die Hashtags, die am häufigsten erscheinen. Lassen Sie uns das für eine Weile laufen und sehen Sie, welche interessanten Ergebnisse wir bekommen. Lassen Sie uns das ein wenig erweitern, damit wir mehr davon sehen können. Da gehen wir. Also gerade jetzt BTS ist Trend-Trend als Top-Hashtag. Ich habe keine Ahnung, was das bedeutet. Das muss ich später nachsehen. Es steht für etwas kulturell Bedeutsames im Moment, worauf die Menschen aufgeregt sind. Stattdessen geht es bei den Menschen um Eis. Eis wird übernommen. Eis nur für Nummer eins eingeholt, sehr aufregend. Hey, wer mag kein Eis bis IP3, was auch immer zum Teufel, das ist. Immer noch zusammen. Sehr dynamisch, richtig? Eis aber, halten Sie sich allein. Wie ein Krieg zwischen Eis und BTS. Bts fragt voraus. Wie auch immer, du könntest das den ganzen Tag laufen, wenn du willst, und ich garantiere dir, dass du etwas anderes siehst, wenn du das selbst
führst, denn es ändert sich
jeden Tag, jeden Moment sagt es, wovon die Welt gerade spricht. Und zum Glück, ich glaube nicht, dass wir hier drin etwas Anstößiges sehen. Normalerweise tust du das. Obwohl um fair zu sein, ich weiß nicht, was BTS ist oder was diese Fremdsprache wo es ist, die entweder noch zusammen auftaucht. Ich weiß nicht, worauf sich das bezieht. Mann, ich muss mehr rauskommen. Aber wie auch immer, da hast du es. Wir können weitermachen und das einfach absagen. Drücken Sie hier den roten Knopf, um zu stoppen. Das. Sieht aus, als ob nach dieser Zeit der Gewinner war, was auch immer das bedeutet, in welcher Sprache das ist, vielleicht kann mir jemand in den Kommentaren sagen. Ich weiß es nicht. Vielleicht will ich es nicht wissen. Sollte es sein, könnte
es etwas Unangenehmes sein. Aber es ist ein ziemlich cooles, lustiges Beispiel, richtig? Also haben wir tatsächlich die DStream API hier verwendet, um sich mit echten
Twitter-Feeds zu verbinden und den Überblick über den beliebtesten Hashtag zu behalten, während wir im Laufe der Zeit gehen. Und wenn ich das für volle fünf Minuten laufen würde, erhalten
wir volle fünf Minuten Daten. Und wir würden dann ein Schiebefenster der letzten fünf Minuten
haben , während wir dieses Skript weiterhin ausführen. Es könnte also eine lustige Sache sein, für eine Weile zu laufen und nur zu sehen, was es tut. Also gibt es es ein Beispiel aus der realen Welt, das reale Daten verwendet. Das ist der lustige Teil, aber wie gesagt, DStreams sind irgendwie die alte Art, es zu tun. Lassen Sie uns also eintauchen in die neue Art, Dinge mit strukturiertem Streaming als nächstes zu tun.
58. Strukturiertes Streaming: Wie ich bereits erwähnt habe, waren DStreams die ursprüngliche Streaming-API für Apache Spark. In diesen Tagen benutzen die Leute etwas anderes. Manchmal nennt man es strukturiertes Streaming. So stoßen Sie immer noch auf Bibliotheken, die
DStreams wie diese Twitter-Bibliothek erwarten , die ich gerade benutzte. Es ist also immer noch nützlich zu wissen, dass es da draußen ist und wie es funktioniert. Aber Sie werden feststellen, dass strukturiertes Streaming die modernere API für Streaming und Spark ist. Und es ist auch einfacher, seine Ideen zu verwenden, dass es Datasets als primäre API anstelle von RDDs sind DStreams, die wie RDDs aussehen. Und wie ich bereits sagte, geht
viel von Spark den Weg, Datasets und in Scala oder DataFrame in Python als primäre API zu verwenden. Und das Schöne daran ist, dass es ziemlich elegant für das Streaming ist, weil Sie sich
ein Dataset vorstellen können , das nur für immer
angehängt wird und Sie es einfach abfragen, wann immer Sie möchten, genau wie jedes andere Dataset. Der Streaming-Teil besteht also nur darin, dass wir diesem Dataset immer mehr Zeilen hinzufügen , wenn neue Informationen empfangen werden. Und das macht die Dinge viel einfacher. Es bedeutet, dass Sie diese Datasets verwenden können, muss genau wie jedes andere Dataset. Es ist also eigentlich nicht viel für uns, in diesem Vortrag darüber zu sprechen. Sobald Sie die Dinge eingerichtet haben, verwenden
Sie dies einfach wie jedes andere Dataset. Alle anderen Dinge, die wir im Kurs gelernt haben, gelten für
ein Streaming-Dataset genauso wie für ein Dataset, das aus einem Batch-Prozess gelesen wird. Und die andere nette Sache ist, dass
Streaming dadurch wirklich in Echtzeit ist. Das war ein echter Henkelpunkt bei vielen Leuten. Und für eine Weile sagten die Leute, dass Spark-Streaming deshalb
schlechter als andere Streaming-Plattformen war . Nun, das können sie jetzt nicht mehr sagen, denn mit Structured
Streaming ist Streaming jetzt wirklich in Echtzeit. Wenn neue Daten empfangen werden, werden
sie sofort an dieses Dataset angehängt und Sie erhalten sofort Zugriff darauf. Wir basieren also nicht mehr auf diesen Mikrochargen wie winzige kleine RDDs, die Daten im Wert von 1 Sekunde enthalten. müssen wir nicht nachdenken. Dieses Gedankenniveau ist in unserem Code nicht mehr erforderlich. Einrichten, es ist super einfach. Alles, was wir tun müssen, ist Spark Dot Read Stream anstelle von Spark dot read sagen, wenn wir einen DataFrame oder ein Dataset einrichten. Und du kannst was sagen? Zum Beispiel, wenn Sie es nur in JSON-Dateien aus einem Logs-Bucket auf Amazon S3 lesen möchten, könnten
Sie einfach sagen, Funken Punkt-Punkt-Stream-Punkt-JSON-S3-Protokolle und das würde nur
dort sitzen und überwachen, dass Bucket in S3 den ganzen Tag lang, 24 , 7, auf der Suche nach neuen JSON-Dateien zum Einlesen und Analysieren. Und es würde einfach jede neue Zeile in
jedem neuen JSON-Datensatz hinzufügen , der dort in diesem EingabedataFrame gefunden wurde. Und dann kannst du tun, was immer du willst. Sie können es nach einer Aktion gruppieren. Sie können ein Fenster machen, wie wir es in DStream gesehen haben. Wenn Sie also ein Zeitfenster angeben möchten, können
Sie diesen zusätzlichen Fensterparameter einfach dort übergeben, um
den Zeitraum anzugeben , über den Sie gehen möchten. Und du kannst es zählen, richtig, der Strom raus, wo immer du willst. In diesem Fall werden wir es in eine JDBC-Verbindung formatieren und es einfach in eine MySQL-Datenbank
schreiben, irgendwo Turnaround und kleben sie in eine Datenbank. Das ist also wirklich der ganze streaming-spezifische Code, den Sie nur den aktiven
sehen würden , der dieses Fenster tatsächlich angibt, den Stream
einrichtet und wohin Sie den Stream schreiben. Abgesehen davon ist es nur ein normaler alter Datenrahmen oder Dataset,
je nachdem, wie Sie es verwenden und was Sie normalerweise mit dem DataFrame
tun würden , in dem Dataset auch hier gilt. Also werden wir hier ein kleines Beispiel für Streaming-Protokolldateien zu tun. Also habe ich eine Apache-Zugriffsprotokolldatei in Ihre Kursmaterialien aufgenommen. Und was wir tun werden, ist einfach ein kleines Verzeichnis in unseren Kursmaterialien zu erstellen und diese Protokolldatei zu kopieren und zu sehen, ob unsere Streaming-Anwendung sie aufnimmt und verarbeitet. Um das zu tun, sagen wir nur Spark dot read stream
dot txt, weil dies nur einfache Textdateien sind,
Protokolldateien mit einem Verzeichnispfad zum Logs-Ordner innerhalb meiner Kursmaterialien. An diesem Punkt kann ich einfach SQL-Operationen verwenden, um die Daten aus diesen Protokollzeilen mit regulären Ausdrücken zu
analysieren. Sie könnten das mit einer Kartenoperation verwenden, wenn Sie es auch wollten. Und dann benutze einfach Gruppe BY, um Dinge
über ein Fenster zu gruppieren , wenn du die Ausgabe streamen möchtest, in diesem Fall an unsere Konsole, aber es könnte genauso einfach zu einer Datenbank oder irgendetwas gehen, was du willst. Also lasst uns eintauchen und ein paar Protokolle streamen. Nicht so ein Logbuch.
59. [Aktivitäts] Strukturiertes Streaming für die Protokollanalyse in Echtzeit: In Ordnung, Also lasst uns wieder mit strukturiertem Streaming spielen, irgendwie die moderne Art, Streaming in diesen Tagen und Spark zu tun. Lassen Sie uns das strukturierte Streaming-Skript hier öffnen und sehen, wie es funktioniert. Zunächst einmal sehen Sie, dass das eigentlich ziemlich einfach ist. Ich meine, abgesehen von den tatsächlichen regulären Ausdrücken, dass diese Protokolldaten analysiert werden, ist
der Spark-Code selbst nicht eine ganze Menge. Es ist ziemlich prägnant. Also lasst uns hier durchlaufen. In Ordnung, also sind wir wichtige Sachen. Wir brauchen hier ein Kraterobjekt, setzen die Log-Level, erstellen eine Spark-Sitzung. Bisher ist nichts anders. Das erste, was aber anders ist, ist, dass wir anstelle von
Funkenpunkt, Punkttext sagen, Funkenpunkt lesen Stream dot txt sagen werden. Das war's. Das besagt, dass wir dies zu einem ungeheuren kontinuierlichen
Informationsstrom machen werden, anstatt nur einen Informationsblock aus einer statischen Textdatei zu lesen. Und der Pfad, den wir hier übergeben, ist eigentlich ein Verzeichnispfad. Und in diesem Fall wird es auf unserem lokalen Dateisystem sein. Aber Sie könnten genauso einfach einen S3-Bucket
oder ein verteiltes Dateisystem überwachen , wenn Sie es auch wollten. Also wird es einfach hier sitzen und meinen Datenschrägstrich Log-Verzeichnis für neue Textdateien beobachten. Und wenn dort neue Textdateien entdeckt werden, wird jede Zeile dieser Textdatei in die Achsenlinien DataFrame angehängt. Ok, so einfach ist es. Jetzt analysiert der Rest dieses komplizierten Codes wirklich nur diese Daten. Apache-Zugriffsprotokolle sind also ein ziemlich seltsames Format und es braucht einige ziemlich komplizierte reguläre Ausdrücke, um die Informationen
daraus zu extrahieren und diese
unstrukturierten Protokolldateidaten in strukturierte Informationen umzuwandeln . Also werde ich nicht in die Details darüber eingehen, wie diese regulären Ausdrücke funktionieren, aber sie sollen die Informationen extrahieren, die wir
aus jedem Feld dieses Apache-Zugriffsprotokolls benötigen . Und wir wenden diese regulären Ausdrücke hier innerhalb dieser großen alten Select-Anweisung an. Also nehmen wir, dass Achsenlinien DataFrame und wir rufen wählen Sie darauf. Nun wird jede neue Textzeile, die in Achsenlinien
gehen, standardmäßig in einer Spalte namens Wert sein. Für jedes dieser Beispiele machen
wir einen Reg Ex-Extrakt für die Wertspalte. Das bedeutet, dass es die rohe Datenzeile nimmt, einen regulären Ausdruck darauf anwenden wird. In diesem Fall ist der Hostausdruck
, der den Hostnamen extrahieren soll. Und wir wollten dem einen Alias von Gastgebern geben. Dies wird also im Grunde eine neue Hostspalte erstellen
, die den Host enthält, der aus dieser Zeile extrahiert wurde. Und wir tun dasselbe für den Zeitstempel für die Methode, für den Endpunkt für das Protokoll, für den Statuscode und die Inhaltsgröße. An diesem Punkt kannst du tun, was du willst, oder? Also in unserem einfachen Beispiel hier,
alles, was wir tun werden, ist nach dem Status zu gruppieren und im Laufe der Zeit zu zählen. So werden wir eine laufende Zählung über die Zeit halten wie oft jeder Statuscode in diesen Protokolldateien angezeigt wird. So wird es wieder dort sitzen und darauf warten, dass neue Protokolldateien in das Datenschrägstrich-Log-Verzeichnis abgelegt werden. Und es wird im Laufe der Zeit gruppiert, wie oft jeder Statuscode erscheint. Wir müssen ihm sagen, wo wir diese Informationen ablegen sollen. Also konstruieren wir, was eine Abfrage genannt wird. Und wir sagen nur,
dass Status zählt DataFrame, Das ist unsere letzte Zählung DataFrame dort. Wir werden diesen Stream mit dem folgenden Ausgabemodus schreiben. Wir werden sagen, wir wollten die Ausgabe formatiert auf die Konsole gehen abzuschließen. Und wir geben dieser Abfrage einen Namen namens zählt. Und wir werden nur Stärke aufrufen, um diesen Ausgabestrom tatsächlich zu starten. Ok. Also haben wir unseren Eingabestream hier oben mit Spark dot read stream dot txt definiert. Das ist es, was überwachen wird. Wir haben eine Reihe von Operationen definiert, die letztendlich zu den
Statuszählungen DataFrame geführt haben, der aus diesem Eingabestrom berechnet wird. Und dann erstellen wir hier einen Ausgabestrom namens Abfrage. Dann warten wir einfach auf die Kündigung. Es wird nur für immer laufen, bis wir es explizit stoppen. Und wenn jemand das macht, rufen
wir Stopp auf der Sitzung an, um die Dinge abzuschließen. Also lasst uns es loslegen und sehen, ob es funktioniert. Zuerst wird es einfach ausführen. Wir leisten es uns, anfangs
nichts in diesem Verzeichnis zu drehen , und deshalb müssen wir
Sachen reinlegen , damit es wirklich etwas Interessantes macht, richtig? Also lasst uns das machen. Gehen wir hier zu unseren Kursmaterialien und gehen in die Daten ein. Und Sie werden sehen, dass es hier eine Zugriffsprotokolldatei gibt, die
ein tatsächliches Apache-Zugriffsprotokoll von einer meiner Websites enthält . Lassen Sie uns das kopieren und öffnen Sie das Logs-Verzeichnis und fügen Sie es dort ein. Und was passieren sollte, ist, dass unser Drehbuch aufgreifen sollte. Ich kann meinen CPU-Lüfter laufen hören, er tut etwas. Und es hat funktioniert. Also nahm er die neue Akte auf und zählte den gesamten Flugcode. So können wir sehen, dass wir tatsächlich
einen Fehler von 500 Fehlercode haben , hier zeigen sie eine schreckliche Menge. Das würde mich also auf
ein echtes Problem auf meiner Website warnen , wenn dies eine echte Anwendung wäre, richtig? Vielleicht könnte ich eine Art Schwelle für die Anzahl von
500 Fehlern haben und mich warnen, wenn das einen Schwellenwert im Laufe der Zeit überschreitet. Mal sehen, ob es mit funktioniert, da mehr Daten hineingeworfen werden. Also gehen wir zurück zu Daten und machen eine Kopie unserer Zugriffsprotokolldatei. Ich werde nur kopieren und einfügen. Also, jetzt haben wir Zugriff Log Dash Copy. Lassen Sie uns das auch in unsere Protokolle kopieren. Und was wir sehen sollten, ist all diese Zahlen, doppelte Charge eins, wir haben eine weitere Charge von Informationen, die hereinkamen. Und sicher genug, alle diese Zahlen haben sich verdoppelt, weil ich gerade die gleiche Protokolldatei kopiert habe. Und wieder, also hast du es. Lassen Sie uns den X-Button hier drücken, um den Stream zu stoppen. Und ja, das ist Spark Streaming und Action, ziemlich coole Sachen. Wie Sie sehen können, ist Structured Streaming wirklich einfach zu bedienen. Wenn Sie ein Dataset verwenden können, können
Sie strukturiertes Streaming verwenden, und Sie sind nicht mehr
darauf beschränkt , Daten in Batchform zu verarbeiten. Sie können es so verarbeiten, wie es eingeht, in Echtzeit, was sehr spannend ist. Alles klar, das ist Spark, das auf den Punkt gebracht wird. Lasst uns weitermachen.
60. [Übung] Windowed mit strukturierten Strömen: Also diese nächste Übung wirklich interessant. Ich möchte, dass Sie die wichtigsten URLs, die dort
in meinen Ereignisprotokollen für meine Apache-Zugriffsprotokolle angezeigt werden, verfolgen . Und behalten Sie das im Auge. Anstatt die Anzahl der Statuscodes im Laufe der Zeit anzuzeigen, möchte
ich, dass Sie stattdessen die Anzahl
der Top-URLs anzeigen, die aus den Protokolldaten angezeigt wurden. Und um es noch interessanter zu machen, möchte
ich nicht, dass Sie das von Anfang an messen. Ich möchte nur, dass Sie in den letzten 30 Sekunden zurückblicken und mir
nur sagen, was die besten Ergebnisse innerhalb der letzten 30 Sekunden waren. Um dies zu tun, müssen Sie
das Konzept der Fensteroperationen im Spark-Streaming einführen. Also lassen Sie mich das schnell vorstellen. Eine fensterartige Operation blickt nur über einen gewissen Zeitraum zurück. Wenn ich zum Beispiel nur Ereignisse betrachten möchte, die in den letzten 10 Minuten passiert sind, hätte
ich ein 10-Minuten-Fenster. Und das Dia-Intervall definiert, wie oft wir dieses Fenster auswerten. Also haben wir ein 10-Minuten-Fenster, sagen wir von 12 Uhr bis 12 zehn. Wenn wir ein Dia-Intervall von fünf Minuten hätten, bedeutet
das, dass wir dieses Fenster bei 1205121012151220 bewerten würden. Jedes Mal, wenn wir uns das letzte 10-Minuten-Fenster ansehen, in dem wir sind. Um das etwas konkreter zu machen, lassen Sie mich Ihnen ein Diagramm zeigen, das direkt aus der Spark-Dokumentation hier stammt. Und hier haben wir ein 10-Minuten-Fenster mit einem 5-minütigen Dia-Intervall. Also beginnen wir das Ding um 12 Uhr in diesem hypothetischen Beispiel. Also haben wir Fenster, die von 12 Uhr bis 12 zehn laufen, von 1205 bis 1215, von 1210 bis 12, 20 und so weiter und so weiter. Also alle fünf Minuten haben wir ein neues 10-Minuten-Fenster definiert. Und im Laufe der Zeit aggregieren wir die Ergebnisse ohne in diesen Fenstern. Und wir fügen weiterhin die Ergebnisse dieser Fenster zu unserer Ergebnistabelle hinzu, während wir gehen. In diesem Beispiel haben
wir einen Strom von Tiernamen, die anscheinend hereinkommen. Also ein 1202 und 12 03, wir haben Katzenhund und Hund kommen. Also ein 12 05, wir haben ein leichtes Intervall, das getroffen wird. Das wird also auf das Fenster von 12 Uhr bis
1210 schauen , denn das ist nur unser erstes Fenster, das wir zufällig haben, seit wir angefangen haben zu laufen. Und was wir bisher haben, ist eine Katze und drei Hunde, die empfangen wurden. Um 1207 bekommen wir eine Eule und eine Katze. Wenn wir also unser nächstes Dia-Intervall bei 1210 ausführen, werden
wir nun auch auf die 12 Uhr bis 12 10 und die 1205 bis 1215 Fenster schauen. Jetzt stellt sich heraus, dass unsere Katze tatsächlich in diese 12 Uhr bis 12, 10 Fenster hinzugefügt wurde. Wir werden das also zu unserer Ergebnistabelle hinzufügen und das aktualisieren. Und wir werden auch ein neues Fenster in unserer Ergebnistabelle für 1205 bis 1215 erstellen, das wir verfolgen werden. Und es geht einfach weiter und geht weiter, oder? Also, ein 1215, wir werden jetzt
ein weiteres neues Fenster von 1210 bis 1220 bekommen , das wir uns ansehen werden. Und wir gehen zurück und aktualisieren alle vorherigen Fenster nach Bedarf, um die neuen Daten zu berücksichtigen. Also haben wir noch einen Hund und eine weitere Stunde, die dazwischen kam. Und wenn Sie genau hinsehen, können Sie es herausfinden. Aber im Grunde ist die Idee,
dass das Fenster der Zeitraum ist, über den du Sachen aggregierst. Und das Folienintervall ist, wie oft Sie das auswerten. Das codierte dafür ist ziemlich unkompliziert. Sie sagen nur Gruppe BY, wenn Sie eine Art Aggregation für eine Spalte durchführen möchten, in diesem Fall die Spalte, die wir nach dem Namen dieser Spalte gruppieren. Und syntaktisch würde er „Fenster“ sagen. Und dann geben Sie einen Anruf mit dem Spaltennamen an, der den Zeitstempel
darstellt, der definiert, wann dieses Ding passiert ist, richtig? Der Fenstercode im
Spark-Streaming verfolgt also nicht automatisch, wann Ereignisse empfangen wurden. Es wird sich eine bestimmte Spalte in Ihren Daten ansehen, die aufgenommen werden. Okay, also bedenken Sie das. Sie wissen, Sie werden Windowing für Daten definiert, die im Stream selbst sind,
nicht auf, wenn das tatsächlich vom Spark-Streaming empfangen wurde. So subtiler, aber wichtiger Unterschied, besonders in unserem Beispiel hier, weil wir sehr alte Apache-Protokolle verwenden, die Zeitstempel von Jahren und Jahren haben. Das wird also beeinflussen, wie wir dieses Problem tatsächlich angehen. Dann sagen Sie, dass die Dauer des Komma-Fensters gleich welcher Fensterdauer ist, die Sie wollen. Und das ist nur auf Englisch angegeben, wie 10 Minuten, 30 Sekunden, was immer du willst. Ich denke, das gibt es aber einen Monat. Und die Dia-Dauer auch in einfachem Englisch angegeben. So syntaktisch, das ist, was Sie wissen müssen, wie man Fensteraggregationen macht. Also deine Herausforderung wieder, modifizieren Sie dieses strukturierte Streaming-Skript, an dem wir gerade gearbeitet haben, um die am häufigsten angezeigten URLs zu verfolgen. Und das nennt man tatsächlich Endpunkte in diesem speziellen Skript. Das Gleiche. Und ich wollte das mit einem 30-Sekunden-Fenster berechnen und die zweite Folie besuchen. Jetzt sind Sie auf braucht einige kleine Codeausschnitte, um dies zu tun. Zunächst einmal werde
ich diesen Codeausschnitt wiederholen, wie man dieses Fenster
tatsächlich syntaktisch angibt. So würde dieser Code aussehen. Das ist nicht die gesamte Zeile, die Sie
im eigentlichen Skript benötigen , aber es ist ein guter Teil davon. Ich gruppiere nach ist nicht genug. Sie müssen auch zählen, wie viele in dieser Gruppe sind, oder? Sie haben also in vorherigen Beispielen gesehen, wie Sie das tun können. Wie ich schon sagte, Sie werden ein Problem haben, weil die Apache-Beispielprotokolle, die ich Ihnen gegeben habe, sehr alt sind, sie sind Jahre alt. Und das wird nicht mit einem angespannten 30-Sekunden-Fenster funktionieren , richtig? Wenn Sie also 30 Sekunden auf
ein Protokoll zurückblicken , das Daten von vor drei Jahren erfasst hat, wird
das nicht so gut funktionieren. Sie können also eine neue Spalte in Ihrem Dataset erstellen, die die aktuelle Zeit ist, zu der es aufgenommen wurde. Und die Syntax dafür ist, dass der zweite Block, ihre Protokolle df dot width Spalte wird eine Spalte namens
Ereigniszeit als gleich dem aktuellen Zeitstempel hinzufügen . So erhalten Sie eine neue Spalte, die Sie für die aktuelle Zeit verwenden können. Das wird für diese Übung etwas nützlicher sein. Und schließlich wollen Sie sicherstellen, dass Sie
die Zählungen in absteigender Reihenfolge bestellen möchten. Irgendwann müssen Sie also Reihenfolge nach Anrufzähler sagen,
was auch immer Sie diesen Zählspaltenpunkt DESC nennen, um anzugeben, dass Sie das in
absteigender Reihenfolge möchten , damit Sie die Top-Ergebnisse zuerst sehen und nicht umgekehrt. Also gehen Sie los und haben Sie es, das ist ein wenig schwieriger, könnte erfordern, dass Sie ein wenig mehr kreatives Denken zu tun oder Sachen online suchen. Aber hey, so funktioniert die reale Welt. Also gib es mal los. Und wenn wir zurückkommen, zeige ich dir, wie ich es gemacht habe.
61. Übung von: Top-URLs in einem 30-Sekunden-Fenster: In Ordnung, also lasst uns etwas etwas schickeres mit
strukturiertem Streaming machen und einen Blick auf meine Lösung werfen, um die Top-URLs zu verfolgen, die von
unseren Apache-Zugriffsprotokollen angesehen werden, indem wir ein 30-Sekunden-Schiebefenster anstelle von nur vom Anfang der Zeit. Also habe ich gerade mit einer Kopie dieses
strukturierten Streaming-Punkt-Scala-Skripts angefangen , wie ich Ihnen empfohlen habe. Und nicht eine ganze Menge ändert sich, bis wir hier auf Linie 42 zu dieser Zeile gekommen sind. Nun, wie ich bereits erwähnt habe, ist dies ein sehr altes Apache-Zugangsgesetz, das ich Ihnen in den Kursmaterialien gegeben habe. Und wenn wir Schiebefenster der Zeit aus den letzten 30 Sekunden machen wollen. Nun, wir müssen ein paar neue Ereigniszeiten erstellen, die aktueller sind, oder? Also das ist alles, was diese Zeile hier tut, nimmt unsere Protokolle df Datenrahmen und hängt eine neue Spalte an, die mit Spalte namens
Ereigniszeit verwendet, die an den aktuellen Zeitstempel gesendet wird, wenn diese Daten tatsächlich aufgenommen werden. Und wir werden uns umdrehen und die resultierenden DataFrame-Protokolle df2 aufrufen. Alles klar, jetzt werden die Dinge interessant. Lassen Sie uns also eine laufende Zählung dieser Endpunkte behalten. Also in, in unserer Nomenklatur hier, und Endpunkt ist im Grunde das gleiche wie eine URL. Wir haben also eine GET-Methode, gefolgt vom Endpunkt, der
die URL auf unserer Website sein wird, die jemand getroffen hat. Um dies zu tun, werden
wir die gleiche Syntax verwenden, über die wir in den Folien gesprochen haben 30-Sekunden-Fenster mit einer 10-Sekunden-Dia-Dauer
einzurichten. Wir sagen nur Protokolle df2, Groupby Window Call. Der Spaltenname hier ist Ereigniszeit. Das ist der, das ist der Zeitstempel, auf dem wir Fenster machen werden. Ok? Wir geben eine Fensterdauer von dreißig Sekunden an und wir checken ein, aktualisieren diese Fenster alle 10 Sekunden. Und der zweite Parameter für den Befehl Gruppe BY wird Endpunkt genannt. Wir werden also nach den Endpunkten gruppieren alle diese gemeinsamen Endpunkte zusammenfassen. Und wenn Sie diese innerhalb
dieses Fensters und auf dieser Foliendauer gruppiert haben, werden wir sie zählen. Also, was diese eine Codezeile tut, ist zu zählen, wie viele jeder URL alle 10 Sekunden angetroffen wurde, das aktuelle 30-Sekunden-Fenster
betrachten, in dem wir richtig sind? Nun, das reicht nicht. Ich möchte diese auch sortieren, so dass ich die beliebtesten URLs sehe. Ich will nur keine ungeordneten Listen sehen. Also werde ich außerdem diese Endpunkte nehmen,
zählt DataFrame und sortieren Sie es, indem Sie sagen, dass Punkt OrderBy Coutname gleich count ist, wird der Name der Zählspalte sein, die von diesem Cal-Befehl Punkt DSC erstellt wird, um zu sagen, dass ich wollte in absteigender Reihenfolge. Die beliebtesten URLs sind also an der Spitze, und das ist es. Der Rest des Codes ist im Grunde der gleiche. Wir haben dort an die Konsole ausgegeben und es im Grunde gestartet. Und ein wenig beiseite hier, eine letzte Anmerkung, wenn Sie dies in eine Datenbank oder eine Datei oder so etwas schreiben möchten, würden
Sie einfach festlegen, dass der Ausgabemodus etwas anderes ist und das Format etwas anderes ist. Wenn Sie also die Dokumentation dort nachschlagen, können
Sie sehen, wie wir in eine Datenbank schreiben können eine Textdatei oder eine Parkettdatei oder was auch immer Sie wollen. Es muss nicht auf der Konsole sein. Es wird viel praktischer sein, diese Daten tatsächlich irgendwo zu speichern, oder? Und was wir speichern, ist die Ergebnistabelle. Also werden wir diese,
diese Tabelle der Ergebnisse für jedes Fenster aktualisiert,
für jede Foliendauer zu erhalten. Das Ergebnis, das wir sehen werden, ist eine Tabelle, die die Ergebnisse verfolgt, die wir in jedem Fenster sehen, jedes 30 Sekunden Fenster, das wir haben. Mal sehen, ob ich dich tatsächlich belüge oder nicht. Lassen Sie uns das laufen und sehen, was passiert. So werden Top-URLs laufen lassen, dass sich drehen und ich werde dieses Fenster groß machen, damit wir sehen können, was los ist. In Ordnung, also sitzt es da und wartet auf Daten. Ich werde hier in meinen Kursmaterialien zu meinen Protokollen zurückkehren. Und Sie können sehen, dass ich drei Kopien meines Achsenprotokolls hier habe, mit dem ich spielen kann. Fangen wir mit einem an. Wir müssen das kopieren und es hier in meinen Logs-Ordner werfen. Da wir also in Echtzeit streamen, sollte
es die Existenz dieser neuen Daten aufnehmen und alles aktualisieren. Es schüttelt gerade weg. Du kannst meinen CPU-Lüfter hören. Und da haben wir es. So können wir sehen, dass diese 10 Sekunden Dia-Intervalle, wir berechnen diesen Fensterwert jedes Mal und wir erhalten ein konsistentes Ergebnis, weil wir
tatsächlich nicht mehr als 30 Sekunden laufen. Also lassen Sie uns weiter gehen und einige weitere Daten
dort hineinwerfen , nur um sicherzustellen, dass es wie erwartet funktioniert. Also beachten Sie, hier sehen wir, dass 0, ich sollte jetzt Batch 1 sehen. Und es gibt Charge eins. Interessanterweise ist es die gleiche Nummer wie vorher, oder? Weil seit dieser ersten Charge mehr als 30 Sekunden vergangen sind. So dass die erste Charge von Informationen tatsächlich abgelaufen ist. Es ist vom Ende meines Fensters gefallen. Wenn wir also kein Fenster hätten, hätten
wir all diese Zahlen doppelt gesehen, richtig. Aber das tat sie nicht, weil die dreißig Sekunden Daten abgelaufen sind. Ich glaube nicht, dass 30 Sekunden ziemlich vergangen sind, also mal sehen, ob ich dort tatsächlich eine größere Zahl bekommen kann. Wenn ich schnell genug bin, legen wir es in ein drittes Exemplar. Und hier sehen wir einen Patch zu mir war nicht ganz schnell genug, fiel vom Ende dort des 30-Sekunden-Fensters. Aber wenn Sie Ihre eigene Version dieses Laufens haben, fühlen Sie sich frei, damit zu spielen oder diese Fensterzeiten anzupassen um ein wenig freundlicher zu Ihnen und wie Sie arbeiten. Und ein guter Weg, um ein Gefühl davon zu bekommen, wie Windows und Dia-Intervalle funktionieren, ist damit zu experimentieren und einfach so herumzuspielen, wie wir es jetzt tun. So haben Sie jetzt etwas über Spark Streaming erfahren und wie Sie Daten in Echtzeit verarbeiten können, wenn sie eingehen.
62. GraphX, Pregel und Breadth-First-Search mit Pregel.: Also in diesem Abschnitt werden wir Graphx vorstellen, die eine API für den Umgang mit Diagrammen von Informationen wie unser Netzwerk von Superhelden früher im Kurs ist. Grafik ist eine Art vernachlässigtes Stiefkind von Smart, um ehrlich zu sein, es hat in letzter Zeit nicht viel Entwicklung gesehen und es steckt immer noch auf der alten RDD-API fest. Es gibt eine neuere Version davon in der Entwicklung namens Graph-Frames, aber es ist noch nicht bereit für die Prime Time. Also für jetzt, nur der Vollständigkeit halber, werde
ich über Graph x und seine aktuelle Form sprechen, die die RDD-Schnittstelle verwendet,
aber Sie werden sehen, dass es immer noch ziemlich mächtig ist. Und es zu benutzen fühlt sich ein bisschen mehr wie SQL an. Lassen Sie uns also eintauchen und sehen, wie Grafiken Ihnen helfen können massive verteilte Probleme mithilfe von Informationsdiagrammen zu
lösen. Lassen Sie uns kurz in die Welt von GraphX eintauchen, der letzten Kernkomponente von Spark selbst. Und wenn wir über Grafiken sprechen, sprechen
wir nicht über Liniendiagramme oder Diagramme oder so etwas. Wir reden von Diagrammen im Sinne der Informatik. So zum Beispiel unser soziales Netzwerk von Superhelden, das wir früher im Kurs gesehen haben. Dies ist ein Beispiel für das Diagramm, von dem wir sprechen, wo wir Scheitelpunkte haben, die in diesem Fall einzelne Superhelden und Kanten zwischen den Scheitelpunkten darstellen, die Beziehungen zwischen ihnen darstellen. Grafik ist irgendwie cool, aber es ist wirklich nur nützlich für eine bestimmte Sache. Es kann also nicht wirklich die Fragen beantworten, die wir in dem Code beantwortet
haben, den wir für die Analyse unseres Superhelden-Netzwerks geschrieben haben. Aber es kann Dinge wie Messen der Verbindung, Gradverteilung, durchschnittliche Pfadlänge, Dreieckzahl, Art dieser hohen Messwerte des Graphen als Ganzes tun. Es kann Dinge tun, wie zählen Sie alle Dreiecke im Diagramm und wenden Sie den PageRank-Algorithmus auf die Unebenheiten. Also, ich denke, das ist wirklich die treibende Kraft hinter GraphX selbst. Es ist am nützlichsten für die Implementierung von etwas wie PageRank, was offensichtlich ein wichtiger Anwendungsfall ist. Und das ist auch ein Problem, bei dem
natürlich massiven Umfang mit sich bringt , wo die Macht von Spark nützlich ist. Also ist es irgendwie mehr dafür gemacht als alles andere. Sie können auch Dinge wie das Verbinden von Diagrammen und Transformieren dieser Diagramme sehr schnell auf verteilte Weise durchführen. Aber für Dinge wie unsere Grade der Trennung Beispiel, wo wir versuchen
herauszufinden , wie viele Grad der Trennung als Superheld von Spider-Man ist. Sie werden keine eingebaute Unterstützung für solche Operationen finden. Es unterstützt jedoch die Pregel-API zum Durchlaufen eines Graphen. Und das ermöglicht es Ihnen, Ihren eigenen Code zu schreiben und eigene Algorithmen
zu entwickeln, die Art von Live in Grafiken. Und das gibt Ihnen die Flexibilität,
diese komplizierteren Dinge zu tun , die Sie sich erträumen könnten. Sie kommen einfach nicht aus der Kiste. Sie müssen darüber nachdenken und kreativ denken, wie wir es tun mussten, wenn wir
dies mit Datenrahmen oder RDDs tun . Grafik führt also ein paar neue Datentypen ein, den Scheitelpunkt RDD und die Kante RDD, sowie den Edge-Datentyp. Und so stellen wir die Scheitelpunkte und die Kanten zwischen ihnen dar, aus denen ein Diagramm besteht. Jetzt Graphics ist ein bisschen wie ein Überfall. Es ist immer noch auf der RDD-API geschrieben, obwohl Spark selbst versucht hat mehr und mehr in Datenrahmen und Datasets zu
migrieren. Ganz ehrlich gesagt, GraphX ist irgendwie auf der Strecke gefallen. Es hat noch nicht wirklich viel aktive Entwicklung gesehen. Es ist immer noch ein Kernstück von Spark selbst, also bedecke ich es hier. Aber Sie sehen, dass es mehr und mehr durch andere Dinge ersetzt wird werden einfach nicht viel in der realen Welt verwendet. Es stellt sich heraus, dass es nicht wirklich so viel Nutzen für Grafiken hat. Und infolgedessen wurde es irgendwie in aller Ehrlichkeit vernachlässigt. GraphX ist also immer noch auf RDDs aufgebaut. Ein weiterer Grund, RDDs zu lernen, gibt es ein alternatives Paket namens
Graph-Frames , das auf der neuen DataFrame-API basiert. Aber es ist noch nicht wirklich veröffentlicht. Es ist eine Version wie 0.8 das letzte Mal, als ich es überprüft habe. Irgendwann könnten wir sehen, wie Graph-Frames Grafiken und Funken ersetzt haben, aber jetzt haben wir die RDD-basierte Grafik, mit der wir arbeiten können. Und Sie werden feststellen, dass Grafikcode größtenteils wie
jeder andere RDD-Sparkcode aussieht . Und tatsächlich, sobald Sie einen Graph erstellt haben, sieht der
Umgang mit ihm sowieso schrecklich wie Spark SQL aus, also ist es nicht so schlimm, wie es klingt. Das Erstellen eines Scheitelpunkts RDD ist ziemlich unkompliziert, wirklich. Sie müssen nur ein Tupel zurückgeben, das eine Scheitelpunkt-ID,
einen eindeutigen numerischen Bezeichner als erstes Feld enthält . Und was auch immer Daten, die Sie mit
diesem kleinen Code-Snippet hier verknüpfen möchten , den wir aus unserem Beispiel nehmen. Du siehst, dass wir das tatsächlich in eine Option einpacken. Und so gehen wir mit Nullwerten in Scala um. Wir haben vorher nicht wirklich darüber gesprochen, aber Sie sehen, dass wir eine Option einer Vertex-ID und einer Zeichenfolge definieren, und das bedeutet, dass wir die Möglichkeit haben, nichts zurückzugeben. Sie werden also sehen, dass wir in dem Fall, in dem wir ein gültiges Ergebnis haben, einige mit einem Tupel zurückgeben, das aus einer Vertex-ID und den mit diesem Scheitelpunkt verknüpften Daten besteht. Wenn wir dort einen ungültigen Eintrag haben, geben wir keine zurück. Und das bedeutet nur, dass es keine Ergebnisse gibt. Es ist im Grunde das Scala-Äquivalent von null. Und das ist nützlich, denn wenn Sie FlatMap
auf einer RDD aufrufen und Ihre Funktion keine zurückgibt, wird
das einfach verworfen und das ist in Ordnung. Das ist also eine Möglichkeit, mit dem Fall umzugehen nichts aus einer FlatMap-Operation zurückgegeben wird. Im Falle unserer Daten mussten wir einige Datenzeilen haben, die ungültig sind. Es stellt sich heraus, dass jede Heldenkennung über 6486 kein echter Charakter ist, also müssen wir diese verwerfen. Und das ist der Fall, wo wir in diesem Fall keines zurückgegeben haben. Erstellen einer Kante ist auch ziemlich unkompliziert. Alles, was Sie tun, ist ein Kantenobjekt zu erstellen, das eine Liste der Knoten enthält, die es verbindet. In diesem Beispiel können Sie sehen, dass wir eine Kante zwischen
einer bestimmten Helden-ID erstellen , die den Anfang
einer Zeile in unserer Datendatei für das Marvel-Superhelden-Dataset beginnt . Und wir konstruieren eine neue Kante zwischen dem in jedem Superhelden, dieser Held verbunden ist, durch diese Textzeile
definiert wird. Also ein Rand, sehr unkompliziert. Es ist nur ein Kantenobjekt, das aus
zwei Scheitelpunkt-IDs und
einigen zusätzlichen Informationen besteht zwei Scheitelpunkt-IDs und , die Sie auch damit verknüpfen möchten. Wieder ziemlich unkompliziert. Und um einen Graphen zu konstruieren, ist das unkompliziert. Sie konstruieren einfach ein Diagrammobjekt und erstellen es mit der Liste der Scheitelpunkte, die Sie darin haben möchten, diese beiden Kanten zwischen diesen Scheitelpunkten. Und das ist es so ziemlich. Sie werden wahrscheinlich dieses Diagramm zwischenspeichern wollen, weil Sie wahrscheinlich eine Reihe von Operationen daran durchführen wollen. Und indem Sie es zwischenspeichern, was sicherstellt, dass es im Speicher bleibt, was dazu beitragen kann, optimierte Dinge zu entfalten, wenn Sie später mit diesem Diagramm arbeiten. ist also auch ziemlich einfach, Dinge mit einem Graphen zu machen, wenn Sie es konstruiert haben, obwohl es manchmal nützlich ist, einen Beispielcode zu sehen, von dem aus zu beginnen. Zum Beispiel, wenn Sie die Top 10 am meisten verbundenen Helden nehmen möchten, könnten
wir Graph Arzt nennen einverstanden, diese Grad der
Verbundenheit zu erhalten und verbinden sich diejenigen mit den Scheitelpunkten selbst. Sortieren Sie die angegebenen Ergebnisse nach dem Feld, das der Anzahl
der Verbindungen entspricht , die sie in absteigender Reihenfolge haben. Nimm die Top 10 und du bist fertig. Das ist also eine einfache Möglichkeit, herauszufinden, wer die am meisten verbundenen Superhelden in nur einer Codezeile
sind, sobald Sie diese Diagrammobjekte konstruiert haben, so etwas einfacher. Die Syntax ist hier etwas schwieriger zu folgen, also ist es ein wenig Jury, denke
ich, darauf , ob das eigentlich
eine einfachere Art ist , es zu codieren, aber es funktioniert. Das ist also eine Möglichkeit, GraphX zu verwenden. Aber wie wir bereits gesagt haben, ist es viel flexibler, wenn wir die Pregel-API zusätzlich zu GraphX
eingeführt haben . Lassen Sie uns also darüber sprechen, dass als nächstes und wie wir tatsächlich Graph x erweitern können, um die Ergebnisse zu duplizieren, die wir in unserem Grad-of Separation Beispiel früher im Kurs erhalten haben.
63. Verwendung der Pregel API mit Spark: Lassen Sie uns also genauer untersuchen, wie die Pregel-API uns mehr Flexibilität bietet. Zusätzlich zu Grafiken können
wir tatsächlich nachbilden, was wir mit dem
Breiten-Suchalgorithmus gemacht haben, um den Grad der Trennung
zwischen zwei beliebigen Superhelden in unserem Graph
von Marvel-Superhelden zu finden zwischen zwei beliebigen Superhelden in unserem Graph , die zusammen erscheinen und Comic-Bücher. Und die Art und Weise, wie Pregel auf einer hohen Ebene arbeitet, ist im Grunde jeder Scheitelpunkt die Fähigkeit hat, Nachrichten an alle seine benachbarten Scheitelpunkte zu senden. Und jeder Graph wird dann in einer Iteration verarbeitet, die als Superstep bezeichnet wird. Und bei jedem Superstep passieren drei Dinge. Meldungen aus der vorherigen Iteration werden von jedem Scheitelpunkt empfangen. Jeder Scheitelpunkt führt dann ein Programm aus, um sich basierend auf diesen Nachrichten zu transformieren. Und dann sendet jeder Scheitelpunkt Nachrichten an andere Scheitelpunkte, wenn er im nächsten Schritt aufgenommen werden möchte. Und wenn Sie sich erinnern, wie wir den Breadth-first Suchalgorithmus implementiert haben, denken
Sie wahrscheinlich schon, Hey, das ist ziemlich gut, wie dieser Algorithmus funktioniert. Und in der Tat tut es das. So können wir unsere Grafik ganz einfach hier initialisieren, wenn Sie sich richtig erinnern, beginnen
wir einfach, indem wir alle Entfernungen bis unendlich einstellen außer dem Ausgangspunkt, von dem wir die Entfernungen messen. Und für diesen werden wir natürlich den Abstand auf 0 setzen, weil
der Abstand zwischen etwas und sich 0 ist. Wir können das mit einer Zeile Code und Grafiken tun. Wir können einfach Graph Dot Map Scheitelpunkte sagen und überprüfen, ob die ID
gleich der Idee des Heldenist gleich der Idee des Helden , den wir von dem Ort beginnen möchten, von dem wir messen. Wenn ja, setzen wir den Anfangsabstand auf 0. Andernfalls setzen wir diese Scheitelpunktattribute auf positive Unendlichkeit. Und dann nutzen wir diese Messaging-Funktion
, um aus diesen ersten Notizen heraus zu lüften. Wir beginnen also von unserem ersten Ausgangspunkt dort. Und wir haben Retro ein wenig Code hinzufügen, um zu definieren, was passiert, wenn wir diese Nachrichten während dieses Messaging-Schritts senden. In diesem Fall suchen wir nach Knoten, die nicht positiv unendlich sind,
einen, den wir gerade verarbeitet haben. Und für diejenigen, werden wir auf ihre Ziel-IDs,
ihre Nachbarn, lüften und entlang des Attributs dieses anfänglichen Knotens plus 1. Das wird also die Entfernungsanzahl erhöhen, während wir gehen und diese nächste Runde und Nachrichten für diesen Superstep senden. Also im Wesentlichen wird Pregel seinen Weg durch dieses Diagramm arbeiten und seinen Weg nach draußen fächern. Und auf dem Weg sucht es nach Knoten, die nicht unendlich sind. Und es geht voran und fächert diese weiter, erhöht die Distanz, wie es seinen Ausweg findet. So behandelt Pregel irgendwie viele von ihnen Mechanik der Durchquerung des Graphen für uns, was für so etwas praktisch ist. Jetzt werden Sie nicht zu aufhängen, wenn Sie dem nicht folgen, werden
Sie wahrscheinlich nie genau
diesen gleichen Algorithmus und die reale Welt tun müssen , richtig? Der größere Punkt hier ist jedoch, dass, wenn Sie
ein Diagramm von Informationen haben , die Sie in Spark verarbeiten müssen, und die integrierten Funktionen von Grafiken nicht tun, was Sie wollen. Manchmal lässt die Pregel-API Sie
es tun , wenn Sie nur ein wenig kreativer darüber nachdenken,
es ist nur ein weiteres Werkzeug, das Sie in Ihrer Werkzeugkiste haben können. Die andere Sache, die wir in BFS tun müssen, ist die minimale Entfernung bei jedem Schritt erhalten. Wir wollen also sicherstellen, dass wir nicht auf uns selbst zurückverfolgen und
diese irrtümlich hohen Entfernungen zwischen den
Knoten bekommen diese irrtümlich hohen Entfernungen zwischen den , weil wir diese längeren Pfade gefunden haben, um dorthin zu gelangen. So können wir ein Vertex-Programm schreiben, das darauf überprüft. Und es wird den minimalen Abstand zwischen dem, der empfängt, und dem, was es hat, bewahren. es also diese Nachrichten von seinen benachbarten Knoten empfängt und eine Entfernung erhält, Wennes also diese Nachrichten von seinen benachbarten Knoten empfängt und eine Entfernung erhält,die tatsächlich größer ist als das, was bereits drin ist, wird die kleinere dieser beiden Entfernungen beibehalten. Darüber hinaus machen wir auch eine Reduktion des Betriebs. Wenn wir also tatsächlich mehrere Nachrichten für denselben Scheitelpunkt im gleichen Durchgang erhalten haben, wird
das auch diesen Fall abfangen und den minimalen Abstand in diesem Fall beibehalten. Es ist also ziemlich unkompliziert, alles zusammenzufassen. Es ist nicht eine ganze Menge Code wirklich. So können wir einfach sagen, definieren Sie unsere anfängliche Grafik und Grafiken mit der Entfernung auf 0, wo wir anfangen, sonst ist es unendlich. Wir nennen dann anfängliche Graph Punkt Pregel. Und dieser eine Funktionsaufruf erlaubt es uns, alle Attribute von Partikeln zu definieren, die wir brauchen. Also übergeben wir in diesem Vertex-Programm, das behauptet, dass wir immer den minimalen Wert erhalten für die Entfernung dort beibehalten. Wir richten dieses Messaging-System ein, in dem wir sagen, dass wir nach
nicht-unendlichen Knoten suchen und Lüfter Wege aus ihnen sind, die diese Entfernung erhöhen, während wir gehen. Und schließlich haben wir diese Reduction-Operation , die besagt,
dass, wenn Sie mehr als eine Nachricht auf einmal eintreffen , wir werden die minimale Entfernung beibehalten, die hereinkommt. Also diese drei Komponenten von regulären übergeben als ein einzelner Funktionsaufruf an die Pregel-API dort. Wieder haben wir das Vertex-Programm. Zuerst haben wir die Messaging-Funktion, und dann haben wir die Reduce-Operation. Und das ist alles, was Sie tun müssen. Also lasst uns ausgehen und sehen, ob es funktioniert.
64. [Aktivität] Superhero mit GraphX: Lassen Sie uns also eintauchen und nutzen Sie die Kraft der Grafik und Pregel um unsere Grade der Trennung Problem mit Grafiken zu lösen. Also öffne hier das grafische Skript und wir werfen einen Blick. Mal sehen, was hier los ist. Es ist etwas einfacher als die RDD-basierte Implementierung, aber es gibt immer noch eine Menge Code, über den man hier sprechen muss, richtig? Also lasst uns es durchmachen. Also lasst uns zur Hauptfunktion springen und dort anfangen. Wir richten unseren Spark-Kontext ist Zeit. Denken Sie daran, dass GraphX immer noch auf der RDD-API basiert, daher verwenden wir hier keine SparkSession. Wir verwenden stattdessen einen SparkContext. Auch hier gibt es eine neue Version namens Graph-Frames in der Entwicklung, aber sie ist noch nicht wirklich offiziell veröffentlicht. Also wieder, Grafiken wenig vernachlässigt, aber Graph-Frames ist hoffentlich auf dem Weg. Grafiken sind jedoch immer noch nützlich und wie Sie sehen können, ist
es nicht so schwer zu verwenden. Also fangen wir an, indem wir hier die Marvel-Dashnamens-Datei einlesen, und wir rufen die Funktion „Parse Names“ hier mit einer FlatMap auf. Sie können sehen, dass hier alles los ist. So gibt ein Tupel der Vertex-ID zurück, die unsere Superhelden-ID ist, und eine Zeichenfolge, die dem Namen dieser ID entspricht. Nichts Schickes. Wir teilen es einfach basierend auf dem Anführungszeichen dort auf, um den Namen zu extrahieren. Und wenn wir mehr als ein Feld haben, machen
wir nur eine kleine Überprüfung der Daten dort. Wir schneiden dieses Anfangsfeld ab, um alle fremden Leerzeichen zu entfernen, die in eine lange Ganzzahl konvertiert werden. Und überprüfen Sie, ob es sich um eine gültige ID handelt. Wenn ja, geben wir diese ganze Zahl zusammen mit dem Namen des Helden zurück, der mit dieser ID verknüpft ist. Und wieder verwenden wir das Optionsformat hier, um zu sagen, dass keines ein gültiges Ergebnis ist. Indem wir also sum sagen, bedeutet
das, dass diese Funktion ein gültiges Ergebnis zurückgibt, aber wir können auch keines zurückgeben. Es könnte sein, dass diese Zeile eine ungültige Hero-ID oder falsch formatierte Daten darstellt. Und in diesem Fall, indem wir den Wert none als Teil unserer Option dort zurückgeben, sagt das FlatMap, dass wir diese Zeile einfach ignorieren wollen und
nichts zu der resultierenden RDD hinzufügen. Als Nächstes, was machen wir? Wir bauen unsere Kanten auf. Also, jetzt werden wir die Marvel-Dash Graph dot txt-Datei analysieren. Und wie Sie sich erinnern, ist das nur eine Liste von Zeilen, die eine hier ID haben, gefolgt von einer Liste aller IDs bei diesem Hero wurde mit im selben Comicbuch gesehen. So machen Kanten kümmert sich darum. Hier geht auch nicht viel vor sich. Grundsätzlich nehmen wir, dass die gesamte Eingabezeile eine Zeichenfolge ist und es gibt eine Liste von Kanten , die aus ganzen Zahlen besteht, die tatsächlichen Vertex-IDs für jeden Helden entsprechen. Also werden wir hier einen Listenpuffer aufbauen und diese Liste mit Kantenobjekten füllen. Das ist also im Grunde das Format, das Graph x von uns erwarten wird. Wir teilen diese rohe Eingabezeile in einzelne Felder auf. Und für jedes Feld, das wir haben, extrahieren
wir das erste, das unser Ursprung sein wird,
das, von dem wir reden. Und dann erstellen
wir für jedes nachfolgende Feld ein neues Kantenobjekt, das aus
der Scheitelpunkt-ID des Superhelden besteht , von dem wir beginnen, und der Scheitelpunkt-ID jeder Verbindung, die dieser Hero hat. Dann geben wir hier die resultierende Liste der Kanten zurück zu unserem Hauptskript. So können wir jetzt den Graph selbst aufbauen, was ziemlich einfach ist. Wir konstruieren nur ein neues Graph-Objekt, das ihm die Liste der Scheitelpunkte und Kanten, die wir angegeben haben, gibt. Und wir übergeben diese Scheitelpunkte nur als Tupel im Grunde, wo der erste Wert die Scheitelpunkt-ID ist. Das ist eine gültige Sache, hier zu tun. Das funktioniert einfach. Und wir haben die resultierende Grafik eingelöst, weil wir
vermutlich eine Menge Arbeit
mit diesem Diagramm machen werden und wir wollen das im Gedächtnis behalten. Wie wir in den Folien gesehen haben, können wir schnell
die Top 10 der am meisten verbundenen Superhelden mit
dieser eine Codezeile berechnen die Top 10 der am meisten verbundenen Superhelden mit , die wir gerade nennen graph doctor stimmt zu und die Verbindung mit der gesamten Liste der Scheitelpunkte,
was bedeutet, dass wir erhalten Sie die Verbindungen für jeden Stützpunkt, den wir kennen, und sortieren Sie die resultierenden Ergebnisse nach dem Feld, das der Anzahl der Verbindungen entspricht. Nimm die Top 10, drucke sie aus, das war's. Und jetzt können wir tatsächlich Breitensuche mit Pregel durchführen, was eigentlich nicht so schwer ist. Also beginnen wir damit, die ID unseres Wurzelvertex hier zu definieren. Also wissen wir zufällig, dass die Scheitelpunkt-ID 5306 Spider-Man entspricht. Und wir können durch die Berechnung der Entfernungen zu iterieren, wenn jeder zu Spiderman. Jetzt beginnen wir mit der Initialisierung des Graphen. Auch hier machen wir nur eine Map Scheitelpunkte Operation, überprüfen jeden Scheitelpunkt und sehen, ob die ID gleich Spiderman ist. Wenn ja, setzen wir den Anfangsabstand auf 0, andernfalls setzen wir ihn auf unendlich. Und jetzt
haben wir in diesem einen Befehl die ganze Pregel-Welt aufgebaut, wenn Sie so wollen. Wir nennen anfängliche Graph Punkt Pregel und wir übergeben in dieser Funktion, die
vor allem unser Vertex-Programm enthält . Also wieder, es ist Zweck im Leben nur, den minimalen Abstand beizubehalten wenn Nachrichten zwischen
der eingehenden Nachricht und dem aktuellen Wert eines bestimmten Knotens empfangen werden. Wir definieren auch unsere SendMessage, wie wir zuvor gesprochen haben. Das wird sich auf alle Nachbarn ausbreiten, wobei die Entfernung um eins erhöht wird. Also für jeden Knoten, der eine aktuelle Entfernung mit ihm verbunden ist, fanden
wir uns heraus, dass wir diese Entfernung inkrementieren, während wir gehen. Und schließlich definieren wir eine Reduce-Operation, die den Mindestwert der Nachrichten,
die von einem Scheitelpunkt empfangen werden, beibehalten wird , wenn mehrere Nachrichten von einem Scheitelpunkt im gleichen Durchgang empfangen werden. Also haben wir hier zwei verschiedene Bits, die enthalten können, dass wir immer
diese kürzeste Entfernung beibehalten , auf die wir stoßen, wenn wir den Graphen durchqueren. Und dieses kleine Snippet definiert hier, wie wir
den Graphen durchlaufen und diesen Abstand mit jedem Durchgang um eins erhöhen. An diesem Punkt können wir gehen und einfach die Top 100 Ergebnisse dort ausdrucken. Wir können sagen, BFS Punkt Scheitelpunkte, Punkt verbinden Verts wieder, nur sagen, dass wir dieses Diagramm auf allen unseren Superhelden bewerten wollen. Nimm die Top 100 und drucke sie aus und wir werden sehen, wie es aussieht. Und wenn wir gezielt die Ergebnisse unserer Grade der
Trennung Übung, die wir verwenden, um RDDs ohne Grafik zu verwenden, neu erstellen wollen , können
wir dort einfach eine kleine Filteroperation durchführen
, um das Ergebnis für Superhelden-ID 14, das ist das Zeichenatom 3,031 und drucken Sie diese Zeile speziell aus. Also lasst uns das loslegen und sehen, ob es funktioniert. Grafiken werden ausgeführt. Und was cool ist, ist, dass es auch ziemlich schnell ist. Wenn es losgeht, sollten wir überhaupt nicht zu lange warten müssen. Ab geht es. Und wir haben unsere Top 10 am meisten verbunden und wir haben unsere Grade der Trennung. Also, wenn ich mich richtig erinnere, ist
das viel schneller als unsere Implementierung, nur mit geradliniger RDD. GraphX macht offensichtlich einige ziemlich coole Optimierungen. Sie sind auch unter der Haube. Lassen Sie uns unsere Ergebnisse überprüfen, stellen Sie sicher, dass sie sinnvoll sind. Also werde ich nach oben scrollen. Top 10 am meisten mit dem Top-Ergebnis verbunden ist immer noch Captain America. Das haben wir früher im Kurs gesehen. So dass überprüft und Grad der Trennung von Spiderman für alle. Interessanterweise ist es ein oder zwei für jeden. Ich denke. Sie wissen, dass die Legende, dass alle mit Kevin Bacon in Verbindung stehen, wahrscheinlich wahr ist, oder? Oh, sieht so aus, als wäre Boom eigentlich ziemlich weit drei gehabt. Er ist dunkler. Noch obskurer als Adam, 3.031, der wieder als zwei Grade der Trennung von Spiderman zurückkommt. Auch das gleiche Ergebnis haben wir vorher bekommen. Das ist also ziemlich aufregend. Wir haben tatsächlich das gleiche Ergebnis. Es funktioniert. Und das ist ein bisschen mehr eine prinzipielle und unkomplizierte Art , diesen Diagrammbetrieb für Trenngrade mit GraphX und der Pregel-API zu
berechnen. Und damit haben wir alle Kernkomponenten von Spark abgedeckt. Herzlichen Glückwunsch, mit GraphX wickeln wir die Dinge ein. Also lassen Sie uns darüber reden, wohin wir von hier aus gehen sollen.