Introducción a Apache Spark con ejemplos y casos de uso

Publicado: 2022-03-11

Escuché por primera vez sobre Spark a fines de 2013 cuando me interesé en Scala, el idioma en el que está escrito Spark. Algún tiempo después, hice un divertido proyecto de ciencia de datos tratando de predecir la supervivencia en el Titanic. Esta resultó ser una excelente manera de conocer más los conceptos y la programación de Spark. Lo recomiendo encarecidamente a cualquier aspirante a desarrollador de Spark que busque un lugar para empezar.

Hoy, Spark está siendo adoptado por importantes jugadores como Amazon, eBay y Yahoo! Muchas organizaciones ejecutan Spark en clústeres con miles de nodos. Según las preguntas frecuentes de Spark, el clúster más grande conocido tiene más de 8000 nodos. De hecho, Spark es una tecnología que vale la pena tomar nota y conocer.

Este artículo proporciona una introducción a Spark que incluye casos de uso y ejemplos. Contiene información del sitio web de Apache Spark, así como del libro Learning Spark: Lightning-Fast Big Data Analysis.

¿Qué es Apache Spark? Una introducción

Spark es un proyecto de Apache anunciado como "computación de clúster ultrarrápida". Tiene una próspera comunidad de código abierto y es el proyecto Apache más activo en este momento.

Spark proporciona una plataforma de procesamiento de datos más rápida y general. Spark le permite ejecutar programas hasta 100 veces más rápido en la memoria o 10 veces más rápido en el disco que Hadoop. El año pasado, Spark se hizo cargo de Hadoop al completar el concurso Daytona GraySort de 100 TB 3 veces más rápido en una décima parte de la cantidad de máquinas y también se convirtió en el motor de código abierto más rápido para clasificar un petabyte.

Spark también permite escribir código más rápidamente, ya que tiene a su disposición más de 80 operadores de alto nivel. Para demostrar esto, echemos un vistazo a "¡Hola mundo!" de BigData: el ejemplo de Word Count. Escrito en Java para MapReduce, tiene alrededor de 50 líneas de código, mientras que en Spark (y Scala) puede hacerlo de la siguiente manera:

 sparkContext.textFile("hdfs://...") .flatMap(line => line.split(" ")) .map(word => (word, 1)).reduceByKey(_ + _) .saveAsTextFile("hdfs://...")

Otro aspecto importante al aprender a usar Apache Spark es el shell interactivo (REPL) que proporciona listo para usar. Con REPL, se puede probar el resultado de cada línea de código sin necesidad de codificar y ejecutar primero todo el trabajo. Por lo tanto, el camino hacia el código de trabajo es mucho más corto y se hace posible el análisis de datos ad-hoc.

Las características clave adicionales de Spark incluyen:

  • Actualmente proporciona API en Scala, Java y Python, con soporte para otros lenguajes (como R) en camino
  • Se integra bien con el ecosistema Hadoop y las fuentes de datos (HDFS, Amazon S3, Hive, HBase, Cassandra, etc.)
  • Puede ejecutarse en clústeres administrados por Hadoop YARN o Apache Mesos, y también puede ejecutarse de forma independiente

El núcleo de Spark se complementa con un conjunto de potentes bibliotecas de alto nivel que se pueden usar sin problemas en la misma aplicación. Estas bibliotecas actualmente incluyen SparkSQL, Spark Streaming, MLlib (para aprendizaje automático) y GraphX, cada una de las cuales se detalla más en este artículo. Actualmente también se están desarrollando bibliotecas y extensiones adicionales de Spark.

Spark bibliotecas y extensiones

Núcleo de chispa

Spark Core es el motor base para el procesamiento de datos paralelos y distribuidos a gran escala. Es responsable de:

  • gestión de memoria y recuperación de fallos
  • programar, distribuir y monitorear trabajos en un clúster
  • interactuar con los sistemas de almacenamiento

Spark presenta el concepto de un RDD (Conjunto de datos distribuido resistente), una colección de objetos distribuidos, inmutables y tolerantes a fallas que se pueden operar en paralelo. Un RDD puede contener cualquier tipo de objeto y se crea cargando un conjunto de datos externo o distribuyendo una colección desde el programa controlador.

Los RDD admiten dos tipos de operaciones:

  • Las transformaciones son operaciones (como mapa, filtro, combinación, unión, etc.) que se realizan en un RDD y que generan un nuevo RDD que contiene el resultado.
  • Las acciones son operaciones (como reducir, contar, primero, etc.) que devuelven un valor después de ejecutar un cálculo en un RDD.

Las transformaciones en Spark son "perezosas", lo que significa que no calculan sus resultados de inmediato. En su lugar, simplemente "recuerdan" la operación que se realizará y el conjunto de datos (por ejemplo, un archivo) en el que se realizará la operación. Las transformaciones solo se calculan realmente cuando se llama a una acción y el resultado se devuelve al programa controlador. Este diseño permite que Spark funcione de manera más eficiente. Por ejemplo, si un archivo grande se transformó de varias maneras y pasó a la primera acción, Spark solo procesaría y devolvería el resultado de la primera línea, en lugar de hacer el trabajo para todo el archivo.

De forma predeterminada, cada RDD transformado se puede volver a calcular cada vez que ejecuta una acción en él. Sin embargo, también puede conservar un RDD en la memoria utilizando el método persistente o de caché, en cuyo caso Spark mantendrá los elementos en el clúster para un acceso mucho más rápido la próxima vez que lo consulte.

SparkSQL

SparkSQL es un componente de Spark que admite la consulta de datos a través de SQL o del lenguaje de consulta de Hive. Se originó como el puerto Apache Hive para ejecutarse sobre Spark (en lugar de MapReduce) y ahora está integrado con la pila Spark. Además de brindar soporte para varias fuentes de datos, permite entretejer consultas SQL con transformaciones de código, lo que resulta en una herramienta muy poderosa. A continuación se muestra un ejemplo de una consulta compatible con Hive:

 // sc is an existing SparkContext. val sqlContext = new org.apache.spark.sql.hive.HiveContext(sc) sqlContext.sql("CREATE TABLE IF NOT EXISTS src (key INT, value STRING)") sqlContext.sql("LOAD DATA LOCAL INPATH 'examples/src/main/resources/kv1.txt' INTO TABLE src") // Queries are expressed in HiveQL sqlContext.sql("FROM src SELECT key, value").collect().foreach(println)

Transmisión de chispa

Spark Streaming admite el procesamiento en tiempo real de datos de transmisión, como archivos de registro del servidor web de producción (por ejemplo, Apache Flume y HDFS/S3), redes sociales como Twitter y varias colas de mensajería como Kafka. Bajo el capó, Spark Streaming recibe los flujos de datos de entrada y los divide en lotes. Luego, el motor Spark los procesa y genera el flujo final de resultados en lotes, como se muestra a continuación.

chispa de transmisión

La API de Spark Streaming se parece mucho a la de Spark Core, lo que facilita a los programadores trabajar en el mundo de los datos por lotes y de transmisión.

MLlib

MLlib es una biblioteca de aprendizaje automático que proporciona varios algoritmos diseñados para escalar horizontalmente en un clúster para clasificación, regresión, agrupamiento, filtrado colaborativo, etc. (consulte el artículo de Toptal sobre aprendizaje automático para obtener más información sobre ese tema). Algunos de estos algoritmos también funcionan con transmisión de datos, como la regresión lineal que utiliza mínimos cuadrados ordinarios o el agrupamiento de k-medias (y más en el camino). Apache Mahout (una biblioteca de aprendizaje automático para Hadoop) ya se alejó de MapReduce y unió fuerzas en Spark MLlib.

GráficoX

gráficox

GraphX ​​es una biblioteca para manipular gráficos y realizar operaciones paralelas de gráficos. Proporciona una herramienta uniforme para ETL, análisis exploratorio y cálculos de gráficos iterativos. Además de las operaciones integradas para la manipulación de gráficos, proporciona una biblioteca de algoritmos gráficos comunes, como PageRank.

Cómo usar Apache Spark: caso de uso de detección de eventos

Ahora que hemos respondido a la pregunta "¿Qué es Apache Spark?", pensemos en qué tipo de problemas o desafíos podría usarse de manera más efectiva.

Encontré un artículo recientemente sobre un experimento para detectar un terremoto mediante el análisis de una transmisión de Twitter. Curiosamente, se demostró que esta técnica probablemente informaría de un terremoto en Japón más rápido que la Agencia Meteorológica de Japón. A pesar de que usaron una tecnología diferente en su artículo, creo que es un gran ejemplo para ver cómo podríamos usar Spark con fragmentos de código simplificados y sin el código de pegamento.

Primero, tendríamos que filtrar los tweets que parecen relevantes como "terremoto" o "sacudida". Fácilmente podríamos usar Spark Streaming para ese propósito de la siguiente manera:

 TwitterUtils.createStream(...) .filter(_.getText.contains("earthquake") || _.getText.contains("shaking"))

Luego, tendríamos que realizar un análisis semántico de los tweets para determinar si parecen estar haciendo referencia a un terremoto actual. Tweets como "¡Terremoto!" o "Ahora está temblando", por ejemplo, se considerarían coincidencias positivas, mientras que tuits como "Asistir a una conferencia sobre terremotos" o "El terremoto de ayer fue aterrador" no lo serían. Los autores del artículo utilizaron una máquina de vectores de soporte (SVM) para este propósito. Haremos lo mismo aquí, pero también podemos probar una versión de transmisión. Un ejemplo de código resultante de MLlib sería similar al siguiente:

 // We would prepare some earthquake tweet data and load it in LIBSVM format. val data = MLUtils.loadLibSVMFile(sc, "sample_earthquate_tweets.txt") // Split data into training (60%) and test (40%). val splits = data.randomSplit(Array(0.6, 0.4), seed = 11L) val training = splits(0).cache() val test = splits(1) // Run training algorithm to build the model val numIterations = 100 val model = SVMWithSGD.train(training, numIterations) // Clear the default threshold. model.clearThreshold() // Compute raw scores on the test set. val scoreAndLabels = test.map { point => val score = model.predict(point.features) (score, point.label) } // Get evaluation metrics. val metrics = new BinaryClassificationMetrics(scoreAndLabels) val auROC = metrics.areaUnderROC() println("Area under ROC = " + auROC)

Si estamos satisfechos con la tasa de predicción del modelo, podríamos pasar a la siguiente etapa y reaccionar cada vez que descubramos un terremoto. Para detectar uno, necesitamos un cierto número (es decir, densidad) de tweets positivos en una ventana de tiempo definida (como se describe en el artículo). Tenga en cuenta que, para los tweets con los servicios de ubicación de Twitter habilitados, también extraeríamos la ubicación del terremoto. Armados con este conocimiento, podríamos usar SparkSQL y consultar una tabla de Hive existente (almacenando usuarios interesados ​​en recibir notificaciones de terremotos) para recuperar sus direcciones de correo electrónico y enviarles un correo electrónico de advertencia personalizado, de la siguiente manera:

 // sc is an existing SparkContext. val sqlContext = new org.apache.spark.sql.hive.HiveContext(sc) // sendEmail is a custom function sqlContext.sql("FROM earthquake_warning_users SELECT firstName, lastName, city, email") .collect().foreach(sendEmail)

Otros casos de uso de Apache Spark

Los posibles casos de uso de Spark se extienden mucho más allá de la detección de terremotos, por supuesto.

Aquí hay una muestra rápida (¡pero ciertamente no exhaustiva!) de otros casos de uso que requieren lidiar con la velocidad, la variedad y el volumen de Big Data, para los cuales Spark es tan adecuado:

En la industria de los juegos, el procesamiento y el descubrimiento de patrones de la manguera de incendios potencial de los eventos del juego en tiempo real y la capacidad de responder a ellos de inmediato es una capacidad que podría generar un negocio lucrativo, para fines tales como la retención de jugadores, publicidad dirigida, auto -ajuste del nivel de complejidad, etc.

En la industria del comercio electrónico, la información de transacciones en tiempo real podría pasarse a un algoritmo de agrupamiento de transmisión como k-means o filtrado colaborativo como ALS. Los resultados podrían incluso combinarse con otras fuentes de datos no estructurados, como comentarios de clientes o reseñas de productos, y usarse para mejorar y adaptar constantemente las recomendaciones a lo largo del tiempo con las nuevas tendencias.

En la industria de las finanzas o la seguridad, Spark Stack podría aplicarse a un sistema de detección de fraude o intrusión o autenticación basada en riesgos. Podría lograr resultados de primer nivel al recopilar grandes cantidades de registros archivados, combinándolos con fuentes de datos externas como información sobre filtraciones de datos y cuentas comprometidas (ver, por ejemplo, https://haveibeenpwned.com/) e información de la conexión/ solicitud como la geolocalización de IP o la hora.

Conclusión

En resumen, Spark ayuda a simplificar la tarea desafiante y computacionalmente intensiva de procesar grandes volúmenes de datos archivados o en tiempo real, tanto estructurados como no estructurados, integrando a la perfección capacidades complejas relevantes, como el aprendizaje automático y los algoritmos gráficos. Spark lleva el procesamiento de Big Data a las masas. ¡Echale un vistazo!