GuilleSQL :: Microsoft SQL Server, SSIS, y más !!

Instalar un Cluster de Hadoop, Hive, y Spark sobre Raspberry


Una opción muy interesante desde un punto de vista didáctico es montar un Cluster de Hadoop (con MapReduce y Yarn), Hive, y Spark (con Scala) sobre un conjunto de Raspberry (una, dos o más, aunque lo suyo es al menos dos o tres para poder jugar con los diferentes roles). Esto nos permitirá acercarnos un poco más a estas tecnologías Big Data que tan de moda se están poniendo, y poder experimentar su instalación, configuración y funcionamiento básico, sin necesidad de una gran inversión en hardware. Big Data for the masses.

¿Por qué utilizar tecnologías como Hadoop o Spark?

Para no mí no es fácil responder a esta pregunta, ya que realmente estoy empezando ahora a conocer todas estas tecnologías. Voy a intentar hacer una aproximación a mi interpretación, aunque quizás dentro de un tiempo, cuando conozca mejor todo esto, sea capaz de hacer una lectura quizás bastante diferente. Voy a ello.

Si tenemos un problema de cálculo asociado a datos, podemos resolverlo con un ordenador. Eso está claro. Si nuestro problema crece, ya sea en la complejidad del cálculo y/o en el volumen de datos, el tiempo de resolución también aumentará, así que llegará un momento, en el que simplemente sustituiremos dicho ordenador por otro más grande, y resuelto. Esta forma de proceder es muy sencilla, más hardware y listo. Sin embargo, ¿qué podemos hacer si llegamos a un punto de inflexión en el que no podemos acceder a un ordenador lo suficientemente grande (porque no existe, o porque su coste es excesivo)? Aquí es donde las tecnologías como Hadoop y Spark nos pueden ayudar.

Hadoop nos va a ofrecer tener un sistema de ficheros distribuido. De este modo, podemos montar una red de 100 ordenadores con almacenamiento local SSD, y configurar hadoop para que tenga un coeficiente de réplica para que cada dato esté copiado/sincronizado en al menos 10 ordenadores.

Esto lo que nos va a permitir es paralelizar, dividir nuestro trabajo en tareas, cada una de las cuales se pueda realizar en un ordenador de nuestro Cluster. Pero lo más importante, es que nos va a permitir que se realice en un ordenador que ya tenga una copia de los datos en local, lo cual va a acelerar mucho más todo el proceso, ya que los ordenadores no tendrán que ir a buscar el dato y traerlo a través de la red, porque ya lo tienen, y en disco rápido.

Claro, con Hadoop, el problema es que la programación (por lo que me han contado, que yo no lo he vivido en mis propias carnes) es un poco infierno, pegándose con código Java para hacer Map Reduce, etc. Aquí es donde llega Spark, que aunque su lenguaje más natural sería Scala, también permite programar en R y en Python, lo que nos da la potencia de Hadoop y la facilidad y potencia de programación de Python y R, para paralelizar código, y para programar con rapidez tanto algoritmos de Ciencia de Datos como incluso realizar las propias visualizaciones desde un simple Jupyter Notebook con un Kernel de PySpark o de sparkr. Y esto mola. Mola y mucho. Es potente, y además fácil.

Pero ¿Qué son todas estas cosas: Hadoop, Hive, Spark,...?

Si, esto también es un poco lío al principio. Muchas palabras nuevas. Vamos a intentar hacer un breve resumen, quizás no muy fiel, pero que transmita un poco el concepto.

  • Hadoop ofrece un sistema de archivos distribuido entre varios Nodos. Divide los ficheros en bloques grandes (por defecto 128MB) que se almacenan duplicados según el coeficiente de réplica que tengamos configurado (por defecto 3, por lo tanto, al menos 3 Nodos tendrán una copia local de cada bloque de datos).
  • MapReduce funciona sobre Hadoop/HDFS y nos va a permitir ejecutar grandes conjuntos de datos en paralelo, sobre los Nodos que tengan localmente los datos que necesita de HDFS.
  • YARN gestiona los recursos de nuestro Cluster, como RAM y CPU.
  • Hive proporciona una capa de abstracción en formato SQL para poder acceder a los datos de HDFS como si fuera una base de datos relacional. Sus consultas SQL son transformadas a Jobs de Map Reduce para su ejecución en paralelo, permitiendo trabajar con grandes volúmenes de información.

Y dicho esto, vamos al lío.

Descripción del escenario de partida

Tenemos las Raspberry con Raspbian recién instalado utilizando PINN, SSH está habilitado, la password por defecto ha sido cambiada, Auto-Login ha sido deshabilitado, la memoria para la GPU ha sido configurada a 32MB, el idioma del teclado ha sido configurado, la configuración de red (dirección IP, DNS y Gateway) del interfaz eth0 ha sido configurada, se tiene acceso a Internet, el hostname ha sido configurado (ej: node01, node02, etc), java ya está instalado (ej: java versión 1.8.0_65), vim ya está instalado (sudo apt-get install vim).

Lo primero que vamos a hacer es crear un usuario hduser para Hadoop, MapReduce y YARN en todas las Raspberry. Utilizaremos el mismo usuario para las tres cosas.

Para ello nos conectaremos a la Raspberry. Crearemos un grupo denominado hadoop, crearemos un usuario denominado hduser estableciéndole como grupo primario hadoop (el que acabamos de crear), y concederemos privilegios de sudo al usuario hduser (a través de la pertenencia al grupo sudo). Esto lo realizaremos con los siguientes comandos:

sudo addgroup hadoop
sudo adduser --ingroup hadoop hduser
sudo adduser hduser sudo

A continuación se muestra la salida de ejecución.

Modificaremos el fichero /etc/hosts en todas las Raspberry para asegurarnos que resuelven correctamente los nombres de todos los nodos del Cluster. Para ello nos aseguraremos de que están presentes las siguientes entradas en /etc/hosts.

192.168.1.190   node01
192.168.1.191   node02
192.168.1.192   node03

También vamos a aumentar el tamaño del fichero de swap a 2GB en todas las Raspberry (la versión de Raspbian que tenemos, viene con 1GB de SWAP). Para ello ejecutaremos los siguientes comandos en cada una de las Raspberry.

sudo su -c 'echo "CONF_SWAPSIZE=2048" > /etc/dphys-swapfile'
sudo dphys-swapfile setup
sudo dphys-swapfile swapon

Lo siguiente que vamos a hacer es generar una clave RSA sin contraseña para el acceso SSH en la primera de las Raspberry (node01), y la vamos a añadir como clave autorizada de confianza en la propia Raspberry para el usuario hduser. Esto nos permitirá poder conectarnos a través de SSH localmente a la propia Raspberry, sin tener que introducir credenciales, que es algo que necesitaremos en varias situaciones, por ejemplo, por los scripts start-dfs.sh y start-yarn.sh para arranchar Hadoop y YARN, pues en caso contrario se solicitará la contraseña del usuario hduser.

mkdir ~/.ssh
ssh-keygen -t rsa -P ""
cat ~/.ssh/id_rsa.pub > ~/.ssh/authorized_keys

Copiaremos la información de las claves RSA, desde node01 al resto de nodos. Esto lo podremos hacer con un comando como el siguiente para cada nodo. Una vez realizado, podremos conectarnos por ssh entre los nodos, sin que se solicite contraseña, así como también realizar copia de ficheros con scp, ejecutar comandos remotos, etc.

scp /home/hduser/* node02:/home/hduser/.ssh

Instalación de Hadoop en Single Node (incluye YARN y MapReduce)

Para comenzar, vamos a crear un Cluster de un único Nodo, por lo tanto, tendremos un NameNode y un DataNode, ambos roles sobre la misma Raspberry.

Nos conectaremos por SSH a nuestra raspberry con el usuario hduser. Descargaremos el binario de la versión de Hadoop que deseamos instalar, en nuestro caso Hadoop 2.7.6, lo descomprimiremos en /opt, lo renombraremos como /opt/hadoop, y cambiaremos su propietario. Esto lo realizaremos con los siguientes comandos:

cd /opt
sudo wget http://apache.rediris.es/hadoop/common/hadoop-2.7.6/hadoop-2.7.6.tar.gz
sudo tar -xvzf hadoop-2.7.6.tar.gz
sudo mv hadoop-2.7.6 hadoop
sudo chown -R hduser:hadoop hadoop

Ahora vamos a establecer varias variables de entorno para el usuario hduser. Para ello, volveremos al directorio home del usuario hduser, y editaremos el fichero .bashrc añadiendo al final del mismo las siguientes líneas.

export JAVA_HOME=$(readlink -f /usr/bin/java | sed "s:bin/java::")
export HADOOP_HOME=/opt/hadoop
export HADOOP_INSTALL=$HADOOP_HOME
export YARN_HOME=$HADOOP_HOME
export PATH=$PATH:$HADOOP_INSTALL/bin:$HADOOP_INSTALL/sbin
export HADOOP_USER_CLASSPATH_FIRST=true

A continuación vamos a modificar varios ficheros de configuración de hadoop. Estos ficheros se encuentran en la ruta /opt/hadoop/etc/hadoop.

En particular, los ficheros que vamos a modificar son los siguientes:

  • /opt/hadoop/etc/hadoop/hadoop-env.sh
  • /opt/hadoop/etc/hadoop/core-site.xml
  • /opt/hadoop/etc/hadoop/hdfs-site.xml
  • /opt/hadoop/etc/hadoop/yarn-site.xml
  • /opt/hadoop/etc/hadoop/mapred-site.xml
  • /opt/hadoop/etc/hadoop/slaves
  • /opt/hadoop/etc/hadoop/masters

El primer fichero que vamos a modificar es hadoop-env.sh en el cual vamos a modificar sólo dos líneas, la export JAVA_HOME y la export HADOOP_HEAPSIZE (por defecto son 1000MB de heap por demonio, y lo bajaremos a 256MB, dada la reducida memoria de la Raspberry), dejándolas tal y como se ve en el siguiente ejemplo.

export JAVA_HOME=$(readlink -f /usr/bin/java | sed "s:bin/java::")
export HADOOP_HEAPSIZE=256

Ahora modificaremos el fichero core-site.xml básicamente añadiendo contenido entre las etiquetas configuration (estarán vacías), dejándolo tal y como se ve en el siguiente ejemplo.

<configuration>
   <property>
      <name>hadoop.tmp.dir</name>
      <value>/hdfs/tmp</value>
   </property>
   <property>
      <name>fs.default.name</name>
      <value>hdfs://node01:54310</value>
   </property>
</configuration>

Seguidamente modificaremos el fichero hdfs-site.xml básicamente para añadir la configuración dfs.replication asignándola al valor 1 (más adelante, cuando tengamos varios nodos, la estableceremos a un valor superior), dejándolo tal y como se ve en el siguiente ejemplo (por defecto, nos encontraremos la etiqueta configuration vacía).

<configuration>
   <property>
      <name>dfs.replication</name>
      <value>1</value>
   </property>
</configuration>

Ahora modificaremos el fichero yarn-site.xml básicamente añadiendo contenido entre las etiquetas configuration (estarán vacías), dejándolo tal y como se ve en el siguiente ejemplo. Para más detalles ver https://hadoop.apache.org/docs/r2.7.6/hadoop-yarn/hadoop-yarn-common/yarn-default.xml

<configuration>
   <property>
      <name>yarn.resourcemanager.hostname</name>
      <value>node01</value>
   </property>
   <property>
      <name>yarn.nodemanager.resource.memory-mb</name>
      <value>4096</value>
   </property>
   <property>
      <name>yarn.nodemanager.resource.cpu-vcores</name>
      <value>4</value>
   </property>
   <property>
      <name>yarn.resourcemanager.bind-host</name>
      <value>0.0.0.0</value>
   </property>
   <property>
      <name>yarn.nodemanager.aux-services</name>
      <value>mapreduce_shuffle</value>
   </property>
   <property>
      <name>yarn.nodemanager.aux-services.mapreduce.shuffle.class</name>
      <value>org.apache.hadoop.mapred.ShuffleHandler</value>
   </property>
</configuration>

A continuación copiaremos el fichero plantilla de MapRecuce (cp mapred-site.xml.template mapred-site.xml), y seguidamente modificaremos el fichero mapred-site.xml básicamente añadiendo contenido entre las etiquetas configuration (estarán vacías), dejándolo tal y como se ve en el siguiente ejemplo. La primera propiedad indica que queremos utilizar YARN, y las siguientes son más específicas para Raspberry, con el objetivo de ajustar el uso de memoria.

<configuration>
   <property>
      <name>mapreduce.framework.name</name>
      <value>yarn</value>
   </property>
   <property>
      <name>mapreduce.map.memory.mb</name>
      <value>256</value>
   </property>
   <property>
      <name>mapreduce.map.java.opts</name>
      <value>-Xmx210m</value>
   </property>
   <property>
      <name>mapreduce.reduce.memory.mb</name>
      <value>256</value>
   </property>
   <property>
      <name>mapreduce.reduce.java.opts</name>
      <value>-Xmx210m</value>
   </property>
   <property>
      <name>yarn.app.mapreduce.am.resource.mb</name>
      <value>256</value>
   </property>
</configuration>

Editaremos el fichero slaves especificando en su interior el nombre de nuestra raspberry, tal y como se muestra en el siguiente ejemplo.

node01

Editaremos el fichero masters especificando en su interior el nombre de nuestra raspberry, tal y como se muestra en el siguiente ejemplo.

node01

Llegados a este punto, reiniciaremos nuestra raspberry (sudo reboot), tras lo cual nos volveremos a conectar por SSH utilizando el usuario hduser, crearemos el directorio para hdfs, y lo formatearemos. Esto lo haremos con los siguientes comandos.

sudo mkdir -p /hdfs/tmp
sudo chown hduser:hadoop /hdfs/tmp
sudo chmod 750 /hdfs/tmp
hdfs namenode -format

A continuación, arrancaremos manualmente Hadoop (hdfs) y YARN (resource scheduler).

start-dfs.sh
start-yarn.sh

La siguiente pantalla capturada muestra la salida de ejecución.

Con esto ya habríamos creado un Cluster de Hadoop con un único nodo. Ahora, vamos a probarlo.

Probando Hadoop en Single Node

Comprobaremos que los demonios de Hadoop y YARN están levantados, ejecutando el comando jps, tal y como se muestra en la siguiente pantalla capturada. Los números de la izquierda son el PID.

Una prueba típica es calcular el número pi con MapReduce, que podemos realizar ejecutando la siguiente línea de código.

hadoop jar /opt/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.6.jar pi 16 1000

La siguiente prueba que vamos a hacer es copiar un fichero al HDFS, y ejecutar un programa mapreduce para contar las palabras de dicho fichero. Descargaremos el fichero de salida, y lo revisaremos en nuestro portátil. Esto lo haremos con los siguientes comandos.

hdfs dfs -copyFromLocal /opt/hadoop/LICENSE.txt /license.txt
hadoop jar /opt/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.6.jar wordcount /license.txt /license-out.txt
hdfs dfs -copyToLocal /license-out.txt
more ~/license-out.txt/part-r-00000 

Seguidamente accederemos a la URL de Hadoop Web UI, para comprobar que está disponible, en http://192.168.1.190:50070

También accederemos a la URL de YARN Web UI, para comprobar que está disponible, en http://192.168.1.190:8088

Añadir Nodos al Cluster de Hadoop

Nos conectaremos por SSH a nuestra raspberry con el usuario hduser. Descargaremos el binario de la versión de Hadoop que deseamos instalar, en nuestro caso Hadoop 2.7.6, lo descomprimiremos en /opt, lo renombraremos como /opt/hadoop, y cambiaremos su propietario. Esto lo realizaremos con los siguientes comandos:

cd /opt
sudo wget http://apache.rediris.es/hadoop/common/hadoop-2.7.6/hadoop-2.7.6.tar.gz
sudo tar -xvzf hadoop-2.7.6.tar.gz
sudo mv hadoop-2.7.6 hadoop
sudo chown -R hduser:hadoop hadoop

Ahora vamos a establecer varias variables de entorno para el usuario hduser. Para ello, volveremos al directorio home del usuario hduser, y editaremos el fichero .bashrc añadiendo al final del mismo las siguientes líneas.

export JAVA_HOME=$(readlink -f /usr/bin/java | sed "s:bin/java::")
export HADOOP_HOME=/opt/hadoop
export HADOOP_INSTALL=$HADOOP_HOME
export YARN_HOME=$HADOOP_HOME
export PATH=$PATH:$HADOOP_INSTALL/bin:$HADOOP_INSTALL/sbin
export HADOOP_USER_CLASSPATH_FIRST=true

Copiaremos desde node01 los ficheros de configuración que hemos personalizado, al resto de nodos del Cluster, para lo cual podemos ejecutar un conjunto de comandos como los siguientes para cada nodo.

scp core-site.xml node02:/opt/hadoop/etc/hadoop/core-site.xml
scp hdfs-site.xml node02:/opt/hadoop/etc/hadoop/hdfs-site.xml
scp yarn-site.xml node02:/opt/hadoop/etc/hadoop/yarn-site.xml
scp mapred-site.xml node02:/opt/hadoop/etc/hadoop/mapred-site.xml
scp slaves node02:/opt/hadoop/etc/hadoop/slaves
scp masters node02:/opt/hadoop/etc/hadoop/masters

Crearemos el directorio para hdfs en el resto de Raspberrys. Esto lo haremos con los siguientes comandos.

sudo mkdir -p /hdfs/tmp
sudo chown hduser:hadoop /hdfs/tmp
sudo chmod 750 /hdfs/tmp

Conectados a node01 por SSH, reiniciaremos la Raspberry y borraremos el directorio de hdfs (luego lo vamos a formatear), para lo cual ejecutaremos los siguientes comandos.

sudo reboot
sudo rm -rf /hdfs/tmp/*

Editaremos el fichero de configuración hdfs-site.xml en cada uno de los nodos (vi /opt/hadoop/etc/hadoop/hdfs-site.xml) y lo modificaremos dejando el ratio de sincronización que deseamos. En el siguiente ejemplo se ha dejado en 2, para que cada dato se copia al menos a 2 nodos.

<configuration>
   <property>
      <name>dfs.replication</name>
      <value>2</value>
   </property>
</configuration>

Editaremos el fichero de configuración slaves en node01 (vi /opt/hadoop/etc/hadoop/slaves), e introduciremos el nombre de todos los nodos del Cluster. El siguiente ejemplo sería para un Cluster formado por sólo dos nodos.

node01
node02

Editaremos el fichero de configuración slaves en cada uno de los nodos excepto en node01 (vi /opt/hadoop/etc/hadoop/slaves), dejándolo configurado con el nombre del nodo local (node01 seguirá almacenando el nombre de todos los nodos). Por ejemplo, en node02 el valor será el siguiente.

node02

Conectados a node01 por SSH, formatearemos hdfs, arrancaremos manualmente Hadoop (hdfs) y YARN (resource scheduler). Para ello ejecutaremos los siguientes comandos. Téngase en cuenta, que con ejecutarlos sólo una vez en node01, se arrancarán los servicios en todos los nodos del Cluster.

hdfs namenode -format
start-dfs.sh
start-yarn.sh

Llegados a este punto, podríamos repetir las pruebas que realizamos anteriormente con el Cluster de un único nodo, y así comprobar el funcionamiento. Un detalle relevante, es que con el comando jps podremos ver como node02  sólo es un nodo de datos, teniendo menos servicios levantados que node01, que seguirá teniendo levantados los mismos servicios que cuando teníamos un Cluster Hadoop de un único nodo. A continuación se muestra la salida de ejecución del comando jps en node02.

Instalación de Hive 2.1.1

A continuación vamos a instalar Hive en su versión 2.1.1 sobre node01. Hive sólo necesita ser instalado en el nodo maestro (master node). Para simplificar la instalación, crearemos el metastore de Hive utilizando una base de datos Derby (es decir, ficheros en el filesystem local). Este es el método por defecto, aunque lo recomedable es utilizar una base de datos relacional como MySQL para evitar problemas de corrupción, permitir múltiples sesiones de Hive, etc. No obstante, para comenzar, y desde un punto de vista didáctico, con Derby sería suficiente.

El primer paso, será descargar y descomprimir hive, dejándolo con los permisos correctos, para que tenga acceso el usuario hduser.

cd /opt
wget http://apache.rediris.es/hive/hive-2.1.1/apache-hive-2.1.1-bin.tar.gz
sudo tar -xzvf apache-hive-2.1.1-bin.tar.gz
sudo mv apache-hive-2.1.1-bin hive
sudo chown -R hduser:hadoop /opt/hive

Modificaremos el fichero .bashrc del usuario hduser en node01 (vi /home/hduser/.bashrc) para añadir hive al path, así como establecer la variable de entorno HIVE_HOME. En nuestro caso de ejemplo, añadiremos las siguientes dos líneas.

export HIVE_HOME=/opt/hive
export PATH=$PATH:$HIVE_HOME/bin

Realizado esto, conectados por SSH a node01, pararemos los servicios de YARN y Hadoop, reiniciaremos, y volveremos a arancar Hadoop y YARN. A continuación se muestran los comandos que utilizaríamos.

stop-yarn.sh
stop-dfs.sh
sudo reboot
start-dfs.sh
start-yarn.sh

Ahora vamos a inicializar Hive. Veremos que esto crea un directorio metastore_db, donde se almacenará el metastore de Hive. Una vez inicializado, accederemos a la línea de comandos de hive, utilizando el comando hive. Estas tareas las realizaremos con los siguientes comandos.

cd ~
schematool -initSchema -dbType derby
ls -l
hive

A continuación se muestra un ejemplo de salida de ejecución.

Instalación de Spark 2.1

El primer paso, será descargar y descomprimir spark, dejándolo con los permisos correctos, para que tenga acceso el usuario hduser. Esto lo haremos en todos los nodos. Los comandos a ejecutar serían similares a los siguientes.

cd /opt
wget https://archive.apache.org/dist/spark/spark-2.1.0/spark-2.1.0-bin-hadoop2.7.tgz
sudo tar -xzvf spark-2.1.0-bin-hadoop2.7.tgz
sudo mv spark-2.1.0-bin-hadoop2.7 spark
sudo chown -R hduser:hadoop /opt/spark

Modificaremos el fichero .bashrc del usuario hduser en todas las Raspberry (vi /home/hduser/.bashrc) para añadir Spark al path, así como establecer las variables de entorno de Spark. En nuestro caso de ejemplo, añadiremos las siguientes dos líneas.

export SPARK_HOME=/opt/spark
export SPARK_CONF_DIR=/opt/spark/conf
export SPARK_MASTER_HOST=node01
export PATH=$PATH:$SPARK_HOME/bin:$SPARK_HOME/sbi

Conectados por SSH a node01, pararemos los servicios de YARN y Hadoop, y crearemos el fichero de configuración de los Workers de Spark, desde la plantilla.

stop-yarn.sh
stop-dfs.sh
cd /opt/spark/conf
cp slaves.template slaves

Editaremos el fichero de configuración de los Workers de Spark (vi /opt/spark/conf/slaves), especificando los nombres de todos los nodos de nuestros Cluster. El siguiente ejemplo sería para un Cluster con dos nodos.

node01
node02

Crearemos en todas las Raspberry el fichero de configuración spark-defaults.conf como una copia del fichero que incluye spark como plantilla (spark-defaults.conf.template), y lo editaremos.

cp spark-defaults.conf.template spark-defaults.conf
vi spark-defaults.conf

Estableceremos el valor de spark.executor.memory a 512 MB, para de este modo intentar ajustar la configuración de Spark al hardware limitado de nuestras Raspberry.

Conectados por SSH a node01, arrancaremos los servicios de YARN, Hadoop, y Spark (tanto Maestro como Workers), y comprobaremos que los servicios están levantados.

start-dfs.sh
start-yarn.sh
start-master.sh
start-slaves.sh
jps

A continuación se muestra cómo sería la salida de ejecución en node01.

Seguidamente ejecutaremos el commando jps en node02 para comprobar qué servicios tiene levantados. Como podemos ver, ahora también aparece levantado el servicio de Worker correspondiente a Spark.

Accederemos al Spark Master Web UI, disponible en el Puerto 8080 del nodo Master (en nuestro caso node01), para lo cual utilizaremos la URL http://192.168.1.190:8080/

Despedida y Cierre

Hasta aquí llega el presente artículo, en el cual hemos intentado ver la instalación y configuración básica de Hadoop, Hive, y Spark, utilizando como campo un conjunto de Raspberry. Aprovecho para compartir algunos enlaces de interés, para quien desee ampliar más información.

Poco más por hoy. Como siempre, confío que la lectura resulte de interés.

 


[Fecha del Artículo (UTC): 18/05/2018]
[Autor: GuilleSQL]



Escribir un Comentario

Para poder escribir un comentario, debe Iniciar Sesión con un usuario.

Si no dispone de un usuario, puede Registrarse y hacerse miembro.

Si dispone de un usuario, pero no recuerda sus credenciales de acceso, puede Restablecer su Contraseña.

Miembros de
Miembros de GITCA (Global IT Community Association)

Menu de Usuario
  Iniciar Sesión
  Registrarse
  Restablecer Contraseña
  Ventajas de Registrarse

Acerca de
  Contigo desde Oct 2007
  771 usuarios registrados
  86146 pageloads/mes
  Ranking Alexa 498160

Social Networks
Sigue a Portal GuilleSQL en Linkedin !!
Sigue a Portal GuilleSQL en Twitter !!



Archivo

Junio de 2018 (3)
Mayo de 2018 (5)
Abril de 2018 (3)
Marzo de 2018 (2)
Febrero de 2018 (7)
Enero de 2018 (1)
Diciembre de 2017 (15)
Noviembre de 2017 (7)
Junio de 2017 (3)
Mayo de 2017 (1)
Marzo de 2017 (3)
Enero de 2017 (4)
Junio de 2016 (1)
Mayo de 2016 (2)
Abril de 2016 (2)
Septiembre de 2015 (2)
Agosto de 2015 (2)
Junio de 2015 (10)
Mayo de 2015 (4)
Abril de 2015 (8)
Marzo de 2015 (11)
Octubre de 2014 (3)
Septiembre de 2014 (7)
Agosto de 2014 (5)
Julio de 2014 (2)
Mayo de 2014 (4)
Abril de 2014 (4)
Marzo de 2014 (4)
Febrero de 2014 (1)
Enero de 2014 (5)
Diciembre de 2013 (8)
Noviembre de 2013 (2)
Octubre de 2013 (7)
Septiembre de 2013 (6)
Agosto de 2013 (1)
Julio de 2013 (6)
Junio de 2013 (11)
Mayo de 2013 (7)
Abril de 2013 (6)
Febrero de 2013 (5)
Enero de 2013 (7)
Diciembre de 2012 (12)
Noviembre de 2012 (13)
Octubre de 2012 (5)
Septiembre de 2012 (3)
Agosto de 2012 (6)
Julio de 2012 (4)
Junio de 2012 (1)
Mayo de 2012 (2)
Abril de 2012 (7)
Marzo de 2012 (16)
Febrero de 2012 (9)
Enero de 2012 (5)
Diciembre de 2011 (10)
Noviembre de 2011 (10)
Octubre de 2011 (4)
Septiembre de 2011 (5)
Agosto de 2011 (2)
Julio de 2011 (2)
Junio de 2011 (4)
Mayo de 2011 (2)
Abril de 2011 (6)
Marzo de 2011 (4)
Febrero de 2011 (10)
Enero de 2011 (5)
Diciembre de 2010 (6)
Noviembre de 2010 (4)
Octubre de 2010 (8)
Septiembre de 2010 (4)
Agosto de 2010 (1)
Julio de 2010 (3)
Mayo de 2010 (5)
Abril de 2010 (6)
Marzo de 2010 (8)
Febrero de 2010 (3)
Enero de 2010 (1)
Diciembre de 2009 (9)
Noviembre de 2009 (14)
Octubre de 2009 (2)
Septiembre de 2009 (8)
Agosto de 2009 (2)
Julio de 2009 (10)
Junio de 2009 (9)
Mayo de 2009 (10)
Abril de 2009 (9)
Marzo de 2009 (3)
Febrero de 2009 (2)
Enero de 2009 (3)
Noviembre de 2008 (2)
Octubre de 2008 (2)
Septiembre de 2008 (2)
Agosto de 2008 (5)
Julio de 2008 (5)
Junio de 2008 (1)
Mayo de 2008 (3)
Abril de 2008 (2)
Marzo de 2008 (2)
Febrero de 2008 (2)
Enero de 2008 (5)
Noviembre de 2007 (2)
Octubre de 2007 (2)






Esta información se proporciona "como está" sin garantías de ninguna clase, y no otorga ningún derecho.
This information is provided "AS IS" with no warranties, and confers no rights.

Copyright © 2007 GuilleSQL, todos los derechos reservados.
GuilleSQL.com y GuilleSQL.net son también parte de Portal GuilleSQL.

Visitas recibidas (Page Loads) en GuilleSQL (fuente: StatCounter):

screen resolution stats
Visitas