Como usei o Apache Spark e o Docker em um Hackathon para criar um aplicativo climático

Publicados: 2022-03-11

Em dois dos meus artigos anteriores, apresentei ao público o Apache Spark e o Docker. Chegou a hora de mostrar a você um aplicativo totalmente funcional, incluindo as duas tecnologias mencionadas.

A motivação “choveu do céu em forma de dados” e foi desencadeada por um hackathon organizado pela IBM. O objetivo de Sparkathon era usar dados climáticos e Analytics para Apache Spark para IBM Bluemix para construir aplicativos móveis relacionados a clima.

A IBM está investindo pesadamente no Spark e recentemente comprou parte digital do The Weather Channel. Como consequência, este evento parece perfeito para sua publicidade.

Inspiração

Você já reclamou do clima em sua localidade, tinha algum tempo de folga planejado e dinheiro para gastar, mas não sabia para onde ir? Se a resposta for sim, então você realmente gostaria do aplicativo My Perfect Weather .

Imagem: Casos de uso para o aplicativo.

Apenas para ilustrar como o aplicativo pode ser usado, aqui estão alguns casos de uso:

  1. Você tem um filho com quem prometeu empinar pipa esta semana, mas está absolutamente sem vento onde você mora e você não quer quebrar sua palavra.
  2. Você mora em um lugar ventoso e chuvoso como eu (Edimburgo, Escócia) e quer sentir calor em sua pele e definitivamente sem chuva.
  3. Você tem o desejo de construir um boneco de neve e não descansará até cumpri-lo.
  4. Você quer pescar e, desta vez, você realmente quer pegar alguma coisa.

O que faz

A ideia por trás do serviço é muito simples. Primeiro, você define o que o clima perfeito significa para você em um determinado momento. Atualmente, você pode filtrar por temperatura, velocidade do vento, tipo de precipitação e probabilidade de precipitação, conforme mostrado na captura de tela abaixo. Então o serviço faz o resto e você recebe os melhores destinos correspondentes. Os resultados são ordenados pela quantidade de dias perfeitos, aqueles que correspondem à consulta original, encontrados para cada cidade e limitados aos cinco primeiros. Dias perfeitos também são marcados com um fundo diferente.

Vamos ver como podemos usar o serviço para os casos de uso definidos na seção anterior.

  1. Defina o vento entre 16 e 32 km/h, ideal para soltar pipa, com pouca chance de chuva e temperatura agradável.
  2. Defina a temperatura mínima para ser quente o suficiente para você, defina a chance de chuva para 0%.
  3. Defina a temperatura em torno e abaixo de 0 C, escolha neve como tipo de precipitação e a chance de precipitação seja alta.
  4. Defina a velocidade do vento para ser inferior a 16 km/h, pouca chuva e nuvens, pois você deseja evitar muito sol e fazer com que os peixes se aprofundem na água, temperatura confortável.

Se desejar, você pode conferir facilmente como chegar ao destino escolhido, pois o aplicativo vem integrado a um serviço de busca de viagens Momondo.

Como eu construí

Basicamente, tudo, exceto o serviço externo de pesquisa de viagens, é executado dentro da plataforma IBM Bluemix.

A IBM ofereceu um teste gratuito para todos os participantes do hackathon, então não precisei me preocupar sobre onde executar o aplicativo.

Vamos ver como os dados fluem no aplicativo e como os componentes apresentados no diagrama de arquitetura se unem.

O aplicativo Play é hospedado dentro de um contêiner do Docker. Um de seus serviços é capaz de entrar em contato com o Weather Service e baixar a previsão de 10 dias no Cloudant. Em uma etapa após o download, o Spark lê os dados climáticos brutos do Cloudant, os processa e os armazena de volta no Cloudant para acesso rápido e fácil pelo aplicativo Play.

Quando os usuários navegam para a página principal do aplicativo, eles são apresentados a um formulário contendo vários controles para definir o clima perfeito. Sua entrada é enviada ao back-end que consulta o Cloudant em busca de cidades que contenham os dias perfeitos. Em seguida, é feita outra consulta para todos os dez dias da previsão para as cidades retornadas na consulta anterior. Os resultados obtidos são apresentados aos usuários e as células representam as condições climáticas por cidade por dia. A última célula de cada cidade contém um link para um serviço de viagens. Clicar nele levará os usuários ao site da Momondo e o formulário de pesquisa de voos será pré-preenchido com o destino e as datas da viagem. Se o usuário já usou o serviço antes (e armazenou um cookie em seu navegador), a origem e a quantidade de viajantes também podem ser pré-preenchidas. Naturalmente, os campos deste formulário podem ser alterados. Por exemplo, pode-se tentar diferentes datas de viagem em busca de uma tarifa melhor.

É basicamente assim que o aplicativo é construído. As seções a seguir apresentam mais detalhes de alguns dos componentes.

Imagem: Componentes do aplicativo meteorológico.

Spark e Insights para o clima

A primeira fase do projeto foi dedicada a descobrir como a Weather API e os outros serviços do Bluemix funcionam e foi seguida pela exploração inicial de dados climáticos usando o Spark. Isso me permitiu entender como o modelo de dados funcionava e como ele poderia ser empregado no aplicativo.

Para os fins deste aplicativo, apenas o primeiro dos seguintes endpoints da API REST Weather é usado:

 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

O endpoint é consultado para a previsão do tempo para cada cidade de interesse, fornecendo um parâmetro de geocódigo que leva a latitude e longitude do local em questão.

Devido à natureza do serviço, o número de solicitações feitas à Weather API se correlaciona com o número de cidades suportadas. Considerei o limite de nível gratuito do Insights for Weather Service, que era de 500 chamadas por dia, e decidi que, para fins de demonstração, usaria um número seguro de cinquenta cidades do tipo turístico na Europa. Isso me permite fazer várias chamadas por dia para cada cidade e lidar com solicitações com falha sem o risco de perder o direito de usar a API. Eu teria que começar a pagar para ter pedidos suficientes para cobrir a maioria das cidades do mundo.

O objetivo final do projeto seria ter dados climáticos do Spark para todas as cidades do mundo (~ 50.000) multiplicados por dez dias de dados de previsão e executá-los várias vezes por dia para ter as previsões o mais precisas possível.

Todo o código Spark reside em um notebook Jupyter. Até agora, não há outra maneira de executar trabalhos do Spark. Os dados meteorológicos brutos são lidos do Cloudant DB, processados ​​e escritos de volta.

Banco de dados NoSQL do Cloudant

Resumindo, achei muito agradável trabalhar com o Cloudant NoSQL DB. É fácil de usar e tem uma boa interface de usuário baseada em navegador. Não há driver como tal, mas tem uma API REST simples e foi fácil de interagir via HTTP.

No entanto, o Bluemix Spark inclui uma API Cloudant Data Sources, que pode ser usada para ler e gravar no Cloudant sem a necessidade de chamadas de baixo nível. Vale a pena notar que não é possível criar um novo banco de dados no Cloudant a partir do Spark, portanto, ele deve ser criado antes, por exemplo, com a interface do usuário da web.

Estrutura do jogo

A aplicação web é escrita em Scala. É muito simples. O controlador serve um aplicativo de uma página com AngularJS e Bootstrap, e o serviço interage com a API Weather e o Cloudant.

Um desafio interessante que enfrentei está diretamente relacionado ao IBM Container Service. Minha intenção era executar o aplicativo na porta 80 para que fosse fácil de usar. No entanto, não consegui encontrar nenhuma maneira no Bluemix de usar o encaminhamento de porta do Docker e mapear a porta externa 80 para a porta interna do Docker 9000 do aplicativo Play. Minha solução foi rodar como root dentro do container (não é uma prática recomendada) e editar o application.conf do Play:

 # Production port play.server.http.port = "80"

Janela de encaixe

O Docker foi muito útil, especialmente no momento da implantação do Bluemix. Eu não precisava ter nenhum conhecimento de Cloud Foundry Apps, me preocupar com buildpacks Scala ou qualquer outra coisa. Eu poderia simplesmente enviar minha imagem do Docker e vê-la em execução.

Para criar a imagem do Docker, usei um plug-in do Docker Typesafe, então nem precisei de um Dockerfile adequado.

São necessários apenas alguns comandos para ver o aplicativo rodando na nuvem após uma breve configuração inicial:

 # 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

Vale ressaltar que o Bluemix Container Service realiza uma Avaliação de Vulnerabilidade nas imagens antes que elas possam ser executadas. Mesmo que não fizesse sentido para o meu aplicativo, ainda tive que corrigir /etc/login.defs da imagem pai, para que possa ser executado. Aqui está o Dockerfile se você estiver interessado.

Desafios que encontrei

Como o Spark ainda é uma nova adição ao IBM Bluemix, ele tem certas limitações. Atualmente, o código só pode ser executado como parte de um notebook, portanto, não há como agendar as execuções. Esta foi uma descoberta e tanto no final do tempo que eu tinha para o hackathon. O que significa para o My Perfect Weather é que os dias meteorológicos apresentados ficarão desatualizados lentamente se o notebook Spark não for executado novamente manualmente . Espero que a IBM resolva essa deficiência prontamente.

Também me deparei com uma pequena imprecisão na documentação da API Insights for Weather que surgiu depois de perceber alguns problemas com os resultados exibidos. Para o tipo de precipitação , os únicos valores esperados foram chuva e neve , mas também encontrei um terceiro valor precip . Do contexto climático, parece indicar chuva com neve, então pela simplicidade do aplicativo é tratado como neve.

Realizações das quais me orgulho

Imagem: Usando o Docker e o Spark no aplicativo de clima.

Acho que My Perfect Weather é uma ideia muito legal, e estou orgulhoso de poder implementá-lo muito rapidamente, combinando todas essas várias tecnologias. É um hack, no entanto, com muitas pontas soltas, mas o mais importante é que está funcionando!

O que eu aprendi

Aprendi bastante durante este pequeno projeto. Eu era novo no IBM Bluemix, então foi uma aventura por si só.

Eu nunca ouvi falar do Cloudant DB antes, mas com alguma experiência do MongoDB a transição foi bastante fácil.

Também aprendi que não deveria estar trabalhando em um frontend. Eu sou um desenvolvedor de back-end no coração, sem o talento para fazer as coisas parecerem legais, então trabalhar com Bootstrap e CSS foi um exercício de pesquisa-copiar-colar-modificar. Muito obrigado à minha esposa por ajudar com o design, recursos visuais, demonstração e conselhos gerais.

O que vem a seguir para My Perfect Weather

Eu gostaria de adicionar mais controles climáticos e estendê-los para cobrir a maior parte do mundo, ou pelo menos toda a Europa em um futuro próximo. Com mais cidades/dias meteorológicas correspondendo aos critérios, será mais desafiador apresentar os dias mais perfeitos, portanto, há espaço para usar o Spark MLlib com Spark Streaming para os dados provenientes das sessões dos usuários.

Espero que a IBM adicione um recurso de agendamento de trabalhos do Spark em breve, para que o serviço possa se tornar totalmente automatizado.

Conclusão

Você pode conferir o aplicativo no seu computador, smartphone ou tablet navegando até myperfectweather.eu.

Se você quiser ter um pico no código, ele está hospedado no Github.

My Perfect Weather foi criado como um projeto concorrente da IBM Sparkathon com cerca de 600 participantes. Ganhou o Grande Prêmio e o Favorito dos Fãs. Confira a página do projeto se quiser saber mais.