viernes, 27 de diciembre de 2019

BigData

Por mas que suene muy de moda el término "BigData" no es mas que lo mismo de siempre: Análisis de datos que pueden venir en formatos cambiantes, no fijos, con sintáxis libre.

Ejemplo:
Debes colectar tweets, post de facebook e información de noticieros (esta ultima mediante lectura automatizada de websites de noticias), además debes colectar imagenes para ser analizadas. Todo debe ser analizado en un "contexto", según cierta "pregunta" realizada al sistema bigdata. Cada "pregunta" realizada al sistema requeriría modelar el mismo conjunto de datos origen ("source") con una optica distinta, dirigida por lo que se pretende buscar.

Hay dos problemas visibles acá:
  1. cómo almacenar objetos libres.
  2. cómo analizar objetos libres según un contexto y guardar el resultado, creando una asociación entre "source" y "analisis" que pueda ser cuantificada mas tarde.

Cómo Almacenar.

Cada fuente de datos (el post de twitter, de facebook y de noticias, imagenes) requieren ser almacenados en su forma original para poder realizarle diversos tipos de analisis individual según un contexto.

Que motor de datos sirve mejor ?

NO: Mysql/Postgre o cualquier "motor relacional". La mejor respuesta es un motor no relacional, como DynamoDB de Amazon Aws, en donde cada "record" es un objeto, con atributos variados, cada registro podria tener "campos" (atributos del objeto) que no existen en otro registro. Tambien tengo esta otra opcion: https://github.com/christiansalazar/omf, la fabriqué para este proposito años atrás de que se hiciera de moda el bigdata (artículo acá)

Preprocesar data y almacenar el resultado descartando el origen ? NO.

Alguien puede pensar en "preprocesar" cada post e insertar el resultado estructurado. Mala idea, porque si debemos analizar la sintaxis escrita por un humano, esta podria tener diferentes interpretaciones dependiendo del contexto que se quiere analizar, y esto es solo un ejemplo.

Analizemos un caso:

Un mismo post podria tener información de un evento en particular y junto a este una queja por mal servicio del hotel que hospedó a los visitantes al evento. Por tanto, el motor de "bigdata" quiere cierto dia analizar data de "eventos" y otro dia quiere analizar calidad de servicio. Por esto, no es bueno guardar solo cierta información del post, sino en cambio guardar todo el post. Los analisis se guardan en otro objeto que será asociado al objeto original ("source").

Debido a lo explicado en el ultimo parrafo entonces nos enfocamos en guardar todo el "post", y no solo su analisis, los analisis del post los categorizaremos y los guardaremos tambien, asociados al post y a un contexto de analisis. Por ejemplo: Un objeto es de tipo "analisis_calidad_servicio" y otro objeto es "evento_deportivo" o "evento_arte", cada objeto estará asociado al post origen, llamalo "source". Asi, tienes un grafo que asocia ciertos "sources" con ciertos "objetos de analisis". Ahora, cómo se crea esa relacion ?

La creación de la relación entre un "source" y un "objeto de analisis" es compleja porque cierto analisis puntual podria implicar analisis de texto con machine learning, analisis de imagen (un post trae imagenes, detectar caras sobre estas, detectar vehiculos chocados, camiones de cierto color etc), incluso podria haber un humano leyendo y categorizando. Debo recordar que "el analisis" no toca ni altera el objeto "source", sino en cambio el "analisis" se guarda en la db junto a una relación.

Hace unos 5 años atrás antes de la moda de "bigdata" fabriqué un pequeño motor PHP que es capaz de manejar objetos y relaciones entre estos, esta en github:

https://github.com/christiansalazar/omf

(ir al articulo relacionado)

En resumen, hay procesos maestros:

1. buscar relaciones existentes que respondan la pregunta realizada al sistema (lectura del sistema)

2. creacion de diferentes relaciones derivadas por el hecho de haber analizado los mismos objetos pero en cierto contexto distinto (escritura del sistema).

3. organizacion de contextos. Los contextos pueden ser vistos como las preguntas que se le hacen al sistema.

martes, 2 de abril de 2019

Variables de Sesión y Cookies en Ambientes Multiservidor con LoadBalancer.

A los loadbalancers no le gustan las variables de sesión almacenadadas en servidor. Prefieren las cookies.

Primero, clarifiquemos cada componente.

Un LoadBalancer es un componente de la red que distribuye el tráfico hacia uno u otro servidor -de un grupo de servidores declarados- dependiendo de alguna regla. Esta regla puede ser el tiempo de duración de un servidor en responder o la cantidad de peticiones que esta atendiendo cada servidor del grupo.

Una Variable de Sesión Almacenada en Servidor, es un dato que se maneja dentro de un servidor, vinculada a la computadora que inició la petición mediante un dato llamado "cookie_id". Mediante este dato "cookie_id" buscará el dato requerido dentro del servidor y podrá saber qué dato le corresponde a cada visitante.

Una Cookie, es un archivo de texto almacenado en el computador que inició la petición -no en el servidor- y se guardará allí un dato que será enviado al servidor que sirva la petición, usando el encabezado del paquete http.

Estas tres cosas son clave a la hora de fabricar software capaz de escalar para poder atender alto tráfico.

Cómo funcionan estos componentes en un escenario real.

Supongamos que hemos creado un servicio web, que se ejecuta en una UrL específica, que leerá un numero de la base de datos, nada mas, algo simple. Pero, este servicio será invocado simultáneamente 100.000 veces. Cuando digo "simultáneo" significa que a la vez hay 100.000 peticiones ejecutándose en el mismo "momentum".

Este simple hecho puede colapsar tanto al servidor como al motor de datos. Sobre todo al servidor http si el software no esta bien diseñado. Me enfocaré en el servidor, debido a que el framework web que se usa para fabricar al servicio tendrá con seguridad una reutilización de la conexión de la base de datos, de modo de no generar 100.000 conexiones, sino solo una.

Muy probablemente el servidor se caerá con este gran número de conexiones. Sí, nodejs puede con eso y mas, pero entonces, para nodejs hablemos de 100.000.000 de conexiones y también se caerá. Queremos hacer un cluster, donde cada nodo (servidor) sea capaz de atender un numero decente de peticiones. Supongamos que estamos forzados a usar un servidor apache.

Cuando el navegador u otro servicio requiere al servicio web que describo acá, entonces la URL los llevará al Loadbalancer y no a un servidor específico. El LoadBalancer seleccionará un servidor, utilizando alguna regla.  En AmazonAWS, el loadbalancer es tan excelente que es capaz de levantar un servidor desde una imagen de disco, echándolo a andar y conectándolo al Loadbalancer, luego, cuando la demanda baje entonces será capaz de eliminar el servidor para reducir costes.

Supongamos que hemos creado dos servidores sirviendo el mismo código fuente. Cada servidor atiende peticiones en "http://servidor-1/servicio" y "http://servidor-2/servicio", siendo "servicio" el codigo que devuelve un dato necesario. Cada servidor usa el mismo codigo, cada uno es un clon del otro, cuya unica diferencia es la IP y su MAC por supuesto.

El loadbalancer elegirá al servidor1 o el servidor2, por tanto, todo lo que el navegador envió originalmente a "https://www.prueba.cl/servicio" irá a parar a uno de los dos servidores declarados en el Loadbalancer.  Note que he puesto "https", el loadbalancer puede recibir contenido seguro y mapearlo a "http" -no seguro- en cada instancia declarada, sin perder la seguridad, porque se supone que hay una red privada entre servidor1, servidor2 y el loadbalancer, nadie interfiere allí.

El servidor1 o el servidor2 atenderá la petición, hace su trabajo y devuelve un dato. Para el navegador no hubo diferencia. De este modo tenemos un pequeño cluster de dos servidores que atienden peticiones como si de uno solo se tratase.

Es seguro. No hay puertos extraños abiertos, nadie puede acceder a los servidores que estan declarados en el loadbalancer.

Ahora, veamos el problema de los datos de sesión del usuario. Supongamos que la petición depende de algún dato introducido por el usuario, digamos su RUT o CEDULA. Este dato se puede almacenar en una cookie o en una variable de servidor, pero, dependiendo de si usamos o no a un loadbalancer entonces un método prevalecerá y el otro no podrá usarse.

Memoria de Sesión: via cookies o variables de sesión en el lado del servidor. ?

Dependerá de cómo estamos instalando nuestros servicios, con o sin loadbalancers.

Cuando NO hay loadbalancer y solo UNA instancia -servidor- atiende a todas las peticiones entonces se puede usar una "memoria de sesión" de tipo "variable de sesión". Debido a que el dato clave estará en el lado del servidor final y no hay necesidad de compartirlo con otros servidores -porque solo hay uno-.

Cuando HAY un loadbalancer y MAS DE UNA instancia sirve las peticiones -digamos que hay 2 servidores- entonces el uso de variables de sesión echará todo por tierra porque el dato que el usuario necesita se habrá quedado en un servidor y los demas servidores no lo conocerán. Para este caso vienen las cookies al rescate.

Las cookies. Debido a la naturaleza de las cookies -almacenar datos en el computador/teléfono que inició la llamada- entonces, cada vez que la petición llega al loadbalancer se copiarán las "cookies" que provienen de ella hacia la instancia que toque servir a la petición.  Por tanto, el servidor1 y el servidor2 recibirán la misma cookie siempre y por consecuencia el dato necesario para servir, digamos el RUT o CEDULA.

Ejemplo


Supongamos que tenemos un sistema de manejo de usuarios (login/logout) y este sistema es atendido por un loadbalancer con 10 servidores detrás, para atender una situación pesada de 100.000 visitantes que quieren registrarse a la vez.

Si usamos "memoria de sesion" del tipo "variables del servidor" entonces todo fallará, porque el usuario se registrará y su "USER_ID" quedará grabado en el primer servidor que le atendió (podría ser cualquiera del uno al diez). Cuando el usuario se termine de registrar y quiera hacer login se dará cuenta que a veces podrá iniciar sesión y a veces no, dependerá de que si con suerte le ha tocado todo el tiempo el mismo servidor, y eso no ocurrirá, porque el Loadbalancer no siempre dará al mismo servidor.

Si usamos "memoria de sesión" del tipo "cookies", entonces su USER_ID se guardará en su computador y no importará a cual servidor se le delegue la petición; el sistema siempre conocerá su USER_ID porque el Loadbalancer lo tomó de la petición que el navegador le hizo y se lo copió al servidor seleccionado. Por tanto, cualquiera de los 10 servidores declarados sabrá qué usuario esta solicitando el servicio.

Resúmen

Si la aplicación web o el servicio web correrá solo en un servidor entonces da igual si se usan cookies o memoria de servidor.  Si se usan multiples servidores conectados por un loadbalancer entonces se deben usar cookies.