En la sesión de hoy vamos a hablar de Apache Hive que es una de las herramientas que forman parte del ecosistema de herramientas de análisis de datos de Hadoop. Vamos a hacer una pequeña introducción sobre qué proporciona Apache Hive en diferencia de las otras herramientas del entorno, vamos a dar un pequeño ejemplo de arquitectura y qué tipos de usos son ideales para Hive, y vamos a dar un pequeño ejemplo donde utilizamos estas características. Apache Hive es lo que se conoce como un "data warehouse" de código abierto. Es la herramienta para hacer este tipo de operaciones más evolucionada del entorno Hadoop. Es un sistema que facilita la lectura, la escritura y la gestión de datos en un gran conjunto de datos y, como la mayoría de herramientas del entorno Hadoop, se coloca encima de un sistema de datos distribuido "HDFS". Por lo tanto, si tenemos nuestros datos, tenemos un proyecto en los que se almacenan los datos en "HDFS" viniendo de cualquier modo de integración de datos, podemos usar Hive cuando necesitemos hacer consultas típicas de "data warehouse". Esas consultas, típicamente, se realizan mediante un lenguaje "SQL", ya sea mediante la consola que proporciona Hive, o mediante un "driver JDBC" a partir de un lenguaje de alto nivel. ¿Para qué se usa Hive? Es muy importante entender que Hive es una herramienta de propósito general pero, se obtiene su mayor beneficio cuando lo planteamos como un entorno para hacer consultas "batch" en conjuntos de datos. Es decir, queremos obtener una visión resumida de los datos, un cierto análisis, tenemos una serie de consultas típicas que queremos realizar, una y otra vez, pero no estamos preocupados tanto por la latencia de esa consulta, como por la capacidad de acceder a un gran conjunto de datos con un volumen grande. Por lo tanto, utilizaremos "HiveQL" como lenguaje de consulta, y estas consultas, que estarán realizadas en alto nivel, serán traducidas a trabajos "Hadoop MapReduce" que se ejecutarán de forma transparente para el usuario. La arquitectura en Apache Hive está compuesta, básicamente, de cinco bloques, cuatro bloques que son el "driver", donde se reciben las consultas, ya sea desde la consola o desde un entorno de programación de alto nivel. Estas consultas son traducidas por el compilador en varios trabajos a realizar, que son orquestados por un repositorio de metadatos, donde se acaban de decidir qué código se va a ejecutar sobre cada servidor. Ese, al final, será lanzado por un motor de ejecución, que realizará peticiones a un "cluster" de Hadoop. El modelo de datos de Apache Hive es bastante similar a la visión de los datos que tiene un sistema gestor de bases de datos. Tenemos unas tablas que se parecen a las tablas de base de datos relacionales, y luego, tenemos una manera, un entorno, el entorno nos proporciona una manera de trabajar con particiones de datos. Es decir, a partir de una tabla que ya tengamos para nuestros datos, podemos definir una partición donde podamos realizar un volcado de datos con la granularidad más fina. En lugar de procesar una tabla entera, podemos procesar una de estas particiones. Y luego, además, si necesitamos trabajar todavía en un conjunto más fino de datos, podemos trabajar con "Buckets", es decir, un conjunto de valores de una determinada partición también puede agruparse y ser tratado de forma individual. Con este tipo de particiones, lo que queremos es optimizar el trabajo de los datos cuando nos interesan columnas o determinados conjuntos de valores. Típicas aplicaciones de esta tecnología son informes de resumen, por ejemplo, tenemos un proyecto donde estamos recibiendo información diaria sobre los estados de diferentes servidores web, o queremos hacer consultas de minería de datos, que es evaluar la actividad de los usuarios a partir de una serie de operaciones o, por ejemplo, un análisis "ad-hoc", estamos trabajando con una red social y queremos conocer qué actividades realizan los administradores de ciertas comunidades en función de su localización. Ese tipo de consultas se realiza fácilmente con Hive. Ahora, vamos a ver un ejemplo de cómo "Hive" puede incorporar los datos en una tabla, vamos a crear una tabla, vamos a incorporar datos y vamos a realizar una consulta sencilla con el lenguaje "HiveQL". Primero, para crear la base de datos utilizamos un comando de creación de bases de datos, creamos una base de datos llamada "clientes". Una vez está creada esa base de datos, creamos una tabla nueva, la tabla se va a llamar "facturas" y tiene, como atributos, un identificador de la factura, un código de cliente, un código de producto y un coste de ese producto comprado. Vemos en el ejemplo que hemos definido que el tipo de datos son texto, eso se guarda como un fichero de texto, y cada una de las filas va a tener cada uno de los valores separados por comas. Este tipo de descripción, lo vamos a usar cuando vayamos a importar datos. Los datos siempre van a estar disponibles en "HDFS", es decir, cualquier fichero, archivo, carpeta que tenga en "HDFS" con datos que quiera importar, lo voy a realizar, voy a hacer esa importación utilizando el "LOAD DATA INPATH", es decir, yo defino el archivo que yo necesito importar en mi tabla y le digo que sobreescriba la tabla, "facturas", en este caso. A partir de este momento, la tabla "facturas" ya contiene datos y ya puedo realizar cualquier tipo de consulta sobre ella. Por lo tanto, un ejemplo, puede ser una "query" sencilla, una consulta sencilla, donde estoy contando el número de facturas que tiene mi tabla. Simplemente, utilizo un "SQL" que selecciono, cuento todas las líneas de facturas. Y el resultado, Hive va a traducir esta consulta tan sencilla en una serie de trabajos "MapReduce", que va a acceder a "HDFS" y me va a devolver el resultado. Por lo tanto, he liberado la necesidad de programar en lenguaje Java, por ejemplo, una serie de clases "MapReduce", de pensar en fases "map" y "reduce", aquí, simplemente, estoy orientandome a una consulta de datos. No quiero decir con eso que los trabajos no existan, sino simplemente, existe un traductor de esas consultas de alto nivel en "HiveSQL" a trabajos "MapReduce". Muchas veces, cuando voy avanzando en mis consultas, acabo de sufrir una serie de lentitud en el sistema, el proceso se vuelve lento porque tengo que acceder a muchos datos. Y, a veces, la propia consulta me da pistas sobre maneras de desagregar o desagrupar estos datos. Cuando voy aprendiendo más, voy diseñando una serie de tablas donde puedo particionar los datos en función de aquellas consultas que voy a realizar de forma más común. Por lo tanto, puedo plantear tablas con un particionado. En este ejemplo que vemos en esta transparencia, lo que vemos es que he definido una tabla llamada "páginas" donde tengo información sobre una página web, sobre el dominio de esta página web y sobre la fecha en la cual se hizo la captura de datos, y defino un atributo llamado "país", puesto que luego voy a hacer consultas porque quiero conocer cómo son nuestros resultados en función de cada país. Cada partición que defino con la clave "PARTITIONED BY", lo que realiza es, automáticamente, va a dividir los datos en "HDFS" en función de ese atributo, es decir, existe una carpeta separada para cada valor independiente de ese atributo. Es decir, si tengo cinco países en mis datos, tendré cinco carpetas. Y yo no tendré que hacer nada, esto lo va a hacer Hive por mí. Entonces, el impacto que tiene este diseño, se visualiza cuando yo voy a hacer una consulta. Por ejemplo, en esta transparencia lo que he puesto es un ejemplo donde necesito todos los datos que tenga sobre estas páginas, a partir del 24 de diciembre del 2017, y solo me interesa el Reino Unido, he definido que mi atributo de país es el Reino Unido. Y estoy buscando un cierto dominio, como este "ejemplo.com". El impacto de esta consulta, en términos de rendimiento, es muy alto, puesto que ahora yo no voy a buscar datos que no estén almacenados en la carpeta donde están los datos del Reino Unido, por lo tanto, habrá una gran cantidad de información agregada que yo he obtenido, que no se va a leer ni se va a procesar y, en algún caso, puede ser que a algunos de los servidores ni siquiera se le haga ninguna pregunta. El impacto de esta optimización en el rendimiento es bastante alto. Es necesario recordar que Hive también permite una definición de granularidad más fina, si necesito definir conjuntos de valores dentro de una partición, puedo utilizar los "Buckets" para realizar esta partición y obtener todavía mejores resultados de rendimiento. Como conclusiones es importante recalcar que Hive es una solución de "data warehouse" de código abierto que ofrece el entorno Hadoop, los datos que vamos a utilizar ya están existentes en el entorno Hadoop, están almacenados en "HDFS". Voy a utilizar un lenguaje muy similar a "SQL", con lo cual muchas personas de mi departamento en análisis no necesitan aprender lenguajes de programación, pueden utilizar "SQL". Que estas consultas que vaya a realizar, estos perfiles de mi proyecto, son orientadas a "batch", es decir, van a tardar un cierto tiempo en devolver los datos. Y que, si este tiempo acaba siendo un problema debido al volumen de datos, puedo utilizar los esquemas de particionado que me permite Hive para reducir el tiempo de procesamiento según sean mis consultas.