Как я использовал Apache Spark и Docker на хакатоне для создания приложения погоды
Опубликовано: 2022-03-11В двух моих предыдущих статьях я познакомил аудиторию с Apache Spark и Docker. Пришло время показать вам полнофункциональное приложение, включающее в себя обе вышеупомянутые технологии.
Мотивация «пролилась дождем с неба в виде данных» и была вызвана хакатоном, организованным IBM. Целью Sparkathon было использование данных о погоде и Analytics для Apache Spark для IBM Bluemix для создания мобильных приложений, связанных с погодой.
IBM активно инвестирует в Spark и недавно купила цифровую часть The Weather Channel. Как следствие, это событие кажется идеальным для их публичности.
Вдохновение
Вы когда-нибудь жаловались на погоду в вашем регионе, планировали отпуск и деньги, но не знали, куда пойти? Если ответ «да», то вам действительно понравится приложение My Perfect Weather .
Просто чтобы проиллюстрировать, как можно использовать приложение, вот несколько вариантов использования:
- У вас есть ребенок, с которым вы обещали запустить воздушного змея на этой неделе, но там, где вы живете, абсолютно безветренно, и вы не хотите нарушать свое слово.
- Вы живете в ветреном и дождливом месте, как и я (Эдинбург, Шотландия), и хотите чувствовать тепло на своей коже и уж точно никакого дождя.
- У вас есть желание слепить снеговика, и вы не успокоитесь, пока не исполните его.
- Вы хотите пойти на рыбалку, и на этот раз вы действительно хотите что-то поймать.
Что оно делает
Идея сервиса очень проста. Во-первых, вы определяете, что означает для вас идеальная погода в данный момент времени. В настоящее время вы можете фильтровать по температуре, скорости ветра, типу осадков и вероятности осадков, как показано на скриншоте ниже. Затем служба сделает все остальное, и вам будут представлены наиболее подходящие направления. Результаты сортируются по количеству идеальных дней, соответствующих исходному запросу, найденных для каждого города и ограниченных пятью лучшими. Идеальные дни также отмечены другим фоном.
Давайте посмотрим, как мы могли бы использовать сервис для вариантов использования, определенных в предыдущем разделе.
- Установите скорость ветра от 16 до 32 км/ч, идеальную для запуска воздушного змея, с небольшой вероятностью дождя и комфортной температурой.
- Установите минимальную температуру, чтобы она была достаточно теплой для вас, установите вероятность дождя на 0%.
- Установите температуру около и ниже 0 C, выберите снег в качестве типа осадков и высокую вероятность осадков.
- Установите скорость ветра менее 16 км/ч, небольшой дождь и облачность, так как вы хотите, чтобы не было слишком солнечно и чтобы рыба погружалась глубже в воду, комфортная температура.
При желании вы можете легко проверить, как добраться до выбранного пункта назначения, поскольку приложение интегрировано с сервисом поиска путешествий Momondo.
Как я это построил
По сути, все, кроме внешнего сервиса поиска путешествий, работает внутри платформы IBM Bluemix.
IBM предложила всем участникам хакатона бесплатную пробную версию, поэтому мне не пришлось беспокоиться о том, где запустить приложение.
Давайте посмотрим, как данные передаются в приложении и как объединяются компоненты, представленные на архитектурной диаграмме.
Приложение Play размещается внутри контейнера Docker. Один из его сервисов способен связываться с погодной службой и загружать 10-дневный прогноз в Cloudant. На следующем этапе загрузки Spark считывает необработанные данные о погоде из Cloudant, обрабатывает их и сохраняет обратно в Cloudant для быстрого и легкого доступа к приложению Play.
Когда пользователи переходят на главную страницу приложения, им предоставляется форма, содержащая различные элементы управления для определения идеальной погоды. Их ввод передается серверной части, которая запрашивает Cloudant для городов, содержащих идеальные дни. Затем выполняется еще один запрос для всех десяти дней прогноза для городов, возвращенных в предыдущем запросе. Полученные результаты представляются пользователям, а ячейки представляют собой погодные условия в каждом городе в течение дня. Последняя ячейка для каждого города содержит ссылку на туристический сервис. Нажав на нее, пользователи перейдут на веб-сайт Momondo, а форма поиска рейса будет предварительно заполнена пунктом назначения и датами поездки. Если пользователь уже использовал эту услугу ранее (и она сохранила файл cookie в своем браузере), происхождение и количество путешественников также могут быть предварительно заполнены. Конечно, поля в этой форме можно изменить. Например, можно попробовать разные даты поездки в поисках лучшего тарифа.
Примерно так устроено приложение. В следующих разделах более подробно рассматриваются некоторые компоненты.
Spark и информация о погоде
Первый этап проекта был посвящен выяснению того, как работают Weather API и другие службы Bluemix, после чего последовало первоначальное исследование данных о погоде с использованием Spark. Это позволило мне понять, как работает модель данных и как ее можно использовать в приложении.
Для целей этого приложения используется только первая из следующих конечных точек 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
Конечная точка запрашивает прогноз погоды для каждого интересующего города, предоставляя параметр геокода , который принимает широту и долготу рассматриваемого места.
Из-за характера службы количество запросов, сделанных к API погоды, коррелирует с количеством поддерживаемых городов. Я рассмотрел лимит бесплатного уровня Insights for Weather Service, который составлял 500 звонков в день, и решил, что для демонстрационных целей я выберу безопасное число из пятидесяти городов туристического типа в Европе. Это позволило мне делать по несколько звонков в день для каждого города и обрабатывать неудачные запросы без риска потерять право на использование API. Пришлось бы начать платить, чтобы хватило запросов на покрытие большинства городов мира.

Конечной целью проекта будет получение данных Spark о погоде для всех городов мира (~ 50 000), умноженных на данные прогноза за десять дней, и выполнение их несколько раз в день, чтобы прогнозы были максимально точными.
Весь код Spark находится в блокноте Jupyter. Пока нет другого способа выполнять задания Spark. Необработанные данные о погоде считываются из базы данных Cloudant, обрабатываются и записываются обратно.
Облачная база данных NoSQL
Одним словом, мне было очень приятно работать с Cloudant NoSQL DB. Он прост в использовании и имеет хороший пользовательский интерфейс на основе браузера. Драйвера как такового нет, но есть простой REST API и с ним легко взаимодействовать через HTTP.
Однако Bluemix Spark включает в себя Cloudant Data Sources API, который можно использовать для чтения и записи в Cloudant без необходимости низкоуровневых вызовов. Стоит отметить, что создать новую базу данных в Cloudant из Spark невозможно, поэтому ее необходимо создать заранее, например, с помощью веб-интерфейса.
Игровая структура
Веб-приложение написано на Scala. Это очень просто. Контроллер обслуживает одностраничное приложение с AngularJS и Bootstrap, а сервис взаимодействует с Weather API и Cloudant.
Одна интересная проблема, с которой я столкнулся, напрямую связана с IBM Container Service. Я намеревался запустить приложение на порту 80, чтобы оно было удобным для пользователя. Однако я не смог найти в Bluemix способ использовать переадресацию портов Docker и сопоставить внешний порт 80 с внутренним портом 9000 Docker приложения Play. Мой обходной путь состоял в том, чтобы запустить как root внутри контейнера (не рекомендуется) и отредактировать application.conf Play:
# Production port play.server.http.port = "80"
Докер
Docker оказался очень кстати, особенно во время развертывания в Bluemix. Мне не нужно было знать о приложениях Cloud Foundry, беспокоиться о сборочных пакетах Scala или о чем-то еще. Я мог просто нажать на свой образ Docker и увидеть, как он работает.
Для создания образа Docker я использовал плагин Typesafe Docker, поэтому мне даже не понадобился правильный файл Docker.
Требуется всего несколько команд, чтобы увидеть приложение, работающее в облаке после короткой начальной настройки:
# 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
Стоит отметить, что служба контейнеров Bluemix выполняет оценку уязвимости образов перед их запуском. Несмотря на то, что это не имело особого смысла для моего приложения, мне все же пришлось исправить /etc/login.defs
родительского образа, чтобы его можно было запустить. Вот Dockerfile, если вам интересно.
Проблемы, с которыми я столкнулся
Поскольку Spark все еще является достаточно свежим дополнением к IBM Bluemix, у него есть определенные ограничения. В настоящее время код может выполняться только как часть записной книжки, поэтому нет возможности планировать запуски. Это было настоящим открытием в конце того времени, которое у меня было на хакатоне. Для My Perfect Weather это означает, что представленные дни погоды будут постепенно устаревать, если блокнот Spark не будет повторно запущен вручную . Я надеюсь, что IBM быстро устранит этот недостаток.
Я также столкнулся с небольшой неточностью в документации Insights for Weather API, которая обнаружилась после того, как я заметил некоторые проблемы с отображаемыми результатами. Для типа осадков единственными ожидаемыми значениями были дождь и снег , но я также нашел третье значение осадков . Из контекста погоды кажется, что это дождь со снегом, поэтому для простоты приложения это рассматривается как снег.
Достижения, которыми я горжусь
Я думаю, что My Perfect Weather — довольно крутая идея, и я горжусь тем, что смог реализовать ее очень быстро, смешав все эти различные технологии вместе. Тем не менее, это хак со многими недоработками, но самое главное, что он работает!
Что я выучил
Я многому научился во время этого короткого проекта. Я был новичком в IBM Bluemix, так что это было само по себе приключением.
Я никогда раньше не слышал о Cloudant DB, но с некоторым опытом работы с MongoDB переход был довольно легким.
Я также узнал, что мне не следует работать над интерфейсом. В душе я бэкэнд-разработчик, у меня нет таланта делать вещи красивыми, поэтому работа с Bootstrap и CSS представляла собой упражнение «поиск-копирование-вставка-изменение». Большое спасибо моей жене за помощь с дизайном, визуальными эффектами, демонстрацией и общими советами.
Что дальше для моей идеальной погоды
Я хотел бы добавить больше контроля погоды и расширить его, чтобы охватить большую часть мира или, по крайней мере, всю Европу в ближайшем будущем. При большем количестве городов/погодных дней, соответствующих критериям, будет сложнее представить самые идеальные дни, поэтому есть возможность использовать Spark MLlib с Spark Streaming для данных, поступающих из сеансов пользователей.
Я надеюсь, что IBM скоро добавит возможность планировать задания Spark, чтобы сервис мог стать полностью автоматизированным.
Заключение
Вы можете сами проверить приложение на своем компьютере, смартфоне или планшете, перейдя на myperfectweather.eu.
Если вы хотите получить доступ к коду, он размещен на Github.
My Perfect Weather был создан как конкурирующий проект для IBM Sparkathon с почти 600 участниками. Он выиграл Гран-при и стал фаворитом фанатов. Посетите страницу проекта, если хотите узнать больше.