Bloggers recientes

 

[ Blog ]
[ Wiki ]
[ Slideshare ]
[ Twitter ]
[ YouTube ]
Gustavo Fernandez Mensajes: 65
Estrellas: 7
Fecha: 27/08/14
Cesar Capillas Mensajes: 154
Estrellas: 7
Fecha: 25/08/14

Archivo

Tags

noBlogo - El blog de zylk.net

Cargando librerias nativas para hadoop 2, come evitar el WARNING Unable to load native-hadoop library

Siguiendo con los posts anteriores (I, II) relacionados con el laboratorio de hadoop 2, el primer post dejé un warning en el arranque de hdfs sin resolver. El warning está relacionado con el uso de librerías nativas del sistema operativo para los procesos de compresión y descompresión. Parece que estos procesos realizados por medio de código java son un 40% más lentos que si los realizan los comandos nativos del sistema operativo. Así que hemos montado el laboratiorio para que haga uso de esas librerías nativas. Para ello hemos tenido que recompilar el producto para poder generar unas librerías .so y .a que hacen de pasarela (supongo que por JNI), a las librerías nativas. Hadoop al arrancar las detecta y las carga en vez de cargar las implementaciones nativas 100% java.

Los pasos han sido los siguientes:

  • Instalar las dependencias necesarias (usamos ubuntu)

>>>sudo aptitude install  zlib1g zlib1g-dbg  zlib1g-dev zlibc libssl-dev lbzip2  libzip-dev libzip2 pbzip2

  • Instalamos las dependencias para poder compilar con make, maven etc.

>>>sudo apt-get install build-essential
>>>sudo apt-get install g++ autoconf automake libtool cmake zlib1g-dev pkg-config libssl-dev
>>>sudo apt-get install maven

  • descargamos protobuf y lo compilamos

>>>wget https://protobuf.googlecode.com/svn/rc/protobuf-2.5.0.tar.gz
>>>tar xzf protobuf-2.5.0.tar.gz
>>>cd protobuf-2.5.0
>>>./configure
>>>make
>>>sudo make install
>>>sudo ldconfig

  • descargamos el código fuente de hadoop.-2.5.0 y lo compilamos con maven

>>>mvn package -Pdist,native -DskipTests -Dtar


Ahora ya podemos usar las nuevea libs para arquitecturas iguales, cada nodo de arquitectura distinta... a recompilar.

Y ya no sale el warning en el arranque de hdfs

WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable

 

Montando un laboratorio de big-data basado en hadoop 2 servicios arrancados

Siguiendo con el post anterior, los servicios que al final hemos arrancado, y la forma de arrancarlos es la siguiente:

Arrancar el filesystem distribuido, el yarn y el servidor de histórico de tares realizadas por yarn
>>>hadoop@lug000:/zoo/hadoop-2.5.0/sbin$ ./start-dfs.sh
>>>hadoop@lug000:/zoo/hadoop-2.5.0/sbin$ ./start-yarn.sh
>>>hadoop@lug000:/zoo/hadoop-2.5.0/sbin$ ./mr-jobhistory-daemon.sh start historyserver


Arrancar el gateway de nfs
>>>hadoop@lug000:/zoo/hadoop-2.5.0/bin$ sudo ./hdfs portmap
>>>hadoop@lug000:/zoo/hadoop-2.5.0/bin$ sudo ./hdfs nfs3

 

UPDATE:

Hemos incorporado hbase al laboratorio

>>>hadoop@lug000:/zoo/hbase-0.98.5-hadoop2$ ./bin/start-hbase.sh

Y además añado el resumen de las consolas web de los distintos servicios

http://lug000.zylk.net:50070 -> hdfs
http://lug000.zylk.net:8088 -> yarn
http://lug000.zylk.net:19888 -> yarn jobhistory
http://lug000.zylk.net:60010 -> hbase



Comprobar que estan los servicios arrancados
>>>hadoop@lug000:/zoo/hadoop-2.5.0/sbin$ sudo jps
4558 NameNode
12804 ResourceManager
13494 Nfs3
13088 JobHistoryServer
4971 SecondaryNameNode
13182 Portmap

Alfresco Shell Tools

Las Alfresco Shell Tools ofrecen una un conjunto de scripts de shell para administradores e integradores de sistemas en Alfresco que utilizan el API REST / Webscript. Estas herramientas de shell son muy interesantes en la gestión, mantenimiento y automatización de entornos de Alfresco, por ejemplo para crear un entorno con cientos de sites o tenants, la recreación de miles de usuarios y grupos locales, tareas de backup y mantenimiento de permisos, o la sincronización avatares o generación de thumbnails. Te las puedes descargar desde aquí:

https://code.google.com/p/alfresco-shell-tools/


En la instalación (por ejemplo en Ubuntu) requerimos de algunas dependencias como el paquete jshon y de las librerías jasson, tal y como se describe en la documentación wiki. Para ejecutar los scripts de Alfresco Shell Tools necesitamos de ciertas variables de entorno, que apuntan a la capa de servicios de Alfresco así como de un usuario y contraseña con permisos de admin. Supongamos que estas herramientas se ejecutan desde nuestro servidor Alfresco, aunque pueden ejecutarse desde un cliente y atacar a diferentes Alfresco remotos segun se definan las siguientes variables de entorno.

$ source exportENVVARS.sh

#! /bin/bash
export PATH="$PATH:."
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:."
export ALFTOOLS_ENDPOINT=http://localhost:8080/alfresco
export ALFTOOLS_SHARE_ENDPOINT=http://localhost:8080/share
export ALFTOOLS_USER=admin
export ALFTOOLS_PASSWORD=secret

Para comprobar que todo esta listo podemos ejecutar:

$ alfSearch.sh alfresco

que busca los nodos con el texto alfresco, y debe dar un listado de nodos. En la página de googlecode existen bastantes ejemplos.

A continuación, voy a ilustrar su uso con algunos comandos típicos que pueden ser útiles en una hipotética migración potencial de sitios y usuarios de un Alfresco a otro. Nota: Es necesario tener en cuenta que los scripts de a continuación pueden necesitar filtrados adicionales y convenios, y que el proceso es meramente ilustrativo. También hay que tener en cuenta en los ejemplos de a continuación que cuando se crea un Site en Alfresco hay una estructura de grupos de usuarios detrás.

Comencemos por ejemplo listando los grupos de Alfresco con:

$ alfListGroups.sh

GROUP_ALFRESCO_ADMINISTRATORS
GROUP_EMAIL_CONTRIBUTORS
GROUP_alfrescoSiteCreators
GROUP_site_swsdp
GROUP_site_swsdp_SiteCollaborator
GROUP_site_swsdp_SiteConsumer
GROUP_site_swsdp_SiteContributor
GROUP_site_swsdp_SiteManager

Podemos diferenciar dos tipos de grupos de manera sencilla, los de sitio (GROUP_site_) y los que no. De modo que los grupos que no son de sitios (locales + ldap) se pueden listar de la siguiente manera:

$ alfListGroups.sh | grep -v "_site_"

GROUP_ALFRESCO_ADMINISTRATORS
GROUP_EMAIL_CONTRIBUTORS
GROUP_alfrescoSiteCreators

Por lo tanto, podriamos obtener los nombres cortos de los sitios de la siguiente manera:

$ ./alfListGroups.sh | grep "_site_" | awk -F"_" '{print $3}' | uniq

swsdp

Considerando este listado en un archivo sites.txt podemos crear un archivo de comandos para nuestro target Alfresco como:

#! /bin/bash
for i in `cat sites.txt`;
 do
   alfCreateSite.sh -s "$1" -d "Descripcion de $1" -a PRIVATE "Titulo de $1"
 done


o bien si en el archivo sites.txt disponemos de los datos del nombre corto del sitio, descripción y titulo separado por comas podríamos generar un archivo de comandos para nuestro servidor target.

$ awk -F"," '{print "alfCreateSite.sh -s "$1" -d "$2" -a PRIVATE " $3""}' sites.txt | sort | uniq

alfCreateSite.sh -s "nombre-sitio-1" -d "Descripcion de sitio 1" -a PRIVATE "Titulo de sitio 1"
alfCreateSite.sh -s "nombre-sitio-2" -d "Descripcion de sitio 2" -a PRIVATE "Titulo de sitio 2"
alfCreateSite.sh -s "nombre-sitio-3" -d "Descripcion de sitio 3" -a PRIVATE "Titulo de sitio 3"
alfCreateSite.sh -s "nombre-sitio-4" -d "Descripcion de sitio 4" -a PRIVATE "Titulo de sitio 4"

Para ejecutarlo contra el servidor target sería necesario cambiar las variables de entorno y ejecutar ese archivo de comandos generado. También podemos obtener la estructura completa de grupos y usuarios con el siguiente script de extracción (AlfrescoAllGroups.sh) y filtrarla según nuestras necesidades:

#! /bin/bash
for i in `./alfListGroups.sh`;
  do
  LISTA=`./alfListGroupMembers.sh $i`;
  for j in $LISTA;
    do
      echo $i,$j
    done
  done


que daría algo así:

GROUP_ALFRESCO_ADMINISTRATORS,admin
GROUP_ALFRESCO_ADMINISTRATORS,cesar
GROUP_EMAIL_CONTRIBUTORS,admin
GROUP_EMAIL_CONTRIBUTORS,cesar
GROUP_site_swsdp_SiteCollaborator,abeecher
GROUP_site_swsdp_SiteManager,admin
GROUP_site_swsdp_SiteManager,mjackson
GROUP_site_swsdp_SiteManager,cesar

y que puede ser la entrada de la asignación de usuarios locales a otro servidor Alfresco (usuarios-carga.txt) mediante el comando sed (transformacion):

$ AlfrescoAllGroups.sh | sed -e 's/GROUP_//g' > usuarios-carga.txt

ALFRESCO_ADMINISTRATORS,admin
ALFRESCO_ADMINISTRATORS,cesar
EMAIL_CONTRIBUTORS,admin

Con lo que podemos crear un archivo de comandos de carga como este para ejecutar:

$ awk -F"," '{print "alfAddAuthorityToGroup.sh " $1 " " $2}' usuarios-carga.txt | sort | uniq

$ alfAddAuthorityToGroup.sh ALFRESCO_ADMINISTRATORS cesar
$ alfAddAuthorityToGroup.sh EMAIL_CONTRIBUTORS cesar
$ alfAddAuthorityToGroup.sh site_swsdp_SiteManager cesar


En este último paso, se utiliza un comando que permite añadir usuarios a grupos (y por tanto a Sites) y sería necesario excluir los datos ya existentes o por defecto en nuestro repositorio.

En definitiva, toda una navaja suiza para administradores e integradores de Alfresco. Las pruebas de arriba estan hechas con las versiones 4.2.c CE y 4.1.x EE de Alfresco.

Montando un laboratorio de big data basado en Hadoop 2

LLevamos ya un tiempo usando el llamado zoo de hadoop para hacer algunos proyectos relacionados con big-data. Hasta ahora siempre hemos usado la versión de hadoop 1.x porque era la versión con la que empezamos a hacer las pruebas de concepto. Pero como parece ya seguro que hadoop ha venido para quedarse no está de más hacer pruebas con las nuevas versiones. En concreto hemos montado un laboratorio de hadoop con última versión estable, que a día de hoy es la 2.5. La hemos montado para analizar las siguientes características:

 

A grandes rasgos tenemos, un laboratorio con 5 nodos (lug000.zylk.net, lug002.zylk.net, lug004.zylk.net, lug005.zylk.net, lug006.zylk.net) que está montado con ordenadores viejos de 32 bits y unas maquinas virtuales de 64 bits para hacerlo lo más heterogeneo posible. Estas 5 máquinas están conectadas por medio de una red de 1 GB, porque uno de los temas críticos entendemos que es la comunicación entre los nodos. En cada máquina descomprimimos la versión de hadoop 2.5.0 y configuramos los archivos necesarios (.sh de entorno y configuraciones generales mínimas http://hadoop.apache.org/docs/r2.5.0/hadoop-project-dist/hadoop-common/ClusterSetup.html). Una vez hemos hecho esto, y teniendo en cuenta que las llaves ssh las teníamos ya configuradas correctamente porque este laboratorio se ha usado para probar la versión 1.x podemos proceder a arrancar el culster.

Previamente a esto preparamos el namenode del hdfs.

>>>hadoop@lug000:/zoo/hadoop-2.5.0/bin$ ./hdfs namenode -format lug000.zylk.net
14/08/25 10:08:19 INFO common.Storage: Storage directory /zoo/data/namenode0 has been successfully formatted.
14/08/25 10:08:19 INFO common.Storage: Storage directory /zoo/data/namenode1 has been successfully formatted.
14/08/25 10:08:19 INFO common.Storage: Storage directory /zoo/data/namenode2 has been successfully formatted.

Y arrancamos el file system distribuido:

>>>hadoop@lug000:/zoo/hadoop-2.5.0/sbin$ ./start-dfs.sh
14/08/25 10:09:37 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Starting namenodes on [lug000.zylk.net]
lug000.zylk.net: starting namenode, logging to /zoo/hadoop-2.5.0/logs/hadoop-hadoop-namenode-lug000.out
lug002.zylk.net: starting datanode, logging to /zoo/hadoop-2.5.0/logs/hadoop-hadoop-datanode-lug002.out
lug004.zylk.net: starting datanode, logging to /zoo/hadoop-2.5.0/logs/hadoop-hadoop-datanode-lug004.out
Starting secondary namenodes [0.0.0.0]
0.0.0.0: starting secondarynamenode, logging to /zoo/hadoop-2.5.0/logs/hadoop-hadoop-secondarynamenode-lug000.out
14/08/25 10:09:58 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable

Habrá que revisar el warning ... aunque de momento no lo vamos a analizar. Podemos conectarnos ya a la consola del file system distribuido y ver el cluster (como estamos haciendo pruebas, de momento solo hemos usado tres nodos de los 5 disponibles)

 


Para ver que todo esta ok, vamos a subir un fichero al sistema

>>>hadoop@lug000:/zoo/hadoop-2.5.0/bin$ ./hdfs dfs -put /tmp/text.txt /text.txt
14/08/25 10:15:00 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable

Y podemos verlo desde la interfaz gráfica




Del filesystem distribuido nos interesa además la nueva característica relacionada con los atributos extras (http://mapredit.blogspot.com.es/2014/07/xattr-are-coming-to-hdfs.html, http://blog.cloudera.com/blog/2014/06/why-extended-attributes-are-coming-to-hdfs/) que en realidad permite asociar datos al fichero a modo de meta-datos simples.

Vamos a asignar al fichero un autor, para hacer la prueba.

>>>hadoop@lug000:/zoo/hadoop-2.5.0/bin$ ./hdfs dfs -setfattr -n 'user.author' -v 'zylk.net' /text.txt
14/08/25 10:21:16 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable


Una vez asignado podemos acceder a su valor de la siguiente manera

>>>hadoop@lug000:/zoo/hadoop-2.5.0/bin$ ./hdfs dfs -getfattr -d /text.txt
14/08/25 10:22:27 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
# file: /text.txt
user.author="zylk.net"


O directamente al valor del atributo

>>>hadoop@lug000:/zoo/hadoop-2.5.0/bin$ ./hdfs dfs -getfattr -n 'user.author' /text.txt
14/08/25 10:24:05 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
# file: /text.txt
user.author="zylk.net"



Una vez que hemos hecho las pruebas mínimas del file system distribuido vamos a probar el nuevo motor para map&reduce basado en yarn, la verdad es que el nuevo motor ha sufrido un cambio radical desde el punto de vista de arquitectura. Vamos a decir que yarn es un motor/framework para escribir aplicaciones distribuidas y un ejemplo de una de estas aplicaciones es Map&Reduce (http://es.slideshare.net/cloudera/introduction-to-yarn-and-mapreduce-2).


Lo primero arrancamos los procesos necesarios

>>>hadoop@lug000:/zoo/hadoop-2.5.0/sbin$ ./start-yarn.sh
starting yarn daemons
starting resourcemanager, logging to /zoo/hadoop-2.5.0/logs/yarn-hadoop-resourcemanager-lug000.out
lug004.zylk.net: starting nodemanager, logging to /zoo/hadoop-2.5.0/logs/yarn-hadoop-nodemanager-lug004.out
lug002.zylk.net: starting nodemanager, logging to /zoo/hadoop-2.5.0/logs/yarn-hadoop-nodemanager-lug002.out


Y vemos que disponemos de una nueva consola web para el seguimiento de la tareas que se van a ejecutar dentro de framework yarn

 





Con el proipo yarn viene con unos cuantos ejemplos de map&reduce. Vamos a ejecutar uno de ellos para ver que está todo correcto. En este caso vamos a calcular el valor de pi usando el método montercarlo (http://centros5.pntic.mec.es/ies.de.bullas/dp/matema/conocer/numpi_probabilidad.htm)

>>>hadoop@lug000:/zoo/hadoop-2.5.0/bin$ ./yarn jar ../share/hadoop/mapreduce/hadoop-mapreduce-examples-2.5.0.jar pi 16 10000
Number of Maps  = 16
Samples per Map = 10000
14/08/25 10:34:25 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Wrote input for Map #0
Wrote input for Map #1
Wrote input for Map #2
Wrote input for Map #3
Wrote input for Map #4
Wrote input for Map #5
Wrote input for Map #6
Wrote input for Map #7
Wrote input for Map #8
Wrote input for Map #9
Wrote input for Map #10
Wrote input for Map #11
Wrote input for Map #12
Wrote input for Map #13
Wrote input for Map #14
Wrote input for Map #15
Starting Job
14/08/25 10:34:29 INFO client.RMProxy: Connecting to ResourceManager at lug000.zylk.net/192.168.1.100:8032
14/08/25 10:34:30 INFO input.FileInputFormat: Total input paths to process : 16
14/08/25 10:34:30 INFO mapreduce.JobSubmitter: number of splits:16
14/08/25 10:34:30 INFO mapreduce.JobSubmitter: Submitting tokens for job: job_1408955506111_0001
14/08/25 10:34:31 INFO impl.YarnClientImpl: Submitted application application_1408955506111_0001
14/08/25 10:34:31 INFO mapreduce.Job: The url to track the job: http://lug000.zylk.net:8088/proxy/application_1408955506111_0001/
14/08/25 10:34:31 INFO mapreduce.Job: Running job: job_1408955506111_0001
14/08/25 10:34:50 INFO mapreduce.Job: Job job_1408955506111_0001 running in uber mode : false
14/08/25 10:34:50 INFO mapreduce.Job:  map 0% reduce 0%
14/08/25 10:35:17 INFO mapreduce.Job:  map 13% reduce 0%
14/08/25 10:35:18 INFO mapreduce.Job:  map 31% reduce 0%
14/08/25 10:35:19 INFO mapreduce.Job:  map 38% reduce 0%
14/08/25 10:35:22 INFO mapreduce.Job:  map 44% reduce 0%
[...]
    File Input Format Counters
        Bytes Read=1888
    File Output Format Counters
        Bytes Written=97
Job Finished in 65.688 seconds
Estimated value of Pi is 3.14127500000000000000



Con esto solo nos quedaría ver como funciona el gateway nfs.. que lo dejaremos para otro artículo. También montaremos hbase sobre hadoop-2, así como el resto de herramientas alineadas con el I+D+i de zylk.net, para poder aportar valor en la gestión documental y la inteligencia de negocio principalmente.
 

Procesos de importación masiva de datos en Alfresco con Filesystem Bulk Import
Uno de los procesos más usuales en la implantación o migración de un gestor documental es la carga de contenidos. Esta carga (inicial o no) puede requerir desplegar una estructura de espacios y documentos en Alfresco, y en casos avanzados de una migración de sus permisos (de owner y heredados), metadatos y versiones. Una herramienta que viene de serie con Alfresco es el módulo de importación de Filesystem Bulk, que permite migrar datos desde unidades locales en el servidor, estructuras de directorios y documentos a través de unos servicios REST expuestos por el módulo. Los tiempos de carga son realmente mejores que mediante cualquier otro método basado en CIFS, Webdav o via API (como CMIS o WS) o incluso ACPs (Alfresco Content Package).
 
La importación se realizar a través de un webscript en la url:
 
http(s)://alfrescoserver/alfresco/service/bulkfsimport
 
donde se especifican principalmente:
  • El directorio de contenidos a importar (Import directory): Directorio local del servidor a importar.
  • El espacio objetivo (Target space): Espacio de Alfresco o nodo de Alfresco donde se va a importar la estructura local especificacda. Dispone de una búsqueda live query de espacios sobre el repositorio.

Dispone de opciones para:

  • Deshabilitar las reglas de contenido.
  • Reemplazar los archivos, que indica si está permitido modificar documentos en caso de que ya existan en la carpeta destino.
  • El tamaño del batch en una transacción (tipicamente el número de cores *2 = p.ej 4)
  • El número de hilos paralelos a ejecutar durante el proceso (por ejemplo 100). Si hay un error fallará todo el batch.

Se puede ejecutar via el formulario o incluso via curl. Hay ciertas restricciones como comenta la documentación del módulo.

  • No hay soporte de AVM.
  • Sólo un import puede hacerse cada vez (debido al JobLockService).
  • El acceso a la herramienta de importación está restringida a los administradores de Alfresco y no a los usuarios potenciales del ECM. 
 
Os dejo algunas recomendaciones a la hora de hacer una importación:
 
- Parametrizar el alfresco-global.properties para que no haga esfuerzos durante las cargas.
 
# ECM content usages/quotas
system.usages.enabled=false
system.enableTimestampPropagation=false
 
- Parametrizar los batches de carga (también se especifican en el formulario).
 
# Numero de threads: numero de cores * 2 
bulkImport.batch.numThreads=4 
# Tamaño del batch
bulkImport.batch.batchSize=100
 
- Configurar el logger de la carga en el custom-log4j.properties en el directorio extension para obtener más información sobre la carga realizada y los errores:
 
log4j.logger.org.alfresco.repo.batch.BatchProcessor=info
log4j.logger.org.alfresco.repo.transaction.RetryingTransactionHelper=info
 
- Minimizar los postprocesos cuando sea posible, porque no van a ser lo adecuado de cara al rendimiento. Por ejemplo, reglas de contenido que realizan transformaciones de determinados espacios.
 
- Deshabilitar SOLR durante la carga: Cada 15 segundos el tracker de SOLR está indexando los contenidos por defecto, y esto hace el proceso más lento. Para ello es necesario editar los archivos solrcore.properties y setear la variable enable.alfresco.tracking a false. Tambien se puede hacer via JMX o Alfresco Share Admin Console.
 
- No dejar que se actualice continuamente la página de status del proceso. Aunque es interesante en la actualización continua del proceso se puede perder algo de rendimiento.
 
- Si los procesos de carga son continuos, puede ser adecuado montar un servidor dedicado de carga que no interfiera con el servicio de los usuarios.
 
- Cuando el proceso de bulk acaba puede ser necesario comprobar los nodos con un script como este (tambien es posible obtener más información sobre esto aquí).
 
- Puedes migrar metadatos a través ficheros XML adjuntos en la estructura de documentos y carpetas. Incluso es posible trasladar aquellos que tienen que ver con el aspecto auditable de Alfresco (nombre, creador, fechas de modificación), lo cual es muy interesante. Con los ACPs también es posible pero no mediante métodos de carga basados en APIs CMIS, REST o WS. 
 
- Para la versión Enterprise también existe un modo inplace (en vez del comentado streaming en donde el repositorio ya esta consolidado). 
 
Por último recordar que muchos de los errores habituales en las cargas estánrelacionados con el juego de datos de origen: por ejemplo, con los encodings de los ficheros, con los permisos de acceso, con documentos corruptos cuyo mimetype no coincide con su extensión, con documentos de tamaño cero, o con documentos y carpetas ocultas en el directorio origen. También apuntar que rsync es tu amigo a la hora de sincronizar un determinado contenstore vivo con el directorio de importacion en nuestro servidor.
Mostrando el intervalo 1 - 5 de 248 resultados.
Resultados por página 5
de 50