Cada vez más vamos viendo como las SAN clásicas van perdiendo protagonismo. Las razones son variadas, desde migraciones forzosas a cloud, pasando por entornos con presupuestos más limitados hasta clientes que acaban hartos de las «draconianas» condiciones de su proveedor de storage. Por ejemplo, es habitual encontrarnos con contratos de mantenimiento muy caros, ampliaciones de disco a precios muy superiores a mercado, así como dificultades para ampliar/mejorar el hardware sin reemplazarlo completamente. También existe una fuerte tendencia a seguir virtualizando y a tratar los servidores como si fuesen «cabezas de ganado». Por todo esto la tendencia hacia el SDS (Software Defined Storage) y las Virtual SAN cada vez va ganando más adeptos.

En el pasado hemos testeado sobre Windows Server 2016 su oferta de SDS incluyendo Storage Replica. El problema que tenemos con la oferta de Microsoft es que a día de hoy contiene solo un subconjunto de las características habituales que tenemos en las SAN y además sufre de bastantes limitaciones. Algunas de estas limitaciones implican menos flexibilidad de cara a los cambios y de ahí que otras ofertas como VMware VSAN tengan más cuota de mercado. Tampoco podemos olvidarnos de un «viejo conocido» que lleva ya muchos años ofreciendo este tipo de Virtual SAN y cuya experiencia en el sector y robustez está un peldaño por encima del resto. Hablamos de StarWind con su software Virtual SAN que con la última versión incluye una versión Free que es prácticamente 100% feature complete. De esta forma, excluyendo las funcionalidades de VTL (Virtual Tape Library) y el interfaz gráfico, podremos testear el producto en un entorno sin limitaciones adicionales. Esta versión está soportada para entornos de producción, aunque al no ser una versión de pago no incluye soporte por lo que en caso de problemas dependeremos de nosotros mismos o del soporte de los foros de StarWind.

Máquinas virtuales de Azure

En este post vamos a ver cómo podemos utilizar este software sobre máquinas virtuales que en nuestro caso serán máquinas virtuales en Azure:

Además del disco C: añadiremos un disco de datos de tipo P30 premium, que montaremos sobre la unidad S: A continuación, procederemos a la descarga e instalación del software. El software podemos descargarlo directamente de la web de StarWind y bien podemos solicitar una licencia trial o únicamente utilizar la versión free. Comenzaremos realizando la instalación en el primer nodo y comprobando que podemos conectar con la consola de administración:

El siguiente paso es crear un nuevo disco virtual:

Elegiremos como ubicación el disco S: anteriormente mencionado y configuraremos un disco virtual de 100 GB:

El siguiente paso es definir el tipo de disco virtual lo cual es bastante importante. La razón es que podemos o bien optar por discos thick-provisioned clásicos o bien por un tipo de discos llamados LSFS:

Los discos LSFS están basados en sistemas de ficheros «log structured» donde las operaciones de escrituras aleatorias, típicas en entornos virtuales por la concurrencia de operaciones, se modifican para convertirlas en secuenciales. Esto puede ayudarnos cuando en el entorno tenemos limitaciones en el número de IOPS más estrictas que de ancho de banda total. Es decir, en cierta forma estamos haciendo algo parecido a lo que hacen las NetApp o el propio log de transacciones de SQL Server, buscando reducir el número de operaciones y maximizando la secuencialidad de éstas:

A continuación pasaremos a configurar la caché. En estas soluciones de tipo Virtual SAN la memoria RAM se puede utilizar como la memoria de una controladora, para cachear escrituras y lecturas. En principio nos puede parecer más arriesgado el cachear las escrituras (write-back) pero debemos pensar en que la configuración típica replica las cachés entre varios nodos haciendo que la caida de uno de ellos no implique la pérdica del dato. Únicamente perderíamos el dato si, de forma totalmente simultánea todos los nodos de nuestra solución fuesen apagados de forma simultánea sin haber sido capaces de hacer flush al disco:

Este sería el nivel más alto de caché, a continuación podríamos definir otro nivel intermedio, compuesto habitualmente de discos flash. En nuestro caso como el almancenamiento es ya SSD no tiene sentido su uso. Esta funcionalidad sin embargo es muy importante cuando queremos usar discos tradicionales, más económicos, combinados con discos flash para acelerar el rendimiento (tiering automático a nivel de bloque):

FInalmente indicaremos que vamos a crear un nuevo target iSCSI y finalizaremos la creación:

El siguiente paso es preparar la máquina que va a utilizar dicho disco vía iSCSI. Aunque la solución soporta otros protocolos, como SMB, que podría sernos bastante útil para por ejemplo configurar una instancia con failover clásico, utilizaremos iSCSI por ser más genérico y el más habitual para este tipo de soluciones.Al utilizar iSCSI el disco se nos presentará localmente tal y como lo haría un disco SCSI tradicional. Por defecto el iniciador iSCSI ya viene instalado en los sistemas operativos modernos por lo que únicamente añadiremos el multipath a las características ya instaladas:

Si nos olvidamos de este paso o no se encuentra bien configurado veremos que nos aparecen los discos duplicados, triplicados, etc. en función del número de paths que tengamos disponibles:

La conexión por iSCSI es sencilla y en la mayor parte de los casos con el autodiscovery nos funcionará correctamente la conexión al disco:

Comprobaremos tras el formateo y la instalación del driver multipath que nos aparece el volumen correctamente montado (sin duplicados) y en este caso asociado a la letra de unidad O:

Una vez tenemos la configuración preparada el siguiente paso es testear el rendimiento. Para testear el rendimiento y tener una referencia lanzamos un conjunto de tests sintéticos que simulan patrones típicos de SQL Server contra el disco de forma local. El siguiente paso sería lanzar este mismo test pero accediendo al disco a traves de iSCSI y de la solucíón SDS. El último paso sería añadir mecanismos de alta disponibilidad, réplicas de disco síncronas, a esta solución para observar su comportamiento. Por realizar una analogía sería como si comenzáramos realizando pruebas contra un SQL Server standalone, luego añadieramos dicha instancia a un cluster y configuraramos un grupo de disponibilidad con réplicas síncronas antes de volver a testear el rendimiento.

La configuración de un segundo nodo es bastante sencilla aunque debemos tener en cuenta que necesitaremos un par de tarjetas de red y que el rendimiento de éstas marcará diferencias importantes. En nuestro caso utilizamos tarjetas de red virtuales de 10 Gbps. Este es el ancho de banda máximo pero que al hablar de un entorno virtual tendremos políticas de QoS y límites de ancho de banda que pueden reducir el ancho de banda máximo disponible:

Para añadir una réplica acudiremos a la herramienta de administración y lanzaremos el replicacion manager:

Seleccionaremos otro nodo en el que previamente habremos instalado el software:

Elegiremos replicación síncrona de forma que tengamos la posibilidad de soportar fallos en ambos nodos lo que junto al MPIO nos dará transparencia en caso de fallo:

La estrategia de failover estará condicionada por el número de nodos y los canales de comunicación disponibles. Al final hablamos de una configuración similar a la que tendríamos que realizar al configurar el Quorum de un cluster de Windows tradicional. En nuestro caso elegiremos utilizar un HeartBeat aunque es posible que en instalaciones con muchos nodos tenga más sentido utilizar Node Majority:

Para almacenar la réplica podemos o bien utilizar un dispositivo ya existente o crear uno nuevo. En nuestro caso no tenemos ningún dispositivo creado en destino así que lo crearemos desde cero:

Cuando finalice el proceso de sincronización comprobaremos el estado y que tanto el canal de comunicaciones como el de heartbeat se encuentran online:

Con el fin de realizar un análisis de rendimiento algo más completo añadiremos también (una vez ya realizadas las pruebas con 2 nodos) un tercer nodo a la réplica. De nuevo tendremos cuidado de seleccionar correctamente los interfaces para heartbeat y para la sincronización:

La mayor parte de los resultados obtenidos entran dentro de los esperado aunque algunos nos han sorprendido positivamente.Comenzaremos analizando los resultados en operaciones de escritura aleatorias. En azul vemos que el rendimiento con profundidad de cola 1 en operaciones aleatorias de 64 KB sufre en cuanto pasamos de acceso local a acceso remoto. Con el número de réplicas vemos que el rendimiento aumenta de forma progresiva, siendo mayor el rendimiento con 3 réplicas (1 principal y dos secundarios), llegando al punto que con tres réplicas se mejora el rendimiento que teníamos con la copia local. Esto dice mucho del buen hacer del software y la gestión de escrituras aleatorias ya que en escrituras esperaríamos mayores penalizaciones:

En operaciones con mayor profundidad de cola y peticiones más pequelas (profundidad 8 y peticiones de 8 y 64 KBs) el comportamiento al añadir la capa software mejora desde la primera configuración. Esto nos indica que el funcionamiento de la caché y del sistema de ficheros basado en un log de escritura está funcionando correctamente. Cuando llegamos a la tercera réplica nos encontramos una caida de rendimiento en estos escenarios respecto a la configuración con 2 réplicas. Esto nos indica que en este tipo de cargas existe un equilibrio entre latencia y throughput bastante delicado, por lo que no escalarán muy bien si añadimos demasiados nodos a la solución.

Por último en el caso de las peticiones de mayor tamaño, de 128 KB, tenemos un comportamiento similar al que teníamos con las operaciones con profundidad de cola pequeña. Tenemos un impacto importante al añadir el acceso remoto pero con el número de réplicas vamos recuperando rendimiento hasta llegar a superar el rendimiento que obteníamos en local sin ningún tipo de «software» intermedio. Desde el punto de vista de rendimiento de las escrituras aleatorias y de disponibilidad la solución con 3 nodos nos parece muy adecuada.

En el siguiente gráfico veremos el comportamiento ante lecturas aleatorias. En este caso el impacto de la caché, las técnicas de readahead del software así como el número de nodos (que hacen aumentan el tamaño de la caché global) nos producen un aumento generalizado en la configuración de 2 nodos. El pasar a tres nodos no nos genera mejoras ya que nos quedamos en 360 MB/s aproximadamente al igual que con dos nodos. La razón es que estamos alcanzando los límites de throughput de red que nos permite la máquina virtual y el propio disco por lo que si deseamos tener mayor rendimiento no debemos prestar atención únicamente al número de nodos sino al «tamaño» de cada uno de ellos. En muchos entornos Cloud tenemos una correlación entre el tamaño de la máquina (CPUs, memoria, etc.) y el ancho de banda máximo (tanto de red como a disco) que podemos utilizar:

Cuando realizamos operaciones secuenciales en vez de aleatorias nos encontramos un escenario desfavorable respecto al aumento de nodos. Con un tamaño de petición de 64 KB tenemos un aumento de rendimiento bueno al pasar a utilizar el software de StarWind pero que se degrada a medida que añadimos más nodos. La lógica nos indica que en estos casos los costes de intercomunicación respecto a una lectura contínua desde un mismo nodo generan dicho perjuicio. Por tanto si nuestro escenario habitual es el de lecturas secuenciales (por ejemplo un Datawarehouse) probablemente la mejor opción será minimizar el número de réplicas:

En el caso de las escrituras secuenciales el comportamiento es muy similar. Cuando realizamos operaciones secuenciales estamos accediendo a las mismas partes del dispositivo virtual de disco de forma contigua lo cual probablemente no le permite al software sacar partido del paralelismo. Es decir, imaginemos que tenemos 300 bloques a gestionar en modo «master», si cuando accedemos a las escrituras las realizamos siempre sobre el mismo bloque hasta pasar al siguiente, lo único que conseguiremos al añadir nodos es que los costes de sincronización entre nodos jueguen en nuestra contra. Con las operaciones aleatorias la situación era a la inversa ya que tanto la caché en RAM como el poder «servir» peticiones que se distribuyen homogéneamente (por su aleatorioedad) en distintos nodos nos aportaba una ventaja de rendimiento:

La conclusión que obtenemos por tanto es que esta solución será muy apropiada cuando las operaciones habituales sean concurrentes y aleatorias, tanto en el caso de escrituras como de lecturas, obteniendo una importante mejora de rendimiento en casi todos los escenarios. Este podría ser un escenario de consolidación de muchas bases de datos transaccionales pequeñas o de un entorno con máquinas virtuales de diferente naturaleza. Pensando en SQL Server podría ser un buen complemento para una migración a cloud de una instancia en Failover clásico donde tengamos un número de bases de datos consolidadas elevado.

En aquellos escenarios donde se generen cargas con profundidades de cola muy bajas será donde podemos tener una degradación mayor. Un ejemplo de este tipo de escenarios lo tenemos cuando estamos realizando operaciones de inserción fila a fila, en un cursor/loop, contra una única base de datos. En este tipo de situaciones la latencia a disco es crítica y el número de IOPS a baja profundidad también lo es, por lo que tendremos una penalización en rendimiento. Tampoco será una solución tan óptima, desde el punto de vista de escalado y el uso de recursos, cuando hablemos de operaciones masivas secuenciales tanto de escritura como de lectura. En este tipo de cargas, mas propias de un datawarehouse, será preferible invertir en un escalado vertical de nuestra instancia, añadiendo más discos, cpu, memoria, más ancho de banda, etc. a una misma máquina. Afortunadamente en este tipo de entornos normalmente es tolerable el uso de mecanismos de alta disponibilidad con RPO y RTO menos exigentes que en un transaccional por lo que no necesitaremos tener replicación síncrona de discos.

 

 

 

 

 

Rubén Garrigós