Cómo usé Apache Spark y Docker en un Hackathon para crear una aplicación meteorológica

Publicado: 2022-03-11

En dos de mis artículos anteriores, presenté a la audiencia Apache Spark y Docker. Ha llegado el momento de mostrarte una aplicación completamente funcional que incluye las dos tecnologías antes mencionadas.

La motivación “cayó del cielo en forma de datos” y fue provocada por un hackathon organizado por IBM. El objetivo de Sparkathon era utilizar datos meteorológicos y Analytics para Apache Spark para IBM Bluemix para crear aplicaciones móviles relacionadas con el clima.

IBM está invirtiendo mucho en Spark y recientemente compró la parte digital de The Weather Channel. Como consecuencia, este evento parece perfecto para su publicidad.

Inspiración

¿Alguna vez se ha quejado del clima en su ubicación, tenía tiempo libre planeado y dinero para gastar, pero no sabía a dónde ir? Si la respuesta es sí, entonces realmente te gustaría la aplicación My Perfect Weather .

Imagen: Casos de uso de la aplicación.

Solo para ilustrar cómo se podría usar la aplicación, aquí hay algunos casos de uso:

  1. Tienes un hijo con el que prometiste volar una cometa esta semana, pero no hay viento en el lugar donde vives y no quieres faltar a tu palabra.
  2. Vives en un lugar ventoso y lluvioso como yo (Edimburgo, Escocia) y quieres sentir calor en tu piel y definitivamente no llueve.
  3. Tienes ganas de construir un muñeco de nieve y no descansarás hasta cumplirlo.
  4. Quieres ir a pescar, y esta vez, realmente quieres pescar algo.

Que hace

La idea detrás del servicio es muy simple. Primero, defines lo que significa el clima perfecto para ti en un momento dado. Actualmente, puede filtrar por temperatura, velocidad del viento, tipo de precipitación y probabilidad de precipitación, como se muestra en la captura de pantalla a continuación. Luego, el servicio hace el resto y se le presentan los mejores destinos coincidentes. Los resultados se ordenan por la cantidad de días perfectos, aquellos que coinciden con la consulta original, encontrados para cada ciudad y limitados a los cinco primeros. Los días perfectos también están marcados con un fondo diferente.

Veamos cómo podríamos usar el servicio para los casos de uso definidos en la sección anterior.

  1. Fije el viento entre 16 y 32 km/h, ideal para volar una cometa, con poca probabilidad de lluvia y temperatura agradable.
  2. Establezca la temperatura mínima para que sea lo suficientemente cálida para usted, establezca la probabilidad de lluvia en 0%.
  3. Establezca la temperatura alrededor y por debajo de 0 C, elija nieve como tipo de precipitación y la posibilidad de que la precipitación sea alta.
  4. Establezca la velocidad del viento en menos de 16 km/h, poca lluvia y nubes, ya que quiere evitar que haga demasiado sol y que los peces se sumerjan más en el agua, temperatura agradable.

Si lo deseas, puedes consultar fácilmente cómo llegar al destino elegido, ya que la aplicación viene integrada con un servicio de búsqueda de viajes Momondo.

Cómo lo construí

Básicamente, todo excepto el servicio de búsqueda de viajes externo se ejecuta dentro de la plataforma IBM Bluemix.

IBM ofreció una prueba gratuita a todos los participantes del hackathon, por lo que no tuve que preocuparme por dónde ejecutar la aplicación.

Veamos cómo fluyen los datos en la aplicación y cómo se unen los componentes presentados en el diagrama de arquitectura.

La aplicación Play está alojada dentro de un contenedor Docker. Uno de sus servicios es capaz de ponerse en contacto con el Servicio Meteorológico y descargar el pronóstico de 10 días en Cloudant. En un paso posterior a la descarga, Spark lee los datos meteorológicos sin procesar de Cloudant, los procesa y los vuelve a almacenar en Cloudant para que la aplicación Play acceda de manera rápida y sencilla.

Cuando los usuarios navegan a la página principal de la aplicación, se les presenta un formulario que contiene varios controles para definir su clima perfecto. Su entrada se envía al backend que consulta a Cloudant sobre las ciudades que contienen los días perfectos. Luego, se realiza otra consulta para todos los diez días del pronóstico para las ciudades devueltas en la consulta anterior. Los resultados obtenidos se presentan a los usuarios y las celdas representan las condiciones climáticas por ciudad por día. La última celda de cada ciudad contiene un enlace a un servicio de viajes. Al hacer clic en él, los usuarios accederán al sitio web de Momondo y el formulario de búsqueda de vuelos se completará previamente con el destino y las fechas de viaje. Si el usuario ha utilizado el servicio anteriormente (y almacenó una cookie en su navegador), el origen y la cantidad de viajeros también pueden estar precargados. Por supuesto, los campos de este formulario se pueden cambiar. Por ejemplo, uno puede probar diferentes fechas de viaje en busca de una mejor tarifa.

Así es como se construye la aplicación. Las siguientes secciones entran en más detalles de algunos de los componentes.

Imagen: Componentes de la aplicación meteorológica.

Spark e Insights para el clima

La primera fase del proyecto se dedicó a descubrir cómo funcionan Weather API y los otros servicios de Bluemix, y fue seguida por la exploración inicial de datos meteorológicos con Spark. Me permitió comprender cómo funcionaba el modelo de datos y cómo podría emplearse en la aplicación.

A los efectos de esta aplicación, solo se utilizan los primeros puntos finales de la API REST de Weather:

 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

Se consulta el punto final para el pronóstico del tiempo para cada ciudad de interés al proporcionar un parámetro de geocodificación que toma la latitud y la longitud del lugar en cuestión.

Debido a la naturaleza del servicio, la cantidad de solicitudes realizadas a Weather API se correlaciona con la cantidad de ciudades admitidas. Consideré el límite de nivel gratuito de Insights for Weather Service, que era de 500 llamadas por día y decidí que, para fines de demostración, elegiría un número seguro de cincuenta ciudades de tipo turístico en Europa. Esto me permitió hacer varias llamadas por día para cada ciudad y manejar las solicitudes fallidas sin riesgo de perder el derecho a usar la API. Tendría que empezar a pagar para tener suficientes solicitudes para cubrir la mayoría de las ciudades del mundo.

El objetivo final del proyecto sería tener datos meteorológicos de Spark Crunch para todas las ciudades del mundo (~50,000) multiplicados por diez días de datos de pronóstico y realizarlo varias veces al día para tener las predicciones lo más precisas posible.

Todo el código de Spark reside en un cuaderno Jupyter. Hasta ahora no hay otra forma de ejecutar trabajos de Spark. Los datos meteorológicos sin procesar se leen de Cloudant DB, se procesan y se vuelven a escribir.

Base de datos Cloudant NoSQL

En resumen, me resultó muy agradable trabajar con Cloudant NoSQL DB. Es fácil de usar y tiene una buena interfaz de usuario basada en navegador. No hay un controlador como tal, pero tiene una API REST simple y fue sencillo interactuar con él a través de HTTP.

Sin embargo, Bluemix Spark incluye una API de fuentes de datos de Cloudant, que podría usarse para leer y escribir en Cloudant sin necesidad de llamadas de bajo nivel. Vale la pena señalar que no es posible crear una nueva base de datos en Cloudant desde Spark, por lo que debe crearse de antemano, por ejemplo, con la interfaz de usuario web.

Marco de juego

La aplicación web está escrita en Scala. Es muy simple. El controlador sirve una aplicación de una página con AngularJS y Bootstrap, y el servicio interactúa con Weather API y Cloudant.

Un desafío interesante al que me enfrenté está directamente relacionado con IBM Container Service. Mi intención era ejecutar la aplicación en el puerto 80 para que fuera fácil de usar. Sin embargo, no pude encontrar ninguna forma en Bluemix de usar el reenvío de puertos Docker y asignar el puerto externo 80 al puerto interno Docker 9000 de la aplicación Play. Mi solución fue ejecutar como root dentro del contenedor (no es una práctica recomendada) y editar application.conf de Play:

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

Estibador

Docker resultó muy útil, especialmente en el momento de la implementación en Bluemix. No necesitaba tener ningún conocimiento de Cloud Foundry Apps, preocuparme por los paquetes de compilación de Scala ni nada más. Podría simplemente empujar mi imagen de Docker y verla funcionando.

Para crear la imagen de Docker, utilicé un complemento Typesafe Docker, por lo que ni siquiera necesitaba un Dockerfile adecuado.

Solo se necesitan unos pocos comandos para ver la aplicación ejecutándose en la nube después de una breve configuración 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 la pena señalar que Bluemix Container Service realiza una evaluación de vulnerabilidad en las imágenes antes de que puedan ejecutarse. Aunque realmente no tenía sentido para mi aplicación, todavía tenía que parchear /etc/login.defs de la imagen principal, para que pudiera ejecutarse. Aquí está el Dockerfile si está interesado.

Desafíos con los que me encontré

Como Spark sigue siendo una adición bastante nueva a IBM Bluemix, tiene ciertas limitaciones. Actualmente, el código solo se puede ejecutar como parte de un cuaderno, por lo que no hay forma de programar las ejecuciones. Esto fue todo un descubrimiento al final del tiempo que tenía para el hackathon. Lo que significa para My Perfect Weather es que los días meteorológicos presentados se irán desfasando lentamente si el portátil Spark no se vuelve a ejecutar manualmente . Espero que IBM aborde esta deficiencia de inmediato.

También encontré una pequeña inexactitud en la documentación de la API Insights for Weather que surgió después de notar algunos problemas con los resultados mostrados. Para el tipo de precipitación , los únicos valores esperados fueron lluvia y nieve , pero también encontré un tercer valor precip . Desde el contexto meteorológico, parece indicar lluvia con nieve, por lo que, por la simplicidad de la aplicación, se trata como nieve.

Logros de los que estoy orgulloso

Imagen: Uso de Docker y Spark en la aplicación meteorológica.

Creo que My Perfect Weather es una idea genial, y estoy orgulloso de poder implementarla muy rápidamente combinando todas esas tecnologías. No obstante, es un truco, con muchos cabos sueltos, ¡pero lo más importante es que está funcionando!

Que aprendí

Aprendí mucho durante este breve proyecto. Era nuevo en IBM Bluemix, por lo que fue una aventura en sí misma.

Nunca antes había oído hablar de Cloudant DB, pero con algo de experiencia con MongoDB, la transición fue bastante fácil.

También aprendí que no debería estar trabajando en una interfaz. Soy un desarrollador back-end de corazón, sin el talento para hacer que las cosas se vean bien, por lo que trabajar con Bootstrap y CSS fue un ejercicio de buscar, copiar, pegar y modificar. Muchas gracias a mi esposa por ayudarme con el diseño, las imágenes, la demostración y los consejos generales.

¿Qué sigue para My Perfect Weather?

Me gustaría agregar más controles meteorológicos y extenderlo para cubrir la mayor parte del mundo, o al menos toda Europa en un futuro cercano. Con más ciudades/días meteorológicos que coincidan con los criterios, será más difícil presentar los días más perfectos, por lo que existe la posibilidad de usar Spark MLlib con Spark Streaming para los datos provenientes de las sesiones de los usuarios.

Espero que IBM agregue la capacidad de programar trabajos de Spark pronto, para que el servicio pueda automatizarse por completo.

Conclusión

Puede consultar la aplicación usted mismo en su computadora, teléfono inteligente o tableta navegando a myperfectweather.eu.

Si desea tener un pico en el código, está alojado en Github.

My Perfect Weather se creó como un proyecto competitivo para IBM Sparkathon con casi 600 participantes. Ganó el Gran Premio y el Favorito de los Fans. Echa un vistazo a la página del proyecto si quieres saber más.