Cuando tenemos que tomar la decisión respecto a qué motor de
base de datos utilizar debemos tener en consideración qué tipo de cargas vamos
a generar con nuestras aplicaciones.

En un entorno cloud PaaS, nuestras opciones estarán también limitadas a los offering que el proveedor considere interesante ofertar.

En este post vamos a analizar el comportamiento de los motores SQL Server, MySQL y PostgreSQL bajo el modelo PaaS en Azure para una carga de tipo OLTP, que podría ser equiparable a la carga de gestión de un almacén.

Vamos a hacer una prueba sencilla de un test “estilo TPC-C” con HammerDB contra tres motores en modalidad PaaS en Azure.

Las tres configuraciones se han desplegado con 4 vCores y se han utilizado tal cual, con los valores por defecto al crearlas, que es la situación más realista que nos encontramos en la vida real (se asume que PaaS se hace cargo por ti de buenas prácticas de configuración):

paas

La carga de datos la hemos hecho con 10 usuarios concurrentes y 10 DW en total. Esto genera una base de datos más bien pequeña, pero que es adecuada para estresar este tipo de pequeñas configuraciones de base de datos con solo 4 cores.

En el caso de SQL Server la base de datos recién creada ocupa 868 MB (sin ningún tipo de compresión) y se necesitaron de 10 minutos para realizar la carga completa.

Respecto a las operaciones del test, tanto en el caso de SQL Server, como de MySQL como PostgreSQL se realizan mediante procedimientos almacenados para reducir el tiempo de ejecución y mejorar el rendimiento. Es decir, que este test no exprime en ningún momento al compilador/generador de planes de ejecución sino que se centra en la capacidad de ejecución de dichos planes en todos los motores.

La carga en HammerDB la configuramos inicialmente con 10 usuarios, sin ningún delay y con 100000 iteraciones para que tuviéramos carga activa tiempo suficiente para estabilizar las transacciones por minuto:

virtual user

Con esta configuración lanzada contra SQL Server, se estabiliza alrededor de  85K tpm con el log y la  CPU al 50% aproximadamente:

Particionado: Azure PaaS SQL Server/ MySQL/ PostgreSQL vs OLTP HammerDB

Si duplicamos la carga, con 20 usuarios concurrentes, vemos que llegamos a estabilizarnos en unos 111K tpm, que supone un 30% más que con la prueba anterior.

carga

El consumo de CPU sin embargo sube hasta el 65% y se va percibiendo ya cierto freno a la escalabilidad:

consumo de cpu

Finalmente probaremos con 100 usuarios para saturar a la base de datos totalmente. Verificamos también que el cliente que genera la carga no está saturado, se mantiene sobre el 25%:

wish application

Con esta configuración de 100 usuarios llegamos a unos 129K tpm y un consumo del 80% de CPU. Consideramos ya este el máximo throughput que podemos obtener:

Particionado: Azure PaaS SQL Server/ MySQL/ PostgreSQL vs OLTP HammerDB
Particionado: Azure PaaS SQL Server/ MySQL/ PostgreSQL vs OLTP HammerDB
Particionado: Azure PaaS SQL Server/ MySQL/ PostgreSQL vs OLTP HammerDB

Tras finalizar las pruebas con 10, 20 y 100 usuarios la base de datos ha crecido a 2.23 GB ya que la carga incluye una importante cantidad de escrituras:

used space

Una vez sabemos dónde están los límites con SQL Server vamos a proseguir con MySQL. Comenzaremos creando la base de datos y haciendo la carga de datos.

Un aspecto a tener en cuenta es que HammerDB necesita drivers específicos para las bases de datos. En un sistema donde tengamos únicamente los drivers ODBC instalados no nos funcionará correctamente:

driver

Para el caso de MySQL necesitamos el conector para C. La última versión que encontré disponible fue la 6.1:

mysql connector

En el caso de MySQL vemos que la base de datos una vez finaliza la carga inicial ocupa prácticamente lo mismo que SQL Server, 887 MB pero sin embargo la carga inicial fue considerablemente más rápida, unos 5 minutos. El storage engine usado fue InnoDB:

tpcc

A continuación comenzaremos con el test con 10 usuarios. Los resultados son claramente inferiores a los que obtenemos con SQL Server, alrededor de unas 8K tpm:

Particionado: Azure PaaS SQL Server/ MySQL/ PostgreSQL vs OLTP HammerDB

Desde el lado de consumo de recursos del servidor vemos consumos muy bajos, de un 8% de la CPU únicamente. Si aumentamos el número de usuarios a 20 la realidad es que obtenemos resultados similares, incluso ligeramente peores:

6909 tpm

Si aumentamos el número de conexiones a 100 lo que obtenemos es un resultado muy similar también. Todo esto ocurre sin que en ningún momento el servidor se ha llegado a estresar a nivel de recursos:

Particionado: Azure PaaS SQL Server/ MySQL/ PostgreSQL vs OLTP HammerDB

La realidad es que MySQL nunca nació teniendo como objetivo soportar ERPs ni sistemas complejos sino como una base de datos ligera especializada en backends de entornos web. En estos entornos la gran mayoría de operaciones son de lectura y no hay demasiados problemas de contención por operaciones de escritura. Sin embargo es probable que estos valores tampoco sean “normales”. Probablemente el resultado es una mezcla de los mecanismos de HA incluidos en Azure junto con ciertos problemas de contención propios de este tipo de cargas.

Por último pasamos a PostgreSQL donde para poder realizar la carga tendremos que instalar la librería libpq.dll. La forma más rápida en windows para instalarla es hacer una instalación sencilla de PostgreSQL que ya la incluye:

Particionado: Azure PaaS SQL Server/ MySQL/ PostgreSQL vs OLTP HammerDB

Al realizar la prueba para PostgreSQL nos encontramos que  los scripts de HammerDB no están del todo finos para esta versión PaaS y se necesitaron algunas pequeñas modificaciones. Por ejemplo el nombre del usuario con la @ generaba un problema ya que luego se utilizaba ese mismo nombre para generar esquemas y objetos, donde no se soporta dicho carácter. El workaround rápido para salir del paso fue hardcodear el nombre del usuario en la función ConnectToPostgres y usar el nombre sin la @ como nombre de usuario:

ConnectToPostgres

La creación del esquema y la carga de datos fue la más rápida de todas en PostgreSQL, necesitándose únicamente 4 minutos en crear las tablas y rellenar los 10 warehouses con 10 clientes en paralelo. Una vez cargada la base de datos ocupaba un tamaño de 832 MB, muy similar de nuevo al resto de motores.

Las siguientes dos gráficas muestran los tiempos de carga y el tamaño tras la carga inicial:

load time
data base

Volviendo a PostgreSQL, comenzaremos con la carga de 10 usuarios, donde vemos que alcanzamos unos 66K tpm con un consumo de CPU de aproximadamente el 25%:

66K tpm

Cuando aumentamos el número de usuarios concurrentes a 20 tenemos un aumento moderado en el número de transacciones por minuto, lejos de lo que esperaríamos al doblar la carga:

Particionado: Azure PaaS SQL Server/ MySQL/ PostgreSQL vs OLTP HammerDB

Finalmente incrementaremos la carga a 100 usuarios concurrentes y nos encontraremos que el rendimiento es algo inferior al de 20 usuarios, aunque algo más estable:

tpm

Si observamos el consumo de CPU vemos que durante las pruebas hemos tenido tres “escalones” aumentando el consumo de CPU en cada una de ellas (la parte final del gráfico), llegando a prácticamente el 100% en algunos momentos:

resultados

Es muy habitual también que el abaratamiento por el lado de licencias al usar software libre se pueda destinar a un aumento en hardware. Por ejemplo estas configuraciones que hemos probado con 4 cores tienen un coste estimado para SQL Server de 425€ mensuales y de 272€ mensuales tanto para MySQL como para PostgreSQL.

Vamos a subir recursos al cluster de PostgreSQL a 8 cores, con lo que el coste subirá a 534€ mensuales, para ver si mejoramos con ello el rendimiento.

ejemplo

Atacaremos directamente con 100 usuarios concurrentes de entrada para ver si el aumento de recursos de CPU nos permite aumentar el rendimiento total:

tpm resultado

Como podemos ver, el duplicar la CPU nos ha permitido aumentar un 30% el rendimiento lo cual está lejos de ser lineal pero entra dentro de lo previsible para este tipo de cargas. Es decir, duplicando la cantidad de recursos estamos teniendo un rendimiento similar al que tenemos en SQL Server con la mitad de recursos. Esto no es algo que se aprecie solamente en este benchmark, sino en muchos otros y es un tema de discusión habitual en charlas informales entre DBAs.

Conclusión

Al final el poderoso don dinero ha hecho que el software propietario, sea SQL Server, sea Oracle, etc. estén un paso por delante en lo que se refiere a optimización y ello repercute en consultas más rápidas, soporte de mayor concurrencia, etc. Algo parecido ocurre con entornos que tengan que manejar bases de datos muy grandes, soportando operaciones analíticas, operaciones paralelas, etc. donde un sistema SMP MySQL o PostgreSQL suele ofrecer un peor rendimiento.

Por otra parte, el hecho que tengamos el código disponible y una mayor “libertad” hace que alrededor de las opciones open source crezcan proyectos que serían imposibles con el código propietario/cerrado. Por ejemplo Citus sobre PostgreSQL, que proporciona una solución MPP a problemas donde escalar horizontalmente, sobre múltiples nodos, etc. es una buena opción y potencialmente mucho más económica.

0 Shares:
Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

You May Also Like