Exportando Sistemas Relacionales a Sistemas Columnares Distribuidos

Publicado en

El manejo de información masiva se ha hecho cotidiano, y una estrategia común para analizar grandes cantidades de datos es moverla de las bases de datos relacionales tradicionales (RDBMS) hacia bases de datos columnares distribuidas.

En el presente artículo muestro los pasos necesarios para migrar información relacional a una infraestructura de Hive en Hadoop. La idea básica es importar grandes datos de un origen relacional como Microsoft SQL Server a un almacenamiento en Hadoop como Hive o HDFS, teniendo la posibilidad de analizar esa información a través de Hue.

Panorama

Para esta labor utilizaremos Apache Sqoop [1], una herramienta precisamente creada para mover datos entre bases de datos estructuradas y Hadoop. Sqoop trabaja con tablas individuales, cada fila de una tabla se trata como un registro en HDFS. Todos los registros se almacenan como datos de texto en archivos de texto, en Hive o HBase (ver figura 1).

Figura 1. Flujo de Sqoop

Prerrequisitos

Para el propósito de este tutorial voy a suponer que ya se tiene instalado y funcionando tanto un ambiente de SQL Server como otro de Hadoop. Si no tienes el de Hadoop, para propósito de aprendizaje puedes utilizar una máquina virtual de Cloudera Quickstart [2]. En tu ambiente de Hadoop necesitas tener instalado Sqoop. Checa si ya tienes, invocando el comando “sqoop” desde la línea de comandos. Si no lo tienes, lo más conveniente es instalarlo por medio del manejador de paquetes de tu sistema operativo (en el caso de OSX está disponible para Homebrew).

Preparando la conexión

Nos conectaremos a SQL Server por medio de JDBC. Para que esto funcione primero necesitamos habilitar TCP/IP en nuestra instancia. Esto se hace desde el SQL Server Configuration Manager.

Posteriormente vamos a descargar el driver de JDBC de SQL Server en nuestro ambiente Hadoop. Este se obtiene del sitio web de Microsoft y al momento de escribir este artículo la versión más reciente se obtiene en http://swgu.ru/t3 . Dentro del paquete encontraremos una carpeta jre7 y otra jre8 y dentro de cada una hay un archivo .jar que corresponde al driver. Así que seleccionaremos el archivo que corresponda a la versión de java que estemos usando y lo copiaremos en /var/lib/sqoop . Si esta carpeta no existe, la creamos y le asignamos los permisos necesarios como se ve a continuación.

$ mkdir -p /var/lib/sqoop
$ chown sqoop:sqoop /var/lib/sqoop
$ chmod 755 /var/lib/sqoop
$ sudo cp sqljdbc_6.0/enu/jre8/sqljdbc42.jar /var/lib/sqoop/

Importando datos

Para verificar que podemos conectarnos de nuestro ambiente Hadoop a SQL Server vamos a comenzar listando las bases de datos. Para ello utilizamos sqoop list-databases con los argumentos de conexión requeridos (en este ejemplo nuestro SQL Server está disponible en la ip 192.168.56.1 y exponiendo el puerto 1444, y tiene un usuario hadoopUser con contraseña hadoop… ).

$ sqoop list-databases --connect jdbc:sqlserver://192.168.56.1:1444 --username hadoopUser --password hadoop...

Con lo anterior obtendremos una lista de las bases de datos.

A continuación importamos la base de datos y tablas que queremos (en este caso la tabla employee de la base de datos sqoopDB).

$ sqoop import --connect "jdbc:sqlserver://192.168.56.1:1444;username=hadoopUser; password=hadoop...; database=sqoopDB" --table employee --hive-import

Por cierto, si quisieramos importar todas las tablas de la BD sin necesidad de especificarlas una por una utilizaríamos sqoop import-all-tables –connect “jdbc://sqlserver….” --hive-import

Si quieres revisar lo que se importó a Hadoop, puedes hacerlo por medio Hue, una interfaz gráfica web para navegar Hadoop.

Hagámoslo repetible

Si quisieramos estar realizando esta tarea frecuentemente, lo más conveniente es  crear un “job” en sqoop que simplemente podemos invocar. Para ello usamos sqoop job con el argumento --create y el resto de la información para conectarse a SQL Server.

$ sqoop job --create jobImpEmpl -- import --connect "jdbc:sqlserver://192.168.56.1:1444;username=hadoopUser;password=hadoop...;database=sqoopDB" --table employee --hive-import

Lo más probable es que no querramos importar todos los datos cada vez que ejecutamos la tarea, sino que solo querramos importar los datos nuevos o modificados. Para lograr esto usamos la opción --incremental e indicamos la columna con el timestamp a verificar.

$ sqoop job --create jobImpEmplInc -- import --connect "jdbc:sqlserver://192.168.56.1:1444;username=hadoopUser;password=hadoop...;database=sqoopDB" --table employee --incremental lastmodified -check-column creationdate --hive-import

Ya creamos los jobs, pero todavía no los ejecutamos. Para ejecutar un job utilizamos sqoop job --execute <nombre-del-job>. Para ver los jobs que tenemos definidos podemos usar sqoop job --list. Y si queremos consultar los detalles de algún job usamos sqoop job --show <nombre-del-job>.

Ejecución periódica automatizada

Si deseamos estar importando datos de manera periódica y automatizada, lo más conveniente es programar la tarea por medio de Oozie, que es una herramienta del ecosistema Hadoop que permite gestionar workflows desde una interfaz web.

Oozie tiene un editor en el cual defines el workflow. Si ya tienes el comando de sqoop que deseas ejecutar simplemente puedes “pegarlo” en un campo de texto al crear tu workflow. Después de eso podemos crear “coordinadores” para calendarizar el envío de información al sistema HDFS (ver figura 2).

Figura 2. Coordinar workflows en Oozie

Conclusión

Se ha mostrado de una forma sencilla la extracción de datos desde un popular ambiente de bases de datos relacionales hasta un sistema columnar como Hive.

Referencias

  1. http://sqoop.apache.org
  2. https://www.cloudera.com/developers/get-started-with-hadoop-tutorial.html
Bio

El MSC Hugo Enrique De La Mora Carrillo (@hugodelamora) es Chief Information Security Officer en CONTPAQi. Anteriormente ha trabajado con sistemas distribuidos, big data, desarrollo para cloud y móvil.