sql >> Base de Datos >  >> RDS >> Mysql

Evaluación comparativa de rendimiento de MySQL:MySQL 5.7 frente a MySQL 8.0

MySQL 8.0 trajo enormes cambios y modificaciones impulsados ​​por el equipo de Oracle MySQL. Los archivos físicos han sido cambiados. Por ejemplo, *.frm, *.TRG, *.TRN y *.par ya no existen. Se han agregado toneladas de nuevas funciones, como CTE (Expresiones de tabla comunes), Funciones de ventana, Índices invisibles, expresiones regulares (o Expresión regular); esta última se modificó y ahora brinda compatibilidad completa con Unicode y es segura para varios bytes. El diccionario de datos también ha cambiado. Ahora está incorporado con un diccionario de datos transaccionales que almacena información sobre los objetos de la base de datos. A diferencia de las versiones anteriores, los datos del diccionario se almacenaban en archivos de metadatos y tablas no transaccionales. La seguridad se mejoró con la nueva adición de caching_sha2_password, que ahora es la autenticación predeterminada que reemplaza a mysql_native_password y ofrece más flexibilidad pero una seguridad más estricta que debe usar una conexión segura o una conexión sin cifrar que admita el intercambio de contraseñas usando un par de claves RSA.

Con todas estas características geniales, mejoras y mejoras que ofrece MySQL 8.0, nuestro equipo estaba interesado en determinar qué tan bien funciona la versión actual de MySQL 8.0, especialmente dado que nuestro soporte para las versiones de MySQL 8.0.x en ClusterControl está en camino (así que estad atentos). en este). Esta publicación de blog no discutirá las características de MySQL 8.0, pero tiene la intención de comparar su rendimiento con MySQL 5.7 y ver cómo ha mejorado.

Configuración y entorno del servidor

Para este punto de referencia, tengo la intención de utilizar una configuración mínima para la producción utilizando el siguiente entorno de AWS EC2:

Tipo de instancia:instancia t2.xlarge
Almacenamiento:gp2 (almacenamiento SSD con un mínimo de 100 y un máximo de 16000 IOPS)
vCPUS:4
Memoria:16GiB
Versión de MySQL 5.7:MySQL Community Server (GPL) 5.7.24
Versión de MySQL 8.0:MySQL Community Server - GPL 8.0.14

También hay algunas variables notables que he establecido para este punto de referencia, que son:

  • innodb_max_dirty_pages_pct =90 ## Este es el valor predeterminado en MySQL 8.0. Ver aquí para más detalles.
  • innodb_max_dirty_pages_pct_lwm=10 ## Este es el valor predeterminado en MySQL 8.0
  • innodb_flush_neighbors=0
  • innodb_buffer_pool_instances=8
  • innodb_buffer_pool_size=8GiB

El resto de las variables que se configuran aquí para ambas versiones (MySQL 5.7 y MySQL 8.0) ya están ajustadas por ClusterControl para su plantilla my.cnf.

Además, el usuario que usé aquí no se ajusta a la nueva autenticación de MySQL 8.0 que usa caching_sha2_password. En cambio, ambas versiones del servidor usan mysql_native_password más la variable innodb_dedicated_server está desactivada (predeterminada), que es una nueva característica de MySQL 8.0.

Para hacer la vida más fácil, configuré el nodo de la versión Community de MySQL 5.7 con ClusterControl desde un host separado, luego eliminé el nodo en un clúster y apagué el host de ClusterControl para hacer que el nodo MySQL 5.7 esté inactivo (sin tráfico de monitoreo). Técnicamente, ambos nodos MySQL 5.7 y MySQL 8.0 están inactivos y no hay conexiones activas a través de los nodos, por lo que es esencialmente una prueba pura de evaluación comparativa.

Comandos y scripts utilizados

Para esta tarea, se utiliza sysbench para probar y simular la carga de los dos entornos. Estos son los siguientes comandos o secuencias de comandos que se utilizan en esta prueba:

sb-prepare.sh

#!/bin/bash

host=$1
#host192.168.10.110
port=3306
user='sysbench'
password='[email protected]'
table_size=500000
rate=20
ps_mode='disable'
sysbench /usr/share/sysbench/oltp_read_write.lua --db-driver=mysql --threads=1 --max-requests=0 --time=3600 --mysql-host=$host --mysql-user=$user --mysql-password=$password --mysql-port=$port --tables=10 --report-interval=1 --skip-trx=on --table-size=$table_size --rate=$rate --db-ps-mode=$ps_mode prepare

sb-run.sh

#!/usr/bin/env bash

host=$1
port=3306
user="sysbench"
password="[email protected]"
table_size=100000
tables=10
rate=20
ps_mode='disable'
threads=1
events=0
time=5
trx=100
path=$PWD

counter=1

echo "thread,cpu" > ${host}-cpu.csv

for i in 16 32 64 128 256 512 1024 2048; 
do 

    threads=$i

    mysql -h $host -e "SHOW GLOBAL STATUS" >> $host-global-status.log
    tmpfile=$path/${host}-tmp${threads}
    touch $tmpfile
    /bin/bash cpu-checker.sh $tmpfile $host $threads &

    /usr/share/sysbench/oltp_read_write.lua --db-driver=mysql --events=$events --threads=$threads --time=$time --mysql-host=$host --mysql-user=$user --mysql-password=$password --mysql-port=$port --report-interval=1 --skip-trx=on --tables=$tables --table-size=$table_size --rate=$rate --delete_inserts=$trx --order_ranges=$trx --range_selects=on --range-size=$trx --simple_ranges=$trx --db-ps-mode=$ps_mode --mysql-ignore-errors=all run | tee -a $host-sysbench.log

    echo "${i},"`cat ${tmpfile} | sort -nr | head -1` >> ${host}-cpu.csv
    unlink ${tmpfile}

    mysql -h $host -e "SHOW GLOBAL STATUS" >> $host-global-status.log
done

python $path/innodb-ops-parser.py $host

mysql -h $host -e "SHOW GLOBAL VARIABLES" >> $host-global-vars.log

Entonces, el script simplemente prepara el esquema sbtest y completa las tablas y los registros. Luego realiza pruebas de carga de lectura/escritura usando el script /usr/share/sysbench/oltp_read_write.lua. El script vuelca el estado global y las variables de MySQL, recopila la utilización de la CPU y analiza las operaciones de fila de InnoDB manejadas por el script innodb-ops-parser.py. Luego, los scripts generan archivos *.csv en función de los registros volcados que se recopilaron durante el punto de referencia, luego usé una hoja de cálculo de Excel aquí para generar el gráfico a partir de archivos *.csv. Verifique el código aquí en este repositorio de github.

¡Ahora, procedamos con los resultados del gráfico!

Operaciones de fila InnoDB

Básicamente aquí, solo extraje las operaciones de fila de InnoDB que realizan las selecciones (lecturas), eliminaciones, inserciones y actualizaciones. ¡Cuando aumenta el número de subprocesos, MySQL 8.0 supera significativamente a MySQL 5.7! Ambas versiones no tienen cambios de configuración específicos, sino solo las variables notables que he establecido. Así que ambas versiones usan valores predeterminados.

Curiosamente, con respecto a las afirmaciones del equipo del servidor MySQL sobre el rendimiento de las lecturas y escrituras en la nueva versión, los gráficos apuntan a una mejora significativa del rendimiento, especialmente en un servidor de alta carga. Imagine la diferencia entre MySQL 5.7 versus MySQL 8.0 para todas sus operaciones de fila InnoDB, hay una gran diferencia, especialmente cuando aumenta la cantidad de subprocesos. MySQL 8.0 revela que puede funcionar de manera eficiente independientemente de su carga de trabajo.

Transacciones procesadas

Como se muestra en el gráfico anterior, el rendimiento de MySQL 8.0 muestra nuevamente una gran diferencia en el tiempo que lleva procesar las transacciones. Cuanto más bajo, mejor funciona, lo que significa que es más rápido procesar transacciones. Las transacciones procesadas (el segundo gráfico) también revela que ambos números de transacciones no difieren entre sí. Es decir, ambas versiones ejecutan casi la misma cantidad de transacciones, pero difieren en la rapidez con que pueden finalizar. Aunque podría decir que MySQL 5.7 todavía puede manejar mucho con una carga más baja, pero se podría esperar que la carga realista, especialmente en producción, sea más alta, especialmente en el período de mayor actividad.

El gráfico anterior aún muestra las transacciones que pudo procesar, pero separa la lectura de la escritura. Sin embargo, en realidad hay valores atípicos en los gráficos que no incluí, ya que son pequeños fragmentos del resultado que sesgarían el gráfico.

MySQL 8.0 revela grandes mejoras, especialmente para hacer lecturas. Muestra su eficiencia en las escrituras especialmente para servidores con una alta carga de trabajo. Un excelente soporte adicional que afecta el rendimiento de MySQL para las lecturas en la versión 8.0 es la capacidad de crear un índice en orden descendente (o escaneos de índice hacia adelante). Las versiones anteriores solo tenían un escaneo de índice ascendente o hacia atrás, y MySQL tenía que ordenar archivos si necesitaba un orden descendente (si se necesita ordenar archivos, podría considerar verificar el valor de max_length_for_sort_data). Los índices descendentes también permiten que el optimizador utilice índices de varias columnas cuando el orden de exploración más eficiente combina el orden ascendente para algunas columnas y el orden descendente para otras. Vea aquí para más detalles.

Recursos de CPU

Durante esta evaluación comparativa, decidí tomar algunos recursos de hardware, en particular, la utilización de la CPU.

Permítanme explicar primero cómo tomo el recurso de la CPU aquí durante la evaluación comparativa. sysbench no incluye estadísticas colectivas para los recursos de hardware utilizados o utilizados durante el proceso cuando se compara una base de datos. Por eso, lo que hice fue crear un indicador creando un archivo, conectarme al host de destino a través de SSH y luego recopilar datos del comando "top" de Linux y analizarlos mientras dormía por un segundo antes de recopilarlos nuevamente. Después de eso, tome el aumento más destacado del uso de la CPU para el proceso mysqld y luego elimine el archivo de bandera. Puedes revisar el código que tengo en github.

Entonces, discutamos nuevamente sobre el resultado del gráfico, parece revelar que MySQL 8.0 consume mucha CPU. Más que MySQL 5.7. Sin embargo, podría tener que lidiar con nuevas variables agregadas en MySQL 8.0. Por ejemplo, estas variables pueden afectar su servidor MySQL 8.0:

  • innodb_log_spin_cpu_abs_lwm =80
  • innodb_log_spin_cpu_pct_hwm =50
  • innodb_log_wait_for_flush_spin_hwm =400
  • innodb_parallel_read_threads =4

Las variables con sus valores se dejan con sus valores predeterminados para este benchmark. Las primeras tres variables manejan la CPU para el registro REDO, que en MySQL 8.0 ha sido una mejora debido al rediseño de cómo InnoDB escribe en el registro REDO. La variable innodb_log_spin_cpu_pct_hwm tiene afinidad de CPU, lo que significa que ignoraría otros núcleos de CPU si mysqld está anclado solo a 4 núcleos, por ejemplo. Para subprocesos de lectura paralelos, en MySQL 8.0, agrega una nueva variable para la que puede ajustar cuántos subprocesos usar.

Sin embargo, no profundicé más en el tema. Puede haber formas de mejorar el rendimiento aprovechando las funciones que ofrece MySQL 8.0.

Conclusión

Hay toneladas de mejoras que están presentes en MySQL 8.0. Los resultados de la evaluación comparativa revelan que ha habido una mejora impresionante, no solo en la gestión de cargas de trabajo de lectura, sino también en una carga de trabajo alta de lectura/escritura en comparación con MySQL 5.7.

Pasando a las nuevas características de MySQL 8.0, parece ser que ha aprovechado las tecnologías más actualizadas no solo en el software (como una gran mejora para Memcached, Gestión remota para un mejor trabajo de DevOps, etc.) pero también en ferretería. Tomado por ejemplo, el reemplazo de latin1 con UTF8MB4 como la codificación de caracteres predeterminada. Esto significaría que requeriría más espacio en disco ya que UTF8 necesita 2 bytes en los caracteres que no son US-ASCII. Aunque este punto de referencia no aprovechó el uso del nuevo método de autenticación con caching_sha2_password, no afectará el rendimiento si usa cifrado. Una vez que se autentica, se almacena en caché, lo que significa que la autenticación solo se realiza una vez. Entonces, si está utilizando un usuario para su cliente, no será un problema y es más seguro que las versiones anteriores.

Dado que MySQL aprovecha el hardware y el software más actualizados, cambia sus variables predeterminadas. Puede leer aquí para obtener más detalles.

En general, MySQL 8.0 ha dominado a MySQL 5.7 de manera eficiente.