Colab zaiskrzył podczas instalacji Apache Sparka

wpis w: Apache, Big Data, chmura, migawka, Python, Spark | 2

Jednym z podstawowych problemów młodego adepta sztuki torturowania danych i  analizy dużych zbiorów jest spory próg wejścia.  Gdzie się tego można nauczyć ?  Jednym z bardziej znanych narzędzi jest Apache Spark. Okazuje się, że  uruchomienie tego oprogramowania  w usłudze Google Colab jest banalne. Systemem operacyjnych z jakiego korzystamy jest Ubuntu 18.04. Oczywiście taka konfiguracja nie umożliwi nam przetworzenia ogromnych ilości danych, ale pozwoli na rozpoznanie narzędzi, podstawowych  pojęć i zbudowania nowych kompetencji.

 

Po uruchomieniu notatnika  w języku Python 3.

W pierwszej komórce wklejamy

Ściągnięty w ten sposób plik instalacyjny zawiera zaledwie kilka linii kodu

 

Instalujemy JDK dla Javy 1.8, następnie ściągamy z repozytorium Apache Sparka w postaci pliku .tgz, rozpakowujemy zawartość i ustawiamy dwie zmienne środowiskowe.

Uruchamiany skrypt instalacyjny

Nadeszła pora na uruchomienie przykładowego kawałka kodu

Najpierw uruchamiamy sesję Sparka

Na wyjściu:

Potem uruchamiamy kontekst Sparka.

Na wyjściu:

Musimy mieć świadomość, że każda zmiana kodu, instalacja danych, zastosowane algorytmy są uruchamiane na klastrze obliczeniowym. Dostęp do infrastruktury jest za pomocą kontekstu Sparka. Patrząc z wysokiego poziomu, każda aplikacja Sparka, składa się z programu sterownika, który uruchamia na klastrze różne równoległe procesy.Program sterownika ma  dostęp do Sparka przez obiektu kontekstowy (SparkContext). Mająć dostęp do kontekstu mamy już możliwość budowy obiektów zawierających dane, które początkowo mogą się nam wydawać jako zwykłe i znane z Pythona struktury danych. Nic bardziej mylnego, obiekty znane jako  Resilent Distributed Datasets (RDD) lub DataFrame (DF) są umieszczane równolegle na wielu węzłach zwanych  wykonawcami (worker node).

Na RDD będziemy wykonywać różne metody, które dzielimy na transformacje i akcje. Transformacje przekształcają nam RDD w inne RDD, zaś akcje generują z RDD wynik który może być zwrócony do sterownika bądź zapisany w HDFS’ie lub innym obsługiwanym źródle danych. Wszystkie transformacje są leniwe (lazy), co oznacza , będą wykonane wyłącznie wtedy, gdy będzie to konieczne. Zamiast manipulacji danymi mamy tu jedynie rejestrację metadanych, które pozwalają na zbudowanie RDD.

Na wyjściu:

Wczytajmy nasz plik jaka ramkę danych (dataframe)

Sprawdźmy jaka jest struktura tych danych.

Na wyjściu:

Zróbmy kilka przykładów z zastosowanie RDD.

Utwórzmy pierwszy obiekt RDD o nazwie rdd-1, do którego załadowaliśmy listę składającą się z 10 cyfr. To prosty obiekt, ale na jego podstawie pokażę podstawowe transformacje i akcje.  Utworzenie obiektu z danych wewnętrznych (nie z plików) umożliwia nam funkcja parallelize.

Na wyjściu:

Pierwszą transformację, którą można zrobić jest map.

Map bierze każdy element zbioru RDD jako element wejściowy przekształca go za pomocą funkcji w element wyjściowy. W poniższym przykładzie przemnożyliśmy elementy przez liczbę dwa. Dla osób, które nie znają składni lambda, mamy tu do czynienia z budową funkcji która przekształca element wejściowy na element wejściowy. Nie wiemy jaki jest typ elementu wejściowego, nie musi to być  typ skalarny. Nie ma potrzeby budowania tego w postaci def + ciało funkcji. Składnia wygląda w uproszczeniu tak lambda wejscie: wyjscie, gdzie wyjście zawiera algorytm.  Myślę, ze po kilku poniższych przykładach stanie się to bardziej czytelne.

Na wyjściu:

Wykonajmy akcję collect na obu zbiorach, dzięki czemu będzie można zobaczyć ich zawartość. Uwaga, nie należy stosować tej akcji na bardzo dużych zbiorach danych, gdyż mogą się one nie zmieścić w lokalnej pamięci. Akcje powinny być wykonywane tylko kiedy są konieczne (!).

Na wyjściu:

Następną transformację, z której możemy skorzystać jest flatMap.

Funkcja  dla każdego elementu na wejściu zwraca kolekcję elementów, w tym przypadku rozkładamy każdy z napisów na wyrazy przyjmująć spację jako separator.

Na wyjściu:

Kolejną transformacją jest operacja filtrowania filter, która tworzy podzbiór spełniający warunki funkcji lambda zwracącej tylko wartości logiczne. W naszym przypadku wymagamy, by element był mniejszy od sześciu

Na wyjściu:

Kolejna transformacja o nazwie distinct umożliwia usunięcie zduplikowanych wartości w zbiorze.

Na wyjściu:

Jak wydać podwójne liczby dwa, cztery, osiem i potrójna dziewięć zostały zredukowane do jednego wystąpienia..

Istnieje możliwość utworzenia mniejszego zbioru danych za pomocą transformacji sample, która przyjmuje trzy argumenty

(czy zastępować, ułamek liczby elementów w zbiorze wyjściowym/wejściowym, ziarno dla generatora liczb pseudolosowych)

Na wyjściu.

Ustawienie ziarna na 123 oznacza, że z tego samego zbioru wejściowego zostanie wylosowany za każdym razem taki sam zbiór wyjściowy. Należy o tym pamiętać.

 

Wszystkie powyższe przykłady dotyczyły jednego zbioru RDD.

Utwórzmy dwa zbiory rdd_1 i  rdd_2. Elementy w nich mogą się pokrywać. Transformacja union umożliwia utworzenie nowego obiektu zawierającego ich sumę.

Składnia wygląda następująco  rdd_wy_wyjsciu=rdd_pierwsze.union(rdd_drugie)

W posobny sposób można skorzystać z operacji intersetion (część wspólna), substract (różnica, czyli elementy, które są w pierwszym obiekcie, a nie ma ich w drugim), cartesian (iloczyn kartezjański). Składnia poleceń jest analogiczna jak dla union.

Na wyjściu:

Nadeszła pora na prezentację kilku akcji.

Akcja reduce umożliwia zamianę wielu elementów zbioru na jeden. W naszym przykładzie  jest to mnożenie

Na wyjściu:

Istnieje też możliwość prostego przemnożenia przez stałą wartość. Umożliwia to operacja fold, której pierwszym elementem jest wartość przez którą będzie przemnożony wynik.

Na wyjściu:

Ten sam kod, ale zamiast zera zastosowaliśmy wartość minus jeden.

Na wyjściu:

Na koniec zostawię dwie akcje count oraz take.

 

Akcja count zwraca liczbę elementów danego obiektu RDD.

Na wyjściu:

Akcja take zwraca pierwszych x elementów z obiektu RDD. W naszym przypadku  jest to liczba dziesięć.

Na wyjściu:

 

Pokazałem jedynie kilka przykładów wykorzystujących stos technologiczny Apache Sparka. Środowisko Colab można wykorzystać jednak jeszcze efektywniej korzystając z SSH i VNC. Wtedy istnieje możliwość uruchamiania gotowych skryptów i kontroli przy wykorzystaniu Spark GUI i  prosty podgląd obiektów

 

O tym będzie kolejny wpis, gdzie spróbujemy przeanalizować pracę nad dużym zbiorem.

 

Przykłady umieściłem w repozytorium w postaci pliku .ipynb

https://github.com/djkormo/colab-examples/blob/master/spark/Colab_apache_spark_intro_primer.ipynb

 

Literatura:

 

Install Apache Spark on Ubuntu 19.04/18.04 & Debian 10/9/8

https://towardsdatascience.com/how-to-use-pyspark-on-your-computer-9c7180075617

https://www.tutorialspoint.com/pyspark/pyspark_sparkcontext.htm

https://runawayhorse001.github.io/LearningApacheSpark/pyspark.pdf

2 Responses

  1. Tomasz Cieplak

    Kolejny świetny artykuł. Uruchomienie Apache Spark na maszynie lokalnej wymaga sporo przygotowań. A tutaj mamy bardzo pomocny przepis na to jak zacząć, pracować i uczyć się Sparka bez walki z całym otoczeniem. A do tego jeszcze Jupyter i Pyhon3. A co będzie dalej? Spark i GPU na platformie Google Colab? Już nie mogę się doczekać!

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *