DStreams vs. DataFrames: Dos sabores de Spark Streaming
Este post es una publicación invitada escrita por Yaroslav Tkachenko, Arquitecto de Software en Activision.
Apache Spark es uno de los frameworks de procesamiento de datos a gran escala más populares y potentes. Fue creado como una alternativa al marco MapReduce de Hadoop para cargas de trabajo por lotes, pero ahora también soporta SQL, aprendizaje automático y procesamiento de flujos. Hoy quiero centrarme en Spark Streaming y mostrar algunas opciones disponibles para el procesamiento de flujos.
El procesamiento de datos en flujo se utiliza cuando se generan datos dinámicos de forma continua, y se encuentra a menudo en casos de uso de big data. En la mayoría de los casos, los datos se procesan casi en tiempo real, un registro a la vez, y la información derivada de los datos también se utiliza para proporcionar alertas, presentar cuadros de mando y alimentar modelos de aprendizaje automático que pueden reaccionar rápidamente a las nuevas tendencias dentro de los datos.
DStreams vs. DataFrames
Spark Streaming se convirtió en alfa con Spark 0.7.0. Se basa en la idea de flujos discretizados o DStreams. Cada DStream se representa como una secuencia de RDDs, por lo que es fácil de usar si vienes de cargas de trabajo por lotes de bajo nivel respaldadas por RDDs. DStreams sufrió muchas mejoras durante ese período de tiempo, pero todavía había varios desafíos, principalmente porque es una API de muy bajo nivel.
Como solución a esos desafíos, Spark Structured Streaming se introdujo en Spark 2.0 (y se hizo estable en 2.2) como una extensión construida sobre Spark SQL. Por ello, aprovecha las optimizaciones de código y memoria de Spark SQL. Structured Streaming también proporciona abstracciones muy potentes como las APIs Dataset/DataFrame así como SQL. Ya no hay que lidiar con los RDDs directamente
Tanto el Structured Streaming como el Streaming con DStreams utilizan micro-batching. La mayor diferencia es la latencia y las garantías de entrega de los mensajes: Structured Streaming ofrece una entrega exacta con una latencia de más de 100 milisegundos, mientras que el enfoque de Streaming con DStreams sólo garantiza la entrega de al menos una vez, pero puede proporcionar latencias de milisegundos.
Personalmente prefiero Spark Structured Streaming para casos de uso simples, pero Spark Streaming con DStreams es realmente bueno para topologías más complicadas debido a su flexibilidad. Por eso a continuación quiero mostrar cómo utilizar Streaming con DStreams y Streaming con DataFrames (que se suele utilizar con Spark Structured Streaming) para consumir y procesar datos de Apache Kafka. Voy a utilizar Scala, Apache Spark 2.3, y Apache Kafka 2.0.
Además, a modo de ejemplo, ejecutaré mis trabajos utilizando los cuadernos Apache Zeppelin proporcionados por Qubole. Qubole es una plataforma de datos que uso a diario. Gestiona clusters de Hadoop y Spark, facilita la ejecución de consultas ad hoc de Hive y Presto, y también proporciona cuadernos Zeppelin gestionados que utilizo con gusto. Con Qubole no necesito pensar mucho en la configuración y ajuste de Spark y Zeppelin, simplemente se maneja por mí.
El caso de uso real que tengo es muy sencillo:
- Se escribe algún tipo de telemetría a Kafka: pequeños mensajes JSON con metadatos y pares clave/valor arbitrarios
- Quiero conectarme a Kafka, consumir y deserializar esos mensajes
- Después aplicar transformaciones si es necesario
- Recoger algunas agregaciones
- Finalmente, Estoy interesado en las anomalías y los datos generalmente malos – ya que no controlo el productor, quiero atrapar cosas como NULLs, cadenas vacías, tal vez fechas incorrectas y otros valores con formatos específicos, etc.
- El trabajo debe ejecutarse durante algún tiempo y luego terminar automáticamente. Normalmente, los trabajos de Spark Streaming se ejecutan de forma continua, pero a veces puede ser útil ejecutarlo ad hoc para el análisis/depuración (o como ejemplo en mi caso, ya que es muy fácil ejecutar un trabajo de Spark en un cuaderno).
Streaming con DStreams
En este enfoque utilizamos DStreams, que es simplemente una colección de RDDs.
Streaming con DataFrames
Ahora podemos intentar combinar el Streaming con la API de DataFrames para obtener lo mejor de ambos mundos!
Conclusión
¿Qué enfoque es mejor? Dado que DStream es sólo una colección de RDDs, se suele utilizar para transformaciones y procesamientos de bajo nivel. Añadir una API de DataFrames encima proporciona abstracciones muy potentes como SQL, pero requiere un poco más de configuración. Y si tienes un caso de uso simple, Spark Structured Streaming podría ser una mejor solución en general!