Estadística simple con Spark V2

Sigo con mi pruebas con lo nuevo (y no tan nuevo de Spark 2), hoy comparto con ustedes una versión 2 de mi anterior post Estadística simple con Spark, pero en esta ocasión realizado con Spark 2.

¿Que tiene de nuevo esta versión?

Primeramente utiliza el módulo spark-csv lo cual nos hace más simple la carga del fichero en un Dataset. Segundo, que no manipulamos en ningún instante RDD alguno, sino que por el contrario estamos trabajando con DataFrames representados mediante la clase Dataset. Entre las cosas nuevas que contempla esta versión hecha en Spark 2 es que mientras antes al realizar un groupBy sobre un DataFrame esto nos devolvía un GroupedData ahora nos devuelve un RelationalGroupedData, esto debido a un cambio de nombre que se le ha dado a partir de esta nueva versión de Spark.

Esta nueva versión realizada con SparkSQL con Datasets tiene varias ventajas, la primera es simplicidad, es mucho mas simple, mas fácil de entender el código además de mas corto, de hecho con menos lineas obtuve más información que con la versión elaborada con RDD’s, es decir, es mas versátil. Por otro lado aunque hay que tener algo de nociones de conjuntos lo interesante es que esta versión esta libre de código SQL.

Sin más dilación he aquí el código y el enlace al proyecto en Github.

Para que comparen los resultados obtenidos aquí con respecto a la entrada anterior dejo un pantallazo de lo obtenido al ejecutarlo en mi local.

promedios por distrito

promedios por distrito

Otras agregaciones por distrito

Otras agregaciones por distrito

Total personas por distrito

Total personas por distrito

Enviar correo de GMAIL con Java

Este es otro post que quería compartir desde hace tiempo, entre otras cosas por su sencillez ya que en un proyecto anterior una solución de este tipo nos ayudó a resolver un problema puntual. Les pongo en contexto, debíamos desde nuestra empresa enviar una información que recabábamos diariamente, como es de suponer estábamos alejados fisicamente y en otra red y como no podía ser de otra forma no había permisos para por FTP o SSH hacer llegar la información, es por ello que dado las exigencias y con el poco tiempo que contábamos se nos ocurrió la idea “¿y si enviamos la información por email?”  y así hicimos, construimos un pequeño programa Java el cual se ejecutaba periódicamente para enviar unos ficheros adjuntos que sacábamos diariamente.

Primero que nada es necesario que desde la cuenta de GMAIL habilitemos el acceso de aplicaciones menos seguras. Para ello es necesario que ingresemos a nuestra cuenta de GMAIL y una vez dentro vayamos a la parte superior derecha donde este el icono de nuestra cuenta, hacemos clic en el icono y posteriormente al botón “Mi cuenta”. Allí veremos la siguiente imagen

mi cuenta de GMAIL

mi cuenta de GMAIL

Como vemos en la imagen de arriba (resaltado en rojo), debemos hacer clic en el apartado de “Inicio de sesión y seguridad”. Y allí nos desplazamos hasta la parte inferior y habilitamos/activamos la opción “Permitir el acceso de aplicaciones menos seguras”, como en la imagen de abajo.

habilitar acceso de aplicaciones menos seguras

habilitar acceso de aplicaciones menos seguras

Hecho esto, vamos al programa, el cual hace uso de Java Mail. El programa es bastante sencillo consta de un fichero de configuración del siguiente tipo:

gmail.account: La cuenta de GMAIL desde la cual enviaremos el correo electrónico.

gmail.password: El password de la cuenta de GMAIL desde la cual enviaremos el correo electrónico.

emaildestinations: Lista de direcciones de correo electrónico separadas por punto y coma (“;”) a donde será enviado el correo.

attachmentfiles: Lista de rutas donde están ubicados los ficheros a adjuntar separados por punto y coma (“;”).

A continuación el programa Java encargado del envío del correo electrónico.

El ejemplo es bastante sencillo, pero nos muestra como indicar el asunto del email, el texto del mensaje así como adjuntar ficheros. Espero que les pueda ser de utilidad. Aquí el enlace al proyecto en Github.

Primeros pasos con Apache Spark 2

Hace pocos días salió la esperada versión 2 de Apache Spark y como algunos de ustedes saben es un framework que ahora mismo atrae mucho mi atención y como no pudo ser de otra forma hice un pequeño proyecto donde quiero ir colocando ejemplos sencillos de Spark con las nuevas (y no tan nuevas) cosas de Spark.

Para empezar comentarles que yo todavía no he utilizado sbt sino por el contrario uso maven como herramienta de construcción de proyectos. He aquí los primeros cambios necesarios para trabajar con spark 2, las dependencias correspondientes a la versión (indicadas en el pom.xml).

Entre los nuevos cambios de spark está que el punto de entrada para los programas spark ya no serán el hiveContext o sqlContext sino que han sido subsumidas en una clase llamada SparkSession. Las clases HiveContext y SQLContext se han mantenido para proporcionar retrocompatibilidad. Ejemplo

Con el SparkSession haremos lo mismo que hacíamos con sqlContext por ejemplo obtener un Dataset

O por el contrario obtener un DataFrame

Otro punto importante ha sido la unificación de las clases Dataset y DataFrame (para Java y Scala) a partir de la versión 2.¿Qué significa esto? pues sencillamente que ahora solo existirá la clase Dataset, pero proporcionará la misma funcionalidad que nos daba la clase DataFrame, de hecho basta con comparar la API en la versión 1.6.2 y 2.0.0 y ver como los métodos de la clase DataFrame están ahora incluidos en la clase Dataset.

Dataset y Dataframe en Spark 2

Dataset y Dataframe en Spark 2

Aquellos interesados en leer más acerca de Dataset y Dataframe  visitar este link

Estos no son los únicos cambios en Spark, de hechos son muchos más, que se corresponden a optimizaciones a nivel de compilación y ejecución así como también a un nuevo parseador SQL, para leer mas acerca de lo nuevo en Spark 2 clic aquí.

Aqui les dejo en enlace al proyecto donde ire añadiendo clases y seguiré probando mas cosas nuevas de Spark.

Representación gráfica de mi cuenta de Twitter

Hola de nuevo chicos, este es un post breve pero que quería compartir con ustedes desde hace mucho tiempo, fue hace un año aproximadamente que en la materia de análisis de redes sociales realicé un mini proyecto, este consistió en analizar la actividad de mi red social de twitter, y además tener una representación gráfica de la actividad de mi cuenta, es decir, a quienes sigo y las menciones y hashtags utilizados por mí y por aquellos a quienes sigo, incluso el número de veces que se ha utilizado cada hashtag.

Lo único que he hecho antes de subir el código a github fue actualizar la versión neo4j a 2.3.6 (base de datos de grafo donde se guardan las relaciones) y eliminar mis datos para el uso de la API de twitter.

Antes de ejecutar esta aplicación será necesario que generen un token y sigan los pasos necesarios para poder utilizar la API de twitter, por otro lado es importante destacar que este programa almacena las distintas relaciones entre entidades en una base de datos embebida de neo4j y para poder visualizar el resultado final de todas esas relaciones guardadas, lo que hice fue simplemente utilizar el navegador/visualizador por defecto que trae neo4j (que si no me equivoco esta creado con d3.js). Así que manos a la obra y comencemos descargando e instalando la versión 2.3.6 de Neo4j desde el siguiente enlace y una vez realizada la instalación pasamos al código fuente.

A continuación la clase principal:

El código completo del proyecto pueden hallarlo en el siguiente enlace. Una vez hayamos ejecutado nuestra aplicación, en la ruta especificada TWITTER_DB_PATH encontraremos una carpeta con extensión .db donde estarán almacenadas las relaciones (todo el grafo), el siguiente paso para poder visualizar el grafo será editar el fichero RUTA_INSTALACION_NEO4J/conf/neo4j-server.properties y editar la ruta donde ha de estar ubicada la base de datos

org.neo4j.server.database.location=TWITTER_DB_PATH.db

TWITTER_DB_PATH= La ruta especificada donde se ha de crear la base de datos Neo4j donde se almacenarán las relaciones.

Ahora procedemos a arrancar la base de datos, que es bastante sencillo solo es necesario ejecutar el siguiente comando:

RUTA_INSTALACION_NEO4J/bin/neo4j start

Hecho esto desde un navegador (chrome o firefox por ejemplo) ir a la ruta http://localhost:7474 y veremos el cliente web de Neo4j

neo4j

neo4j

Luego desde la consola donde ejecutar las consultas (donde aparece el símbolo del $) ejecutar el siguiente comando para poder visualizar todo el grafo.

MATCH (n) RETURN n

En mi caso obtuve lo siguiente

relaciones neo4j

relaciones neo4j

Como podrán darse cuenta se pueden distinguir los distintos tipos de relaciones (USE y MENTION) entre los distintos nodos, además hay 2 tipos de nodos, los azules son las cuentas de twitter y los verdes son los hashtags.

Otra cosa interesante es que con el visualizador de Neo4j podemos ver los datos de las relaciones como por ejemplo el número de veces que una cuenta de twitter ha usado un hashtag o mencionado a otra cuenta como en la siguiente gráfica

Número de veces que un hashtag es utilizado

Número de veces que un hashtag es utilizado

Como se puede apreciar en la parte inferior de la gráfica, la cuenta Ben & Martijn ha utilizado 2 veces el hashtag #Java.

Bueno ya no me queda más nada que mostrar a este respecto, así que si te resulta interesante ejecuta este ejemplo y ve como es la actividad de tu cuenta de twitter y te aseguro que encontraras cosas que te llamarán la atención y si te parece compártelas con el resto.

Por último mencionarles que intentare en medida de lo posible actualizar este código para que trabaje con la versión 3 o superior de Neo4j, mejorar el código (hacerlo más claro) y actualizarlo a Java 8. Cualquier comentario y/o sugerencia soy todo oídos.

Primer ejemplo con apache Storm

Apache Storm es un framework de procesamiento distribuido de eventos. Empresas como twitter utilizaron Storm desde el 2011 aunque posteriormente lo reemplazó por Heron en el 2015.

Actualmente me encuentro trabajando en una aplicación construida con Apache Storm y quiero compartir con ustedes mi primer ejemplo con Apache Storm el cual es bastante simple pero cumplio su cometido que era el iniciarme en este framework y entender sus componentes principales.

Necesitaremos descargar rabbitMQ la versión 3.5.7.

Una vez hayamos instalado rabbitMQ (es solo cuestión de descomprimir) vamos a habilitar un plugin (un cliente web) donde podremos de forma sencilla monitorizar las colas, entonces nos ubicamos en la siguiente ruta ruta_instalacion_rabbitmq/sbin/ y desde allí ejecutamos el siguiente comando

./rabbitmq-plugins enable rabbitmq_management

Este comando habilitará el cliente web que nos permitirá monitorizar las colas, los exchanges  incluso manipular las colas pudiendo ingresar elementos a las colas, sacar elementos e incluso purgar las colas. Paso siguiente iniciaremos el rabbitMQ con el siguiente comando:

./rabbitmq-server

Inmediatamente después desde un navegador nos dirigimos a la dirección http://localhost:15672

rabbitmq overview

rabbitmq overview

Una vez allí crearemos una cola para hacer nuestro ejemplo y la llamaremos “data”.

agregar cola en rabbitmq

agregar cola en rabbitmq

Ahora deberíamos ser capaces de ver la única cola de nuestro sistema. Clicando en ella podríamos incluso agregarle mensajes por medio de la interfaz gráfica (si lo desean hagan la prueba y verán como cada uno de los mensajes que agreguen se irán encolando), pero la inserción de mensajes en la cola lo haremos mediante un pequeño programa Java.

cola data

cola data

Ahora un poco de teoría para conocer acerca de Apache Storm.

¿Qué es Apache Storm?

Es un framework de computación distribuida en tiempo real, escrito en su mayoría en Clojure. Storm es similar a la forma como Hadoop ofrece un conjunto de primitivas generales para hacer el procesamiento por lotes, también ofrece un conjunto de primitivas generales para hacer cómputos en tiempo real. Storm es simple, se puede utilizar con cualquier lenguaje de programación.

Las aplicaciones de Storm son creadas como topologías en la forma de DAG (Directed Acyclic  Graph) con spouts y bolts actuando como los vertices del grado. Las aristas en el grafo son llamados streams y dirigen la data de un nodo a otro. Juntos, la topología actúa como una tubería de transformación de datos.

Los spouts son fuentes de flujo (streams) en una topología. Los spouts generalmente leerán tuplas desde una fuente externa y las emiten dentro de la topología.

Un bolt es donde se realiza todo el procesamiento de una topología, pueden hacer cualquier cosa, desde filtrado, funciones, agregaciones, joins, comunicarse con bases de datos y mucho más.

El ejemplo que hice y compartiré a continuación con ustedes será bastante simple, estará constituido por un spout que leerá de una cola rabbitmq (la cola data que creamos anteriormente) y ese mensaje lo insertará en la topología para posteriormente al recibirlo el bolt mostrarlo por linea de comandos (ya luego si ustedes lo desean lo que podrían hacer es que en vez de mostrarlo por linea de comandos volcar ese mensaje en otra cola de rabbitmq).

El programa java que se encarga de insertar mensajes a la cola

El Spout que leerá de la cola rabbitMQ

El bolt que leerá los datos que han sido insertados en la topología por el Spout

Definición de la topología

Para ejecutar nuestro ejemplo y verlo funcionando debemos ejecutar 2 clases (el orden sería indistinto):

  • SendMessagesToRabbit
  • RabbitMQTopologyExample

Al ejecutar la clase SendMessagesToRabbit, podremos ver en el cliente Web de RabbitMQ como la cola tendrá 10000 mensajes encolados. Al ejecutar la topología (ejecutando la clase RabbitMQTopologyExample) podremos ver como los mensajes se van desencolando y a su vez por linea de comandos (por ejemplo de nuestro editor) veremos los mensajes que en teoría el bolt leyó y procesó.

Espero que les sea de utilidad y disfruten con este framework, desde mi punto de vista es sencillo y funciona bien, incluso la nueva herramienta que utiliza Twitter posee retrocompatibilidad con Storm por lo cual se podría empezar con un ejemplo de este tipo.

Clic aquí para ir al repositorio github.