Archivos de etiquetas: JGroups

Cluster con Hazelcast en Alfresco One 4.2.2

Si hay algo en lo que Alfresco ha trabajado en cada una de las versiones que han visto la luz ha sido el tema de cluster y la comunicación entre los nodos. En las versiones 2.x con EHCache y un sistema de multicast que era bastante pobre, usando JGroups en la 3.x hasta llegar a la 4.2.x con Hazelcast.

Pero, ¿qué es Hazelcast?

Es según la propia página web oficial un “Open Source In-Memory Data Grid”, es decir, una plataforma para la distribución de datos de código abierto. Entre sus características podemos encontrar:

  • Implementaciones distribuidas de Set, List, Map, Lock, MultiMap
  • Mensajería distribuida P/S
  • Soporte transaccional e integración JEE vía JCA
  • Soporte encriptación a nivel de sockets
  • Persistencia síncrona o asíncrona
  • Clusterizado Sesión HTTP
  • Discovery dinámico
  • Monitorización JMX
  • Escalado dinámico
  • Particionado dinámico
  • Fail-over dinámico

Como se puede ver, es una herramienta fantástica para cumplir las especificaciones de cluster que necesita Alfresco.

Las funciones de las que se sirve Alfresco y que son comunes a Hazelcast están:

  • Compartir datos/estados entre varios servidores: como compartición sesión Web
  • Cacheo distribuido de datos
  • Comunicación segura entre servidores
  • Particionado de datos en memoria
  • Distribución de trabajo entre servidores
  • Procesamiento paralelo
  • Gestión fail-safe de datos

Además se lleva muy bien con Hibernate como caché de segundo nivel y con Spring.

¿Cómo configuramos el cluster de Alfresco 4.2.2?

Para configurar un sistema de cluster en Alfresco 4.2.2 es tan fácil como cuando se configuraba con EHCache o JGroups e incluso más todavía y eso sí, se comprueba la fiabilidad que tiene este producto integrado en Alfresco.

Hay que entender que aquí explico solamente como montar el cluster, es decir, que ambos nodos se comuniquen entre sí, un sistema completo de alta disponibilidad requiere de un balanceador ya sea hardware o software, un sistema de cluster en la base de datos, etc.

Lo primero que hay que hacer es quitar cualquier referencia a EHCache y JGroups antiguos, esto va orientado a sistemas que han ido siendo actualizados desde versiones antiguas principalmente:

Por ejemplo, el fichero que está dentro de {alfrescoRoot}/tomcat/shared/clases/alfresco/extensión:

ehcache-custom.xml

También en dicha localización (si existe) el fichero:

hazelcastConfig.xml

Este fichero se ha incluido ya dentro del fichero alfresco.war con lo que no hace falta.

Así como las siguientes propiedades que están dentro de {alfrescoRoot}/tomcat/shared/clases/alfresco-global.properties:

alfresco.cluster.name
alfresco.ehcache.rmi.hostname
alfresco.ehcache.rmi.port
alfresco.ehcache.rmi.remoteObjectPort
alfresco.jgroups.defaultProtocol
alfresco.jgroups.bind_address
alfresco.jgroups.bind_interface
alfresco.tcp.start_port
alfresco.tcp.initial_hosts
alfresco.tcp.port_range
alfresco.udp.mcast_addr
alfresco.udp.mcast_port
alfresco.udp.ip_ttl
filesystem.cluster.enabled
filesystem.cluster.configFile

Configuración del cluster para el repositorio

Por defecto si apuntamos dos instancias de Alfresco al mismo repositorio y base de datos, estos formarán de forma automática un grupo de repositorio, no obstante hay que realizar una pequeña configuración para que todo funcione correctamente.

Montar el repositorio de forma compartida y visible para todos los nodos, por ejemplo vía NAS o SAN a través de protocolo NFS.

Configurar el acceso a la base de datos para la misma base de datos en cada uno de los nodos.

Abrir el puerto 5701 TCP en el cortafuegos de los nodos para que puedan ser accesibles entre ellos.

Especificar correctamente la IP (sea en wildcard como por ejemplo 192.168.1.*) de la tarjeta de red del cluster:

alfresco.cluster.interface=192.168.1.101

Fijar la propiedad para activar Hazelcast en JMX

hazelcast.jxm=true

Y por razones de seguridad se debería fijar la contraseña con la siguiente propiedad:

alfresco.hazelcast.password=

Un ejemplo de la parte del fichero alfresco-global.properties para la configuración del cluster puede ser la siguiente:

alfresco.cluster.enabled=true
alfresco.cluster.interface=192.168.1.101
alfresco.hazelcast.password=clavehazelcast
alfresco.hazelcast.port=5701
alfresco.hazelcast.autoinc.port=false
alfresco.hazelcast.mancenter.enabled=false
alfresco.hazelcast.max.no.heartbeat.seconds=15

Una vez arrancada la primera instancia se puede observar un mensaje como el siguiente:

2014-06-30 22:38:36,148 INFO [cluster.core.ClusteringBootstrap] [localhost-startStop-1] Cluster started, name: MainRepository-fea9ebdf-04f3-495e-9456-cf43c24b8e91
2014-06-30 22:38:36,152 INFO [cluster.core.ClusteringBootstrap] [localhost-startStop-1] Current cluster members:
192.168.1.101:5701 (hostname: alfnode1.localdomain)

Finalmente al arrancar el segundo en este se observará lo siguiente:

2014-07-02 10:58:12,108 INFO [cluster.core.ClusteringBootstrap] [localhost-startStop-1] Cluster started, name: MainRepository-fea9ebdf-04f3-495e-9456-cf43c24b8e91
2014-07-02 10:58:12,111 INFO [cluster.core.ClusteringBootstrap] [localhost-startStop-1] Current cluster members:
192.168.1.102:5701 (hostname: alfnode2.localdomain)
192.168.1.101:5701 (hostname: alfnode1.localdomain)

También se puede ver que el cluster está bien configurado mediante la nueva consola de administración cuya URL es:

http://
:8080/alfresco/service/enterprise/admin

En “Servicio de repositorio” y dentro de este en “Agrupación de servidores del repositorio” se puede ver toda la información del cluster, además se puede validar con el botón “Validar grupo” que realiza las comprobaciones necesarias para saber si ambos nodos se están comunicando correctamente:

Propiedades de Hazelcast

Todas las propiedades admitidas por Hazelcast en alfresco-global.properties son:

alfresco.cluster.enabled
Ejemplo: true
Descripción: Activa el cluster de Alfresco para este nodo

alfresco.cluster.interface
Ejemplo: 192.168.80.1
Descripción: Especifica la tarjeta de red usada para el cluster. Se puede usar tipo de dirección wildcard, por ejemplo 192.168.80.*

alfresco.cluster.nodetype
Ejemplo: NodoDesconectado001
Descripción: Especifica un nombre “amigable” para ese nodo del cluster, generalmente utilizado para servidores que se han unido al repositorio pero no forman parte del cluster (p.e. servidores de indexación)

alfresco.hazelcast.password
Ejemplo: mipasswd
Descripción: Define el password que usarán los nodos del cluster

alfresco.hazelcast.port
Ejemplo: 5701
Descripción: Establece el puerto de comunicación entre nodos del cluster

alfresco.hazelcast.autoinc.port
Ejemplo: false
Descripción: Realiza varios intentos de puertos para hayar uno libre desde la configuración alfresco.hazelcast.port. Alfresco no recomienda establecer esta propiedad

alfresco.hazelcast.mancenter.enabled
Ejemplo: false
Descripción: Activa las estadísticas y otros valores del cluster donde se puede acceder a través del Centro de gestión de Hazelcast

alfresco.hazelcast.mancenter.url
Ejemplo: http://localhost:8080/mancenter
Descripción: URL de acceso al centro de gestión de Hazelcast, evidentemente alfresco.hazelcast.mancenter.enabled debe estar en valor true

alfresco.hazelcast.max.no.heartbeat.seconds
Ejemplo: 15
Descripción: Tiempo máximo de monitorización para que se de por hecho que un nodo no está respondiendo

Configuración de Hazelcast en Share

En un entorno de cluster, Alfresco Share ahora utiliza Hazelcast para proporcionar mensajes entre los nodos de la capa web. Como resultado, las cachés ya no necesitan estar deshabilitadas para cualquier nodo. Cada uno funciona prácticamente tan rápido como una sola instancia de Share, mejorando así su rendimiento general.

Se pueden realizar dos configuraciones según las necesidades, con multicast o a nivel de TCP directo.

En todo caso, en balanceadores hay que seguir usando el sistema de Sticky-Session para funcionar correctamente. Hay que configurar correctamente el fichero share-config-custom.xml dentro de {extensionRoot}/alfresco/classes/web-extension poniendo correctamente el host y puerto de acceso al repositorio en caso necesario.

También hay que tener en cuenta que si se usa autenticación Kerberos o NTML con SSO las sesiones utilizarán la cookie JSESSIONID por lo que habrá que tenerla en cuenta por parte del balanceador.

Para esto hay que configurar el fichero custom-slingshot-application-context.xml
que hay en {extensionRoot}/alfresco/classes/web-extension (quitándole la extensión .sample)

Ejemplo para multicast:

 <!– Hazelcast distributed messaging configuration – Share web-tier cluster
    config (3.4.8 and 4.0.1) – see http://www.hazelcast.com/docs.jsp – and specifically
    http://www.hazelcast.com/docs/1.9.4/manual/single_html/#SpringIntegration –>
<!– Configure cluster to use either Multicast or direct TCP-IP messaging
    – multicast is default –>
<!– Optionally specify network interfaces – server machines likely to have
    more than one interface –>
<!– The messaging topic – the "name" is also used by the persister config
    below –>
<hz:topic id="topic" instance-ref="webframework.cluster.slingshot"
    name=»slingshot-topic» />

    
        
        
            
                <hz:multicast enabled="true" multicast-group="224.2.2.5"
                    multicast-port=»54327″ />
                
                    
                
            
            
                192.168.1.*
            
        
    

<bean id="webframework.slingshot.persister.remote"
    class=»org.alfresco.web.site.ClusterAwarePathStoreObjectPersister»
    parent=»webframework.sitedata.persister.abstract»>
    
    
        alfresco/site-data/${objectTypeIds}
    
    
    
        slingshot-topic
    

<bean id="webframework.factory.requestcontext.servlet" class="org.alfresco.web.site.ClusterAwareRequestContextFactory"
    parent=»webframework.factory.base»>
    
    
    
    

Ejemplo para conexión directa TCP:

<!– Hazelcast distributed messaging configuration – Share web-tier cluster
    config (3.4.8 and 4.0.1) – see http://www.hazelcast.com/docs.jsp – and specifically
    http://www.hazelcast.com/docs/1.9.4/manual/single_html/#SpringIntegration –>
<!– Configure cluster to use either Multicast or direct TCP-IP messaging
    – multicast is default –>
<!– Optionally specify network interfaces – server machines likely to have
    more than one interface –>
<!– The messaging topic – the "name" is also used by the persister config
    below –>
<hz:topic id="topic" instance-ref="webframework.cluster.slingshot"
    name=»slingshot-topic» />

    
        
        
            
                <hz:multicast enabled="false" multicast-group="224.2.2.5"
                    multicast-port=»54327″ />
                
                    alfnode1,alfnode2
                
            
            
                192.168.1.*
            
        
    

<bean id="webframework.slingshot.persister.remote"
    class=»org.alfresco.web.site.ClusterAwarePathStoreObjectPersister»
    parent=»webframework.sitedata.persister.abstract»>
    
    
        alfresco/site-data/${objectTypeIds}
    
    
    
        slingshot-topic
    

<bean id="webframework.factory.requestcontext.servlet" class="org.alfresco.web.site.ClusterAwareRequestContextFactory"
    parent=»webframework.factory.base»>
    
    
    
    

Centro de gestión Hazelcast (mancenter):

El centro de gestión Hazelcast (mancenter) permite monitorizar y administrar los servidores que ejecutan Hazelcast. Además, mancenter permite supervisar el estado general de los clústeres, y analizar y examinar las estructuras de datos en detalle.

Para instalarlo, se puede instalar tanto en un tomcat distinto como en el mismo de Alfresco. Solo hay que bajar una versión de Hazelcast (mancenter) y copiar el fichero mancenter-x.x.x.war al directorio de aplicaciones de tomcat.

Por ejemplo:

cp mancenter-2.4.1.war /opt/Alfresco422/tomcat/webapps/mancenter.war

Establecer la propiedad hazelcast.mancenter.home con el directorio donde se almacenan los datos, aquí se puede poner en la misma línea de opciones de Java (JAVA_OPTS), por ejemplo:

-Dhazelcast.mancenter.home=/opt/Alfresco422/tomcat/mancenter_data

Acordarse de activarlo en alfresco-global.properties:

alfresco.hazelcast.mancenter.enabled=true

Establecer la url de acceso, por ejemplo:

alfresco.hazelcast.mancenter.url=http://192.168.1.101:8080/mancenter

Por último, si se produce un error de serialización en el arranque, descomentar la siguiente línea en el contex.xml del servidor Tomcat:


 

Monitorización del funcionamiento de Hazelcast en Alfresco

La mejor forma como siempre es usando Log4j y para esto se puede usar la siguiente propiedad:

log4j.logger.org.alfresco.enterprise.repo.cluster=info

Para monitorizar la caché también se usan las siguientes propiedades:

log4j.logger.org.alfresco.enterprise.repo.cluster.cache=DEBUG
log4j.logger.org.alfresco.repo.cache=DEBUG

A nivel del propio Hazelcast:

log4j.logger.com.hazelcast=info

Y para aumentar el registro de seguimiento también se puede usar:

log4j.logger.com.hazelcast.impl.TcpIpJoiner=debug

Para finalizar

Las pruebas realizadas con un cluster de Alfresco One 4.2.2 usando Hazelcast han resultado ser muy satisfactorias, he realizado pruebas de subida de documentos, cambios de propiedades, etc. y eran instantáneas en ambos nodos.

Hay que tener en cuenta además que hay que configurar Solr (si se usa esta opción de indexado) correctamente para que se use de forma compartida, siempre y cuando no se utilize protocolo NFS para estos recursos compartidos de red ya que no está aconsejado. En este cado (uso de NFS) también se puede seguir usando una configuración similar a la que se utilizaba con Lucene, es decir, mantener índices locales por cada nodo.

Más información

http://docs.alfresco.com/4.2/concepts/ha-intro.html
http://hazelcast.org
http://unpocodejava.wordpress.com/2013/01/21/que-es-hazelcast/

Arquitectura(s) Cluster en Alfresco

Desde un punto de vista más teórico y funcional, dentro de los escenarios de posibles instalaciones en cluster de Alfresco ECM encontramos dos escenarios básicos, uno que utiliza repositorio por cada nodo y estos son sincronizados y la más usada actualmente, en la que se usa un repositorio común así como índices separados por cada nodo.

Dentro del segundo escenario, existe multitud de documentación sobre posibles arquitecturas de Alfresco ECM que podemos encontrar tanto en la documentación oficial de Alfresco (http://docs.alfresco.com) como en otros recursos tanto personales (http://blyx.com), como públicos (Junta de Andalucía, Ministerio de Justicia, etc.)

Pero generalmente, cuando se habla de arquitecturas en cluster para Alfresco, estas se limitan solo al producto en sí, es lógico pues Alfresco ECM es capaz de clusterizarse mediante el uso de EHCache y JGroups sin necesidad de más componentes.

Una posible arquitectura a desarrollar es la siguiente:

Se pueden observar varias capas o niveles en las cuales se pueden introducir de forma intermedia distintos elementos adicionales como nuevos balanceadores (hardware y software), firewalls, etc. según las necesidades de cada entorno.

Existen además varios tipos de usuarios, los usuarios externos o que acceden desde fuera de la organización, estos a su vez pueden ser usuarios «anónimos» o «autenticados» y también usuarios que son trabajadores de la organización y que deben tener los recursos como si estuvieran dentro de esta, incluidos los de administración.

Intranet Network: Es la red de intranet principal a través de la cual se conectan todos los usuarios. Generalmente es la red local de la empresa, bien, sementada, o por el contrario para un solo segmento p.e. 192.168.1.0/24 (Clase C). Los accesos a la mayoría de los protocolos por parte de los usuarios y concretamente a través de HTTP para el Share se realizan dentro de esta red. En algunos casos se puede segmentar esta para el uso de otros protocolos como CIFS pero requiere más complejidad de la que ya hay en sí misma.

Capa de WEB/Balanceo (1): Esta capa está planteada desde un doble punto de vista, por un lado es un servidor web (Apache) y por otro lado también es un balanceador software (Apache+mod_jk o Apache+mod_proxy) si bien también contempla el uso de alta disponibilidad por sí mismo (HA_Proxy) usando una IP «flotante» o virtual (192.168.1.100) a través de lo que se llama un Heartbeat (HB). De esta forma mantenemos la alta disponibilidad y sistema en «failover» para esa capa y usando un único punto de entrada para todos los usuarios.

Como esta capa es de entrada exclusiva por HTTP (Web y WebDAV), los accesos de otros protocolos que no pueden ser accedidos a través de Apache y el balanceo, como CIFS y FTP se realizarán directamente sobre la capa de aplicación.

Capa de presentación o FrontEnd (2): En esta capa se utiliza el servidor de aplicaciones como sistema de acceso al repositorio donde se instala Alfresco Share.

Esta capa puede contener también servidores HTTP como Apache para servir partes estáticas e incluso para balancear también hacia la siguiente capa (repositorio de Alfresco). En este diagrama no viene indicado para no complicar en exceso pero en muchas ocasiones es muy buena idea que también esta capa balancee e incluya un «Heartbeat» para mantener alta disponibilidad también en este punto.

Tampoco viene reflejado pero se da por supuesto que los servidores Tomcat están en cluster a nivel de servidor de aplicaciones, que , aunque esto no afecte directamente a Alfresco es una buena idea tener todas las capas también con sus propios métodos de redundancia y sincronización.

Capa de aplicaciones o repositorio (3): Aquí están localizados los repositorios o Alfresco Explorer, no los repositorios físicos que son más propios de la siguiente capa. Es decir, la instalación de Alfresco (sin Share) estaría en este sitio. Alfresco está configurado por JGroups como cluster y conectado su «Heartbeat» mediante una red propia para este que realiza la sincronización mediante TCP y RMI (EHCache).

Capa de persistencia y repositorio (4): Esta capa es la encargada de almacenar físicamente los ficheros/documentos en el sistema de ficheros así como toda la información asociada en la base de datos. Se da por supuesto que el almacenamiento está redundado mediante cabinas de discos así como de un sistema como Oracle RAC o MySQL Cluster NDB. Cada sistema tiene su propia subred que debería estar conectada por «fibra channel».

Otros elementos: Como se ve en el diagrama de arquitectura, existen elementos que al no estar directamente conectados mediante HTTP ni tener posibilidad de balanceo además de por sus características de aplicaciones, se conectan directamente a uno de los nodos de Alfresco. Así mismo, algunos accesos (p.e. CIFS, etc.) se realizan al otro nodo en una forma de repartir la carga de estos sistemas que no son balanceables.

Estos elementos son usados en muchas ocasiones para inyección masiva de datos o bien para conectar aplicaciones como SAP, AutoCAD, etc.

Administration & Monitoring Network: Por último, se usa también una red aparte también para los administradores y para monitorización, de esta forma se aíslan estas transmisiones y evita mayor carga en la red.

Más información: