Jak wykorzystałem Apache Spark i Docker w Hackathonie do zbudowania aplikacji pogodowej?
Opublikowany: 2022-03-11W dwóch moich poprzednich artykułach przedstawiłem publiczności Apache Spark i Docker. Nadszedł czas, kiedy pokazałem Wam w pełni funkcjonalną aplikację zawierającą obie wyżej wymienione technologie.
Motywacja „spadła z nieba w postaci danych” i została wywołana hackathonem zorganizowanym przez IBM. Celem Sparkathona było wykorzystanie danych pogodowych i Analytics for Apache Spark dla IBM Bluemix do tworzenia aplikacji mobilnych związanych z pogodą.
IBM intensywnie inwestuje w Spark, a ostatnio kupił cyfrową część The Weather Channel. W konsekwencji to wydarzenie wydaje się idealne dla ich rozgłosu.
Inspiracja
Czy kiedykolwiek narzekałeś na pogodę w swojej lokalizacji, miałeś zaplanowany czas wolny i pieniądze do wydania, ale nie wiedziałeś, gdzie się udać? Jeśli odpowiedź brzmi „tak”, to naprawdę polubisz aplikację My Perfect Weather .
Aby zilustrować, w jaki sposób aplikacja może być używana, oto kilka przypadków użycia:
- Masz dziecko, z którym obiecałeś latać z latawcem w tym tygodniu, ale w twoim miejscu jest absolutnie bezwietrznie i nie chcesz łamać słowa.
- Mieszkasz w wietrznym i deszczowym miejscu, tak jak ja (Edynburg, Szkocja) i chcesz poczuć ciepło na swojej skórze i zdecydowanie bez deszczu.
- Masz ochotę ulepić bałwana i nie spoczniesz, dopóki go nie spełnisz.
- Chcesz łowić ryby, a tym razem naprawdę chcesz coś złowić.
Co to robi
Idea serwisu jest bardzo prosta. Najpierw określasz, co w danym momencie oznacza dla Ciebie idealna pogoda. Obecnie możesz filtrować według temperatury, prędkości wiatru, rodzaju opadów i prawdopodobieństwa opadów, jak pokazano na zrzucie ekranu poniżej. Następnie usługa zajmie się resztą i otrzymasz najlepiej pasujące miejsca docelowe. Wyniki są sortowane według liczby idealnych dni, pasujących do oryginalnego zapytania, znalezionych dla każdego miasta i ograniczone do pięciu najlepszych. Idealne dni są również oznaczone innym tłem.
Zobaczmy, jak możemy wykorzystać usługę w przypadkach użycia zdefiniowanych w poprzedniej sekcji.
- Ustaw wiatr od 16 do 32 km/h, idealny do latania latawcem, z małą szansą na deszcz i komfortową temperaturą.
- Ustaw minimalną temperaturę, aby była wystarczająco ciepła, ustaw szansę na deszcz na 0%.
- Ustaw temperaturę na około 0 C i poniżej, wybierz śnieg jako rodzaj opadów i prawdopodobieństwo, że opady będą wysokie.
- Ustaw prędkość wiatru na mniej niż 16 km/h, trochę deszczu i chmur, ponieważ chcesz uniknąć zbytniego słońca i zanurzyć ryby głębiej w wodzie, w komfortowej temperaturze.
Jeśli chcesz, możesz łatwo sprawdzić, jak dojechać do wybranego miejsca, ponieważ aplikacja jest zintegrowana z wyszukiwarką turystyczną Momondo.
Jak to zbudowałem
Zasadniczo wszystko oprócz zewnętrznej usługi wyszukiwania podróży działa na platformie IBM Bluemix.
IBM zaoferował bezpłatną wersję próbną wszystkim uczestnikom hackathonu, więc nie musiałem się martwić, gdzie uruchomić aplikację.
Zobaczmy, jak przepływają dane w aplikacji i jak łączą się ze sobą komponenty przedstawione na diagramie architektury.
Aplikacja Play jest hostowana w kontenerze Docker. Jedna z jego usług umożliwia kontakt z serwisem pogodowym i pobieranie 10-dniowej prognozy do Cloudant. W kroku następującym po pobraniu Spark odczytuje surowe dane pogodowe z Cloudant, przetwarza je i przechowuje z powrotem w Cloudant, aby uzyskać szybki i łatwy dostęp do aplikacji Play.
Gdy użytkownicy przechodzą do strony głównej aplikacji, otrzymują formularz zawierający różne elementy sterujące, aby określić idealną pogodę. Ich dane wejściowe są przesyłane do backendu, który wysyła zapytanie do Cloudant o miasta zawierające idealne dni. Następnie wykonywane jest kolejne zapytanie dla wszystkich dziesięciu dni prognozy dla miast zwróconych w poprzednim zapytaniu. Uzyskane wyniki są prezentowane użytkownikom, a komórki reprezentują warunki pogodowe na miasto na dzień. Ostatnia komórka dla każdego miasta zawiera link do usługi turystycznej. Kliknięcie go przeniesie użytkowników do witryny Momondo, a formularz wyszukiwania lotów zostanie wstępnie wypełniony informacjami o miejscu docelowym i datach podróży. Jeśli użytkownik korzystał już wcześniej z usługi (i zapisał plik cookie w swojej przeglądarce), pochodzenie i liczba podróżnych mogą być również wstępnie wypełnione. Oczywiście pola w tym formularzu można zmienić. Na przykład można wypróbować różne daty podróży w poszukiwaniu lepszej taryfy.
W ten sposób zbudowana jest aplikacja. Poniższe sekcje zawierają więcej szczegółów na temat niektórych składników.
Spark i wgląd w pogodę
Pierwsza faza projektu została poświęcona na ustalenie, jak działa Weather API i inne usługi Bluemix, a następnie nastąpiła wstępna eksploracja danych pogodowych za pomocą Sparka. Pozwoliło mi to zrozumieć, jak działa model danych i jak można go wykorzystać w aplikacji.
Na potrzeby tej aplikacji używany jest tylko pierwszy z następujących punktów końcowych interfejsu Weather REST API:
GET /v2/forecast/daily/10day - Weather Standard 10-day Daily Forecast GET /v2/forecast/hourly/24hour - Weather Standard Hourly Forecast GET /v2/observations/current - Current Weather Observation GET /v2/observations/timeseries/24hour - Time-Series Observation
Punkt końcowy jest pytany o prognozę pogody dla każdego interesującego miasta, dostarczając parametr geokodu , który bierze pod uwagę szerokość i długość geograficzną danego miejsca.
Ze względu na charakter usługi, liczba zapytań kierowanych do Weather API jest skorelowana z liczbą obsługiwanych miast. Rozważyłem limit bezpłatnego poziomu usługi Insights for Weather Service, który wynosił 500 połączeń dziennie i zdecydowałem, że w celach demonstracyjnych skorzystam z bezpiecznej liczby pięćdziesięciu miast turystycznych w Europie. Dzięki temu mogę wykonywać kilka wywołań dziennie dla każdego miasta i obsługiwać nieudane żądania bez ryzyka utraty prawa do korzystania z API. Musiałbym zacząć płacić, aby mieć wystarczającą liczbę wniosków, aby objąć większość miast świata.

Ostatecznym celem projektu byłoby pomnożenie danych pogodowych Sparka dla wszystkich miast na świecie (~50 000) przez dziesięć dni danych prognozy i wykonanie tego kilka razy dziennie, aby prognozy były jak najdokładniejsze.
Cały kod Spark znajduje się w notatniku Jupyter. Jak dotąd nie ma innego sposobu wykonywania zadań Spark. Surowe dane pogodowe są odczytywane z Cloudant DB, przetwarzane i zapisywane z powrotem.
Baza danych Cloudant NoSQL
Krótko mówiąc, praca z Cloudant NoSQL DB była dla mnie bardzo przyjemna. Jest łatwy w użyciu i ma dobry interfejs użytkownika oparty na przeglądarce. Nie ma sterownika jako takiego, ale ma prosty interfejs API REST i można z nim łatwo współpracować za pośrednictwem protokołu HTTP.
Jednak Bluemix Spark zawiera interfejs API Cloudant Data Sources, którego można używać do odczytu i zapisu w Cloudant bez konieczności wykonywania wywołań niskiego poziomu. Warto zaznaczyć, że nie ma możliwości stworzenia nowej bazy danych w Cloudant od Sparka, więc trzeba ją wcześniej utworzyć np. za pomocą webowego UI.
Play Framework
Aplikacja internetowa jest napisana w Scali. To bardzo proste. Kontroler obsługuje jednostronicową aplikację z AngularJS i Bootstrap, a usługa współdziała z Weather API i Cloudant.
Jedno ciekawe wyzwanie, z którym się zmierzyłem, jest bezpośrednio związane z IBM Container Service. Moim zamiarem było uruchomienie aplikacji na porcie 80, aby była przyjazna dla użytkownika. Jednak nie mogłem znaleźć żadnego sposobu w Bluemix, aby użyć przekierowania portów Docker i mapować zewnętrzny port 80 na wewnętrzny port Docker 9000 aplikacji Play. Moje obejście polegało na uruchomieniu jako root wewnątrz kontenera (nie jest to zalecana praktyka) i edytowaniu pliku application.conf Play:
# Production port play.server.http.port = "80"
Doker
Docker bardzo się przydał, zwłaszcza w momencie wdrożenia do Bluemix. Nie musiałem mieć żadnej wiedzy na temat aplikacji Cloud Foundry, martwić się o pakiety buildów Scali ani cokolwiek innego. Mógłbym po prostu popchnąć obraz Dockera i zobaczyć, jak działa.
Do stworzenia obrazu Dockera użyłem wtyczki Typesafe Docker, więc nie potrzebowałem nawet odpowiedniego pliku Dockerfile.
Wystarczy kilka poleceń, aby aplikacja działała w chmurze po krótkiej wstępnej konfiguracji:
# log in to IBM Bluemix cf login cf ic login # create the image locally sbt docker:publishLocal # rename it docker tag -f my-perfect-weather:1.0-SNAPSHOT registry.ng.bluemix.net/radek1st/my-perfect-weather:1.0 # push it docker push registry.ng.bluemix.net/radek1st/my-perfect-weather:1.0 # and run it cf ic run --name my-perfect-weather -p 80 -m 2048 registry.ng.bluemix.net/radek1st/my-perfect-weather:1.0
Warto zauważyć, że usługa Bluemix Container Service przeprowadza ocenę podatności obrazów przed ich uruchomieniem. Mimo że nie miało to sensu dla mojej aplikacji, nadal musiałem załatać /etc/login.defs
obrazu nadrzędnego, aby można go było uruchomić. Oto plik Dockerfile, jeśli jesteś zainteresowany.
Wyzwania, na które natknąłem się
Ponieważ Spark jest wciąż dość świeżym dodatkiem do IBM Bluemix, ma pewne ograniczenia. Obecnie kod można wykonać tylko jako część notatnika, więc nie ma możliwości zaplanowania przebiegów. To było nie lada odkrycie pod koniec mojego czasu na hackathon. Dla My Perfect Weather oznacza to, że prezentowane dni pogodowe będą powoli tracić aktualność, jeśli notebook Spark nie zostanie ponownie uruchomiony ręcznie . Mam nadzieję, że IBM szybko zajmie się tym problemem.
Natknąłem się również na małą nieścisłość w dokumentacji Insights for Weather API, która pojawiła się po zauważeniu pewnych problemów z wyświetlanymi wynikami. Dla typu opadów jedynymi spodziewanymi wartościami były deszcz i śnieg , ale znalazłem również trzecią wartość precypu . Z kontekstu pogodowego zdaje się wskazywać deszcz ze śniegiem, więc dla uproszczenia aplikacji jest traktowany jako śnieg.
Osiągnięcia, z których jestem dumny
Myślę, że My Perfect Weather to całkiem fajny pomysł i jestem dumny, że mogłem go bardzo szybko wdrożyć, łącząc te wszystkie technologie. Mimo wszystko jest to hack, z wieloma luźnymi końcami, ale najważniejsze jest to, że działa!
Czego się nauczyłem
Podczas tego krótkiego projektu nauczyłem się całkiem sporo. Byłem nowy w IBM Bluemix, więc była to przygoda sama w sobie.
Nigdy wcześniej nie słyszałem o Cloudant DB, ale z pewnym doświadczeniem z MongoDB przejście było dość łatwe.
Dowiedziałem się też, że nie powinienem pracować nad frontendem. W głębi serca jestem programistą backendowym, bez talentu do robienia rzeczy ładnie wyglądających, więc praca z Bootstrap i CSS była ćwiczeniem typu „wyszukuj-kopiuj-wklej-modyfikuj”. Ogromne podziękowania dla mojej żony za pomoc w projektowaniu, wizualizacjach, demo i ogólne porady.
Co dalej z moją idealną pogodą
Chciałbym dodać więcej kontroli pogody i rozszerzyć go na większość świata, a przynajmniej na całą Europę w najbliższej przyszłości. Przy większej liczbie miast/dni pogodowych spełniających kryteria, trudniej będzie zaprezentować najdoskonalsze dni, więc istnieje możliwość użycia Spark MLlib z Spark Streaming dla danych pochodzących z sesji użytkowników.
Mam nadzieję, że IBM wkrótce doda możliwość planowania zadań Sparka, aby usługa mogła stać się w pełni zautomatyzowana.
Wniosek
Możesz sprawdzić aplikację na swoim komputerze, smartfonie lub tablecie, przechodząc na myperfectweather.eu.
Jeśli chcesz mieć szczyt w kodzie, jest on hostowany na Github.
My Perfect Weather powstał jako konkurencyjny projekt dla IBM Sparkathon z blisko 600 uczestnikami. Zdobył główną nagrodę i faworyta fanów. Sprawdź stronę projektu, jeśli chcesz dowiedzieć się więcej.