• Geeks' Blog

Odczyt i zapis danych podczas uruchamiania zadań Apache Spark w środowisku Kubernetes

Jeśli chcemy analizować dane w Apache Spark w środowisku Kubernetes musimy zadbać o odczyt danych i zapis rezultatu po wykonaniu zadania. Tego problemu nie ma kiedy używamy Apache Spark w formie Standalone i mamy tylko jeden worker; możemy odczytywać dane i je zapisywać na dysk bez dbałości o widoczność tego zaspobu przez wiele executorów Sparka.

Kiedy Apache Spark działa w klastrze 'standalone' i uruchamianych jest wiele workerów, najczęstszy scenariusz to kopiowanie danych do analiz na każdą maszynę workera i zapisywanie rezultatów na każdej z maszyn a po wykonanej pracy ich 'merge' z workerów do finalnego rezultatu. Wbrew powszechnemu marketingowi, Apache Spark nie pracuje najcześciej z danymi RAW/BRONZE czy SILVER na setkach Terrabajtów czy na Petabajtach danych. Najczęściej takie dane są dzielone i workery otrzymują tylko część danych lub danych w oknie czasowym jest stosunkowo niewiele. Dopiero zadania na danych GOLD wykonywane są na dużych wolumenach danych.

Pody Apache Spark w Kubernetes są tworzone dynamicznie i przestają istnieć po wykonaniu zadania. Dystrybuowanie do nich danych i ich zapis byłby problematyczne. Teoretycznie raczej mamy dwa scenariusze:

  • Dane lokalne w podzie – każdy pod widzi tylko swój lokalny filesystem. Mówimy tylko o zapisie danych do lokalnego poda bo skoro pod tworzony jest dynamicznie, problematyczne jest przesłanie do niego danych.
  • Sieciowy PersistentVolume (PV, PVC, ReadWriteMany, np. NFS, Ceph, EFS) – wszystkie pody (driver + executory) montują ten sam katalog, dane są widoczne wszędzie; Spark może odczytywać i zapisywać równolegle. Dane przesyła się po prostu zapisując je w PV; można też wstępnie wrzucić pliki do PV przed startem joba.

Oba scenariusze są trudne w produkcyjnym wykorzystaniu. Wskazane jest by wszystkie workery widziały ten sam zasób który jednocześnie jest łatwy do zarządzania. Dlatego używamy trzeciego rozwiązania:

  • Obiektowy storage (S3, GCS, Azure Blob) – wszystkie pody mają dostęp przez protokoły S3/HTTP, Spark odczytuje i zapisuje dane w formacie np. Parquet, CSV; dane przesyła się do bucketu przed startem joba, np. aws s3 cp /local/path s3://bucket/input.

Amazon Simple Storage Service (Amazon S3) lokalnie

Najprostszym, nie najbardziej wydajnym, jest używanie usługi która wykorzystuje właśnie S3 (protokół s3, s3a). Dzięki https://www.min.io/ taki serwis możesz mieć lokalnie. Oprogramownie jest proste do instalacji. Oprogramowanie udostępnia tę sama funkcjonalność która daje chmura AWS - za darmo. Istnieje też wersja bardziej rozbudowana, komercyjna oraz, a jakże, chmura MinIO.

Firma MinIO zrobiła co prawda klasyczny open-core shift i usuneła wiele funkcji ostatnio ze swojej darmowej wersji oprogramowania. I tak by zarządzać uprawnieniami potrzebny jest client który pobierzesz tutaj. Jednak do jeśli potrzebujesz serwisu S3 do stosunkowo niewielkich volumenów danych, MinIO jest wszystkim czego potrzebujesz. Możliwa jest także budowa trybu rozproszonego (distributed mode) w MinIO Community.

Więcej…

Jak działa Apache Spark w środowisku Kubernetes - uruchamianie zadań

W realnym, produkcyjnym scenariuszu użycia Spark w klastrze nie rezyduje on tam na stałe. Jego komponenty są instalowane dynamicznie wraz ze zlecaniem zadania i są usuwane po wykonaniu pracy.

Polecenie spark-submit jest używane do przesłania aplikacji (zadań) Spark do klastra Kubernetes. Wymagana ne jest byś miał(a) oprogramownie Spark lokalnie - twój lokalny Spark jest klientem.
Mechanizm przesyłania działa w następujący sposób:

  1. Spark tworzy proces drivera (Spark driver), który uruchamia się wewnątrz poda Kubernetes.

  2. Driver tworzy procesy executorów, które również działają jako pody w Kubernetes, łączy się z nimi i wykonuje kod aplikacji.

  3. Gdy aplikacja zakończy działanie, pody executorów są zatrzymywane i usuwane, natomiast pod drivera zachowuje logi i pozostaje w stanie „completed” (zakończony) w API Kubernetes, dopóki nie zostanie usunięty ręcznie lub przez mechanizm automatycznego czyszczenia (garbage collection).

Należy zauważyć, że w stanie „completed” pod drivera nie zużywa żadnych zasobów obliczeniowych ani pamięci.

Więcej…

Integracja Git[Gitea] z Apache Airflow: Publikowanie i Zarządzanie DAG-ami

Apache Airflow przechowuje DAGi w katalogu 'dags'. Dokładną scieżkę do tego katalogu znajdziesz w pliku konfiguracyjnym Airflow. 

[core]
dags_folder = /opt/airflow/dags

Może się zdarzyć, że po instalacji ten katalog nie zostanie automatycznie utworzony - musisz go stworzyć. W najprostszym scenariuszu, publikacja nowego workflow (Dag) polega na umieszczeniu pliku w tym katalogu. Niestety ale Apache Airflow nie umożliwia publikacji z poziomu webowego GUI. W środowisku produkcyjnym takie zarządznie plikami DAGów byłoby jednak uciążliwe, dlatego lepszym pomysłem jest wykorzystanie systemu Git. Git jest jednym z przykładów oprogramowania z klasy „rozproszonych systemów kontroli wersji” (Distributed Version Control Systems, DVCS). 

Jeśli chcesz korzystać z systemu kontroli wersji, nie musisz ograniczać się do GitHub. Gitea, GitHub czy GitLab to serwery i GUI dla Git-a — korzystają z tych samych protokołów (SSH/HTTPS) i wywołują natywne komendy Git w tle, oferując interfejs webowy, zarządzanie użytkownikami, pull requesty i CI/CD, ale same nie zastępują Git-a. Dla naszych testów użyjemy lokalnego servera Git; Gitea.

Przygotowanie repozytorium w Gitea

W poniższych przykładach używać będziemy lokalnego serwera Gita zainstalowanego w środowisku WSL. Wcześniej jednak musimy zainstalować pakiet Git w środowisku WSL:

sudo apt update
sudo apt install git -y

Następnie tworzymy katalog (i podkatalogi) w którym będzie zainstalowana Gitea i nadajemy uprawnienia:

sudo mkdir -p /opt/gitea/{custom,data,log}
sudo chown -R $USER:$USER /opt/gitea
chmod -R 750 /opt/gitea

Teraz pobieramy binarkę ze strony Gitea, nadajemy plikowi prawo wykonywania i przenosimy go do docelowego katalogu:

wget -O gitea https://dl.gitea.io/gitea/1.24.6/gitea-1.24.6-linux-amd64
chmod +x gitea
sudo mv gitea /opt/gitea/

Tworzymy skrypt startujący Gitea; plik opt/gitea/start_gitea.sh:

#!/bin/bash
# -----------------------------
# Start Gitea in WSL
# -----------------------------

# Ścieżki
GITEA_BIN=/opt/gitea/gitea
GITEA_CUSTOM=/opt/gitea/custom
GITEA_WORK_DIR=/opt/gitea/data
LOG_DIR=/opt/gitea/logs
mkdir -p $LOG_DIR

# Funkcja uruchamia proces w tle jeśli nie działa
run_if_not_running() {
    local name=$1
    local cmd=$2
    if pgrep -f "$cmd" > /dev/null; then
        echo "$name is already running."
    else
        echo "Starting $name..."
        nohup $cmd > $LOG_DIR/${name}_$(date +%Y%m%d_%H%M%S).log 2>&1 &
    fi
}

# Eksport zmiennych środowiskowych
export GITEA_CUSTOM
export GITEA_WORK_DIR

# Start Gitea webserver
run_if_not_running "gitea-web" "$GITEA_BIN web --port 3000"
echo "Gitea startup script finished. Web UI: http://localhost:3000"

Za każdym razem kiedy będzie startować WSL, będzie uruchamiana Gitea - dodajemy więc komendę wykonującą ten plik do pliku bashrc:

nano ~/.bashrc
/opt/gitea/start_gite.sh

Więcej…

Czym są pliki w formacie Apache Parquet

Apache Parquet to format plików danych typu open source, zorientowany na kolumny, zaprojektowany z myślą o efektywnym przechowywaniu i pobieraniu danych. Oferuje wydajne schematy kompresji i kodowania, umożliwiające obsługę złożonych danych w dużych ilościach i jest obsługiwany przez wiele języków programowania oraz narzędzi analitycznych. Pełny opis formatu parquet oraz dokumentacja znajduje sie na stronie https://parquet.apache.org/

Czym się różni format CSV of formatu Parquet?

Główna różnica między plikami Parquet a CSV polega na sposobie przechowywania danych i efektywności: CSV to tekstowy format wierszowy, łatwy do odczytu przez człowieka, ale wolny przy dużych plikach, bez typów danych i zwykle większy.

Parquet to binarny format kolumnowy, wspierający kompresję i typy danych, umożliwiający szybki odczyt tylko potrzebnych kolumn i bardziej wydajny przy analizie dużych zbiorów danych.

CSV

Plik zwykle zaczyna się od nagłówka (pierwszego wiersza z nazwami kolumn), a kolejne wiersze zawierają dane, gdzie kolumny są oddzielone określonym separatorem, najczęściej przecinkiem, czasem średnikiem lub tabulatorem. Nagłówek nie jest obowiązkowy - dodawany jest tylko ze względu na łatwiejszy odczyt pliku. Oto przykład pliku tekstowego, CSV:

Parquet

Plik Parquet ma strukturę kolumnową i binarną: zamiast wierszy z separatorami, dane każdej kolumny są przechowywane razem w tzw. column chunks, a wiele takich bloków tworzy row groups. Plik zawiera także metadane opisujące schemat danych i typy kolumn, co umożliwia szybki odczyt wybranych kolumn. Nie ma tradycyjnego nagłówka ani separatorów – kolejność elementów w kolumnach odpowiada wierszom, dzięki czemu system wie, które wartości z różnych kolumn tworzą razem wiersz. Z naszego CSV powyżej powstały trzy kolumny.

Ale to nie wszystko. Dane są dzielone na tak zwane 'row groups' - bloki wierszy (np. po 50 tysięcy wierszy). Każdy taki zestaw wierszy zawiera 'chunki' (bloki kolumn) w których przechowywane są dane kolumn. Dane w plikach Parquet dzieli się na row groups, żeby szybciej wczytywać tylko potrzebne fragmenty, lepiej kompresować dane, przetwarzać je równolegle i efektywnie zarządzać pamięcią. Gdybyśmy mieli dwie row groups dla informacji z naszego CSV, jedna przechowywałaby pierwsze dwa wiersze a druga dwa następne:

Więcej…

Strona 1 z 29

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
© 2025
Powered by DataGeeks & Human Intelligence