[AUDIO_EN_BLANCO] [MÚSICA] En la sesión de hoy vamos a hablar sobre Apache Spark. Apache Spark es una de las herramientas con más éxito dentro del entorno de trabajo de Hadoop MapReduce. Vamos a explicar durante la sesión de hoy qué novedades aporta Spark en el entorno de trabajo y cómo se realiza un análisis, un típico análisis de datos dentro de este entorno. Vamos a preguntarnos por qué es necesario Apache Spark, cómo aparece, por qué es necesario diferenciarse del entorno hasta ahora, cuál es la arquitectura de Spark, qué novedades aporta, y vamos a entrar un poco en detalle sobre las transformaciones de datos de Spark y cuál es su impacto dentro del uso. Veremos que simplifica mucho el uso del entorno MapReduce de Hadoop. Bien, el primer análisis que, la primera pregunta que nos hacemos es por qué es necesario Apache Spark. Y la primera respuesta es porque el paradigma MapReduce aparece como un cambio dentro del entorno de gestión de los datos, con ese famoso mantra en donde lo que se mueve es el cómputo, no los datos, y se muestra útil para procesar grandes conjuntos de datos. Pero, a partir de su uso inicial, se ve, se comprueba, que hay determinados usos de los datos que están muy limitados por el tipo de trabajo que se realiza en MapReduce, donde tenemos una fase Map, una fase Reduce, y los datos finales. Y hay modelos de trabajo que quedan fuera de esta simplificación de trabajo con los datos. Existen flujos de datos que son iterativos, es decir, que se ven conjuntados de datos de entrada, se realiza una operación, se obtiene unos datos de salida y se vuelven a aplicar otros filtros, otros análisis sobre ese conjunto de datos de salida. Típicamente es el caso de machine learning, donde, si tenemos unos ciertos datos you cargados en memoria, podemos optimizar su uso y continuar trabajando con ellos. Este tipo de procesamiento no está soportado de una forma muy directa en los modelos MapReduce, con lo cual aparece una nueva manera de trabajar con ellos donde se plantean una serie de ventajas. Las ventajas de Spark son: primero, la facilidad de trabajar con DAGs, es decir, cuando nuestro procesamiento de datos tiene la forma de un grafo dirigido a cíclico, es decir, tenemos varias fases donde la fase posterior depende de los datos de la anterior, Spark perite crear esa cadena de pasos de una forma bastante simplificada. Por lo tanto, todos aquellos algoritmos, pipelines de trabajo, workflows, que definan etapas donde hay una dependencia clara entre ellas, va a ser fácil de trabajar en Spark con ellas. En el mismo análisis vamos a poder englobar todas esas etapas. Lo siguiente es su simplicidad. El entorno se ha simplificado mucho y vamos a poder definir trabajos de una manera muy, muy fácil. Luego lo veremos en los ejemplos. Y la siguiente ventaja es la versatilidad. El entorno de trabajo you no está dirigido solo a desarrollar nuestros propios algoritmos. Podemos integrar librerías que proporciona Spark y, entre ellas, las más famosas son: la de grafos, que es GraphX, y Mlib que es la librería de algoritmos de machine learning. Dentro, estos algoritmos, estas librerías, se pueden aplicar de forma directa en nuestros algoritmos. La arquitectura de Spark está dividida en grandes bloques. Existe un gran entorno que es el Spark Core, donde se van a trabajar de forma interna los procesamientos de los datos, que veremos posteriormente, y tenemos una serie de bloques, que es el Spark tradicional, donde vamos a utilizar un lenguaje de programación o una consola, y luego existen esos entornos nuevos que añade Spark, como Mlib o GraphX, que tienen su conexión directa con el Core de Spark, con lo cual no necesitan llamar a un programa, sino ellos mismos pueden llamar directamente al motor de análisis de datos. Por debajo, también se añaden una serie de entornos más flexibles, you que podemos usar un cluster de Spark, hecho a medida, o bien podemos usar otros entornos, otros gestores de recursos, como YARN de Hadoop o Mesos de Apache, donde podemos definir diferentes tipos de clusters utilizando Spark en cada uno de ellos. El procesamiento de datos con Spark es un poco, está diferenciado el trabajo que se hacía en Hadoop MapReduce. Tenemos un código fuente de una serie de consultas que vienen, you sea de la consola o you sea de GraphX o de cualquier otra librería, ese código se va a traducir en una serie de primitivas de datos, y esas primitivas se van a orquestar en el motor de ejecución de forma que se va a establecer una serie de pasos de forma que se establece un grafo dirigido a cíclico, cuyas etapas se van a optimizar en la ejecución en cada uno de los elementos del procesamiento del cluster. Las características de Spark, por lo tanto, son: la flexibilidad de almacenamiento, podemos almacenar ciertos tipos de datos en memoria si nos interesa, o podemos guardar los datos persistidos en disco que puedan ser analizados por otras etapas. Ofrece el entorno multilenguaje, es decir, podemos usar programas Spark desde lenguajes de alto nivel como Python, R o Scala. Y existe una independencia del entorno de gestión de recursos distribuidos you que Spark permite el uso de YARN y de Mesos como gestor de recursos. Finalmente, también permite la posibilidad de realizar consultas de forma iterativa con la aplicación o utilizando el terminal de forma que podamos tener un vistazo rápido de cómo son nuestros datos antes de lanzar consultas de gran volumen. La gran obsesión, la gran optimización que realiza Spark es la reducción de volumen de trabajo entrada/salida. Es el objetivo de Spark realizar, mejorar esa cantidad de datos que se mueven. Para ello presenta el concepto de RDDs, Resilient Distributed Datasets, que es una, bloques de datos, que se van a procesar a partir de los datos de entrada, se van a gestionar RDDs, colecciones de datos, que son serializables y que pueden ser particionados y distribuidos entre varios servidores de una manera muy sencilla. Todas las aplicaciones en Spark se van a traducir en un conjunto de RDDs que se van a leer, se va a aplicar un cierto procesamiento, se va a obtener un RDD como resultado y se va a poder aplicar, de nuevo, otra función de ese estilo, hasta que al final tengamos un resultado final interesante para la aplicación, que será almacenado de nuevo en el sistema de ficheros distribuidor que estemos usando. Vamos a dar un ejemplo de uso de RDDs. Entonces, tendremos para el usuario, para el programador que trabaje con Spark, tenemos una serie de transformaciones de datos, una serie de primitivas, que vamos a aplicar a los datos de lectura o de una serie de transformación previa que va a ir cambiando cada uno de los datos. Ahora no estamos solo trabajando con MapReduce, sino con muchas otras más, tenemos mucha más riqueza. En el ejemplo que estáis viendo en la transparencia, tenemos primero el clásico, el Map donde aplicamos una función a cada uno de los elementos del RDD para generar un nuevo RDD, después aplicamos un filtro, que es una, básicamente es una función booleana, que va a devolver un valor cierto o falso según esa función se cumpla y, para aquellos elementos el RDD que se cumpla, que se dé como cierto, van a formar parte del resultado del filtro. Todos aquellos que no se cumpla no serán parte del resultado. También veremos un caso de aplicación de keyBy, que es una agrupación por clave, es decir, tenemos todos los datos que tengan la misma clave. Y luego, finalmente, tenemos un Join, que es una aplicación, un filtro bastante común donde agrupamos más de un RDD a partir de un determinado valor de clave, es decir, tendremos, es como un Reduce, a partir de un determinado valor de clave tenemos un conjunto de valores que han ido apareciendo asociados a esa clave. Bien, cuando realicemos un programa puede ser tan sencillo, un ejemplo de trabajo de Spark puede ser tan sencillo como estas tres líneas que estáis viendo en la transparencia. Tenemos, cada una de estas líneas refleja un flujo de RDDs y existen, pueden existir, diferentes flujos que se definen en paralelo. Por ejemplo, en la primera línea, leo los datos de entrada y aplica un Map. Después de ese Map aplica un filtro por un valor concreto. La segunda línea también lee los datos de entrada pero, en lugar de filtrar, busca una cierta clave y agrupa valores por esa clave. En la tercera línea lo que hacemos es juntar esas dos líneas separadas de trabajo y hacer un join de la, por un determinado valor de clave a partir del cual solo nos interesa los 40 primeros valores. Bien, a partir de esa definición tan sencilla de qué vamos a hacer con los datos, seguimos teniendo un lenguaje orientado a datos, es decir, estamos definiendo qué queremos hacer con ellos. Spark lo que crea es el flujo de datos, cada uno de los recuadros azules que estáis viendo refleja un rdd distinto. El primero de la primera línea lee los datos de entrada de un fichero y genera el primer rdd que es el resultado del map. Como resultado del map se aplica el groupBy y tenemos un resultado agregado por clave. En la segunda línea se establece otro procesamiento de datos en paralelo que lo que hace es leer los datos de entrada y también realizar otro map muy parecido, pero en este caso el resultado del map lo vamos a pasar a un filtrado. Es decir, solo aquellos valores que tengan esa determinada clave van a pasar a la siguiente fase. Y como resultado final se hace un join de los dos flujos. El, los bloques de datos B y E van a ser unidos mediante la misma clave y el resultado final no va a ser almacenado en forma completa, sino solo aquellos 40 primeros elementos por, nos interesa solo tener un vistazo de cuáles son esos datos. Todo este agrupamiento, ejecución de datos del trabajo de filtro se realiza de forma automática para el usuario. El usuario no tiene que definir ningún map, ningún reduce, sino este flujo se orquestra de forma transparente para el programador. Para finalizar, parte del éxito de Spark se ve en esta transparencia. Cuando vemos programado en Hadoop, hemos visto lo que nos cuesta definir un simple trabajo de map reduce para contar palabras. Aquí podéis ver que en tres líneas en Spark podemos hacer lo mismo, y la visión es de muy alto nivel. En la primera línea vemos cómo se crea un contexto, un nuevo SparkContext, aquí you tenemos una variable Spark que va a almacenar, va a leer valores de una cierta carpeta y podemos almacenar diferentes datos. Entonces, a partir de que estos datos de entrada you están definidos, leemos los datos en una variable llamada datos con la función TextFile que, es decir, lee ficheros de datos y fijaos que el procesamiento se realiza sobre la variable C simplemente acumulando procesamiento de datos, ¿no? Elementos de procesamiento. Primero vamos a hacer un map, un FlatMap para convertir cada línea en strings, en cadenas. El siguiente map lo que va a convertir es cada cadena en una pareja de valor de clave cadena y valor un número uno, y luego vamos a transferir esos datos al siguiente procesamiento, al siguiente trabajo que es hacer un reduce por parejas, es decir, para cada clave se van a sumar todos los valores que tengamos por parejas y, al final, grabaremos el resultado en un fichero hdfs. Como se puede observar, se ha simplificado muchísimo el uso de estas primitivas y no tenemos que preocuparnos de más que cuál es el flujo que queremos aplicar a nuestros datos de forma secuencial. Bien, como conclusión, ¿cuándo podemos usar Spark? ¿Cuáles son los entornos, cuáles son los requerimientos de trabajo? ¿Dónde se puede usar Spark? Primero, lo primero que tenemos que pensar es que es sencillo, es fácil de utilizar, es rápido, si sabemos que esos conjuntos de datos son necesarios puede ser incluso eficiente, y nos proporciona una gran facilidad de uso. Por lo tanto, este entorno es par que está sustituyendo a muchísimos casos a Hadoop map reduce como primer entorno inicial de contacto con análisis de datos. En los últimos años está desplazando a Hadoop como framework de referencia de trabajo de datos, y es una de las primeras opciones más populares al día de hoy cuando tenemos que realizar una serie de procesamiento utilizando las librerías que nos añaden como es la de graphs o, sobretodo, la de machine learning. [MÚSICA] [AUDIO EN BLANCO]