Cómo escalar aplicaciones. SCALE UP vs. SCALE OUT y las posibilidades con Windows y SQL Azure

Yendo directamente al grano, SCALE UP hace referencia a lograr escalabilidad a nivel de servidor, incrementándole sus recursos de hardware, antes de mejorar la escalabilidad usando otro servidor. Por ejemplo, aumentando su cantidad de memoria, o la capacidad/velocidad de los discos o la cantidad de núcleos de cómputo del servidor.

En un enfoque SCALE OUT, la escalabilidad se logra “sacando” la carga a otros servidores.

Al principio el enfoque SCALE UP puede parecer el menos costoso y más sencillo para muchos casos. Pero cuando las exigencias siguen aumentando con el tiempo, lo que sí es seguro, es que se llegará a un límite práctico en el que no será posible “agrandar” más el servidor para ponerle por ejemplo 500 núcleos de procesamiento de manera que pueda satisfacer una fuerte demanda. En estos casos, es fácil observar cómo puede resultar mucho más barato, eficiente y productivo un enfoque de SCALE OUT. Además, un SCALE UP generalmente genera tiempo de baja, mientras se cambian o mejoran las partes de hardware. Mientras que con un SCALE OUT, solo es cuestión de levantar más máquinas independientes.

Windows Azure es tan flexible, que nos permite ambos tipos de escalamiento. El SCALE UP se logra a través del ajuste que podemos hacer a las instancias que creamos para correr nuestros servicios (recordemos que una instancia es cada uno de los servidores virtuales que ordenamos crear para desplegar nuestras aplicaciones de Windows Azure). Estas instancias vienen en cuatro tamaños. Así que al mejor estilo SCALE UP podemos hacer que el tamaño de cada instancia crezca. Estas son las posibilidades de tamaño que tendríamos:

image

Así que podríamos escalar desde 1.6 hasta 10.4 GHz en CPU, desde 1.75GB hasta 14GB de RAM y desde 225MB hasta 2TB de disco duro.

En cuanto a la alternativa SCALE OUT, tenemos servidores que se aprovisionan muy rápido y pueden comenzar a trabajar en equipo manipulando solo unos elementos de configuración. Así pues, tenemos la ventaja de poder adicionar más y más instancias a nuestro despliegue, las cuales se ajustarán automáticamente con solo un despliegue inicial.

ESCALABILIDAD CON SQL AZURE

El SCALE OUT no aplica solo a los servidores de presentación o cómputo (web o worker roles), sino también de SQL Azure como tal. No obstante, en SQL Azure no tenemos la posibilidad de hacer SCALE UP.

SQL Azure ofrece una gran cantidad de ventajas sobre todo al tener que escalar bases de datos de una manera elástica y rápida, dado que tenemos casi que ilimitada capacidad para levantar nuevas bases de datos para satisfacer cualquier demanda. En SQL Azure, no tenemos una relación física uno a uno entre servidores y bases de datos como en SQL Server tradicional. Pero la abstracción que se nos brinda es perfecta para que la mayoría de las veces el manejo que se le da a estos conceptos sea el mismo que on-premises. Sin embargo, cuando tenemos una cuenta de SQL Azure, tenemos la posibilidad de generar todas las bases de datos que queramos, las cuales residirán en servidores distintos (a veces coincidencialmente residirán en el mismo servidor). Pero esta distribución es ejecutada por los balanceadores de carga automáticos de Azure que se encargan de determinar cómo distribuir las cargas de peticiones a la plataforma.

Entonces en SQL Azure no vamos a tener la posibilidad por ejemplo de aumentar la memoria de un server dado, sino que sencillamente levantamos otra base de datos. Con esto, podemos tomar una base de datos que requiera ser escalada y segmentarla o particionarla en otras bases de datos más pequeñas y con mejor rendimiento.

Comprendido ya el concepto de SCALE OUT, veamos ahora que por ejemplo cuando hablamos de bases de datos, existen dos formas para hacer este tipo de escalamiento: Vertical y Horizontal. Estos tipos de escalamiento se ejecutan particionando las tablas que conforman la base de datos horizontal como verticalmente. Luego de estar particionadas, obviamente se generan más tablas y éstas a su vez se pueden ubicar en distintas bases de datos, lo que nos daría el escalamiento buscado.

Escalamiento Vertical:

Consiste en dividir las tablas verticalmente a través de columnas. Así pues, uno por ejemplo podría escoger dejar las columnas más importantes en una tabla y las menos usadas en otras. Por ejemplo dejar en una tabla T1 de la base de datos D1 los datos del cliente y su dirección principal, y en otra T2 en la base de datos D2, otra tabla con las direcciones secundarias. Entonces para lograr un correlacionamiento correcto entre T1 y T2, en T2 deberíamos tener un mecanismo de llaves foráneas hacia T1.

Otro ejemplo de particionamiento vertical se observa por ejemplo cuando dejamos una tabla completa (o conjunto de ellas) en una sola base de datos. Y otras tablas en otras bases de datos. Por ejemplo, tiene mucho sentido en una aplicación de negocios, tener la tabla de clientes en una sola base de datos, para obtener el mayor rendimiento posible para ésta.

Lo que es más, se puede combinar ese particionamiento para lograr aún más escalabilidad y eficiencia, de manera que podremos poner la tabla de clientes en su propia base de datos, y luego particionar sus columnas en distintas tablas, pero dentro de la misma base de datos.

image

Escalamiento Horizontal:

Este escalamiento comprende la distribución de los datos de una tabla a través de varias tablas con la misma estructura, cada una de las cuales generalmente se encuentra en una base de datos distinta y en ocasiones aún en instancias y/o servidores distintos. Es un excelente acercamiento para circunstancias en las cuales la variabilidad de la carga de trabajo en el servidor de base de datos es muy alta, pues en SQL Azure por ejemplo, es muy fácil aprovisionar y desaprovisionar servidores; además siempre resulta mucho más barato que tener un servidor de muy altas prestaciones siempre encendido esperando por picos de carga de trabajo.

En cada versión de la tabla se almacena un conjunto de datos que tienen como dato común el valor de una columna que generalmente se conoce como PartitionKey. Entonces cada versión de la tabla se llama Partition. Este es el tipo de particionamiento que se hizo popular con SQL Server 2005.

Para poder tener “conciencia” de dónde están ubicados los datos con una PartitionKey determinada, existe una tabla maestra donde reside esta información.

Por ejemplo; en una aplicación comercial, se puede decidir dejar en una base de datos diferente cada las ventas de cada ciudad. En este caso la ciudad sería la PartitionKey para identificar cada tabla. Sin embargo, una clave de partición, podría estar conformada por más campos dependiendo de la naturaleza de la aplicación y el tipo de carga de trabajo.

Consideraciones para el escalamiento horizontal:

1. Escoger una llave de partición adecuada, tras un profundo conocimiento del negocio. En general es más recomendable usar una llave natural que una numérica en estos casos. En el caso anterior, haber escogido la ciudad como llave de partición es mucho más eficiente por ejemplo que haber escogido por ejemplo el Id de la venta.

2. Administración de particiones: Es una de las tareas más complejas luego de haber definido las particiones; generalmente implica consideraciones en el desarrollo de la aplicación que debe saber dónde insertar o modificar nuevos datos así como dónde buscar los existentes. La idea es escoger un tipo de partition key que no vaya a requerir una posterior reubicación de datos cuando el negocio eche a andar, lo que probablemente significaría un tiempo de baja del servicio.

3. Evitar cross-database joins: Aparte de ser bastante ineficiente, algunas plataformas como SQL Azure no soportan consultas distribuidas. Por eso es mejor que todos los datos que requiere una tabla dada, estén en la misma DB. De lo contrario habrá que escribir el código necesario para poder ejecutar consultas asíncronas a través de varias particiones que retornen datos separadamente que luego tendrán que ser unidos en la capa de aplicación.

4. Alta disponibilidad: Cuando se escoge un acercamiento de este tipo de escalabilidad, es requerido que todos los servidores a través de los cuales está particionada la base de datos tengan unos índices de disponibilidad bastante altos. Estos índices son provistos por SQL Azure. Es así como cada vez que creamos una base de datos, SQL Azure crea automáticamente tres copias de la misma, para asegurar esta alta disponibilidad. Cada copia es creada en servidores físicos distintos dentro de la misma ubicación geográfica. La sincronización entre estas bases de datos es automática también. En caso de falla, SQL Azure automáticamente redirige las peticiones a una de las copias de seguridad y vuelve a levantar una tercera copia para futuras eventualidades. Todo esto ocurre sin intervención humana y sin caídas del servicio.

5. Administración: El escalamiento horizontal puede llegar a generar alta complejidad en la administración dado que hay que aplicar updates, ejecutar patching, ajustar un plan de recuperación de desastres, etc. y todo esto para cada servidor usado en el escalamiento. Afortunadamente SQL Azure se encarga de todas estas tareas automáticamente por nosotros. De las únicas tareas de administración que un DBA debería tener en cuenta son: creación de esquemas, afinamiento de índices, optimización de consultas, logins, usuarios y administración de la seguridad.

image

Conclusión:

A pesar de que el particionamiento puede ayudar a mejorar el performance, la escalabilidad y los costos, puede llegar a ser bastante complejo implementar un esquema de particionado exitoso. Algunas aplicaciones tienen un esquema de particionamiento natural del cual se puede tomar ventaja mientras hay otras aplicaciones que requieren ser re - arquitecturadas para volverlas escalables; cosa que vale la pena la mayoría de las veces. Windows Azure y SQL Azure proveen una plataforma sobre la cual las aplicaciones pueden hacer SCALE-UP/SCALE-OUT en el caso de Windows Azure al permitir “agrandar” las instancias y al permitir usar varias instancias con el mismo despliegue. Y en el caso de SQL Azure con SCALE-OUT al permitir pasar de una o dos bases de datos a decenas o cientos de bases de datos de una manera muy sencilla sin incurrir en fuertes costos de infraestructura. Además, los clientes no pierden inversión si necesitas reducir nuevamente la infraestructura, ya que todo estaba en arriendo en el esquema de plataforma como servicio.