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

Cómo comparar el rendimiento de MySQL usando SysBench

En este artículo vamos a discutir sysbench, el estándar real para la evaluación comparativa de MySQL. Vamos a echar un vistazo a los conceptos básicos del uso de sysbench y cómo podemos usar sysbench para aprender sobre MySQL y el segundo es el aspecto más importante para nosotros. Prácticamente usaremos sysbench como una herramienta para generar tráfico del que sabemos mucho porque sysbench retendrá información sobre el tráfico generado cada segundo.

Prueba MySQL de SysBench 

Sysbench es una herramienta de evaluación comparativa de subprocesos múltiples basada en luaJIT, es el estándar real para las evaluaciones comparativas de MySQL, debe poder conectarse a la base de datos.

Instalación de Sysbench

Primero, necesitamos instalar sysbench, estoy instalando sysbench en otro servidor para que podamos probar el impacto real de la carga en nuestro servidor MySQL.

curl -s https://packagecloud.io/install/repositories/akopytov/sysbench/script.rpm.sh | sudo bash
yum -y install sysbench

Listo, es muy fácil instalar sysbench, es mejor permitir que sysbench interactúe con MySQL Server a nivel de firewall, ya que este es un entorno de prueba, he desactivado el firewall en ambos hosts para evitar cualquier dificultad.

Entorno listo para SysBench:

Para esta prueba, estoy creando la base de datos sbtest y el usuario sbtest_user y otorgaré todos los PRIVILEGIOS a sbtest_user en la base de datos sbtest.

usando la raíz;

mysql> create database sbtest
mysql> create user sbtest_user identified by 'password';
mysql> grant all on sbtest.* to `sbtest_user`@`%`;
mysql> show grants for sbtest_user;
+---------------------------------------------------------+
| Grants for [email protected]%                                |
+---------------------------------------------------------+
| GRANT USAGE ON *.* TO `sbtest_user`@`%`                 |
| GRANT ALL PRIVILEGES ON `sbtest`.* TO `sbtest_user`@`%` |
+---------------------------------------------------------+

Rendimiento de MySQL usando SysBench

Configuración comparativa:

El paso de preparación de sysbench crea las tablas con los datos que se utilizarán en el benchmark. En este ejemplo estamos ejecutando el comando de preparación. Hay algunos parámetros con MySQL al principio, esos serán los parámetros de conexión. Los otros parámetros son parámetros de la prueba oltp_read_write.lua y estamos especificando la prueba en sí misma, que es oltp_read_write.lua y estamos ejecutando el comando de preparación. La opción que comienza con MySQL especifica la conexión MySQL, el nombre de host y el puerto para conectarse, el nombre de usuario y la contraseña para conectarse, y el esquema predeterminado para la conexión. Las tablas y los parámetros table_size son las propiedades de la prueba oltp_read_write.lua.

Esto significa que el paso de preparación creará 16 tablas con 10 000 reglas en cada una de ellas. El siguiente paso es ejecutar el benchmark.

Para ejecutar normalmente, se pasan todos los parámetros que pasarán a preparados y algunos adicionales que revisamos ahora, estos son específicos de la ejecución real del punto de referencia. El "TIEMPO" El parámetro especifica el límite de tiempo para que se ejecute el punto de referencia, cero significa tiempo ilimitado, el punto de referencia se ejecutará hasta que presionemos control+c. Así es como usaremos sysbench en el laboratorio y así es como la gente normalmente lo usa en el aprendizaje y no en una configuración de evaluación comparativa.

Solo queremos liberar tráfico en algo que examinaremos y podemos detenerlo con control+c una vez que hayamos terminado con el examen.

El “intervalo de informe” Los parámetros especifican con qué frecuencia se imprimieron las estadísticas de sysbench. Por lo general, esto se establece en 1 como en nuestro ejemplo, que hace que sysbench imprima la línea por cada segundo. Incluso en las configuraciones de evaluación comparativa, este parámetro se usa ampliamente porque imagina si tenemos un punto de referencia de una hora y solo tenemos estadísticas agregadas al final, eso no dice nada sobre la distribución de los datos, como el rendimiento en el servidor a lo largo del tiempo. . El “hilo” La opción especifica el número de subprocesos de cliente o conexiones MySQL para usar en sysbench. La cantidad de subprocesos del cliente también tendrá un efecto en la cantidad de subprocesos del servidor que se pueden usar. La “tasa” El parámetro especifica la tasa de llegada de las transacciones de sysbench como una forma de cumplir realmente con la carga causada por el punto de referencia. Si las transacciones pueden continuar, se ponen en cola, esto es nuevamente algo que se usa típicamente en este tipo de configuración, lo que vamos a usar ahora en un tipo de configuración de aprendizaje.

Desde el servidor sysbench:

Preparar un conjunto de datos:

En la máquina virtual de evaluación comparativa, ejecutaremos el comando sysbench prepare para crear una base de datos para nuestras evaluaciones comparativas.

Aquí podemos ver que estamos usando sbtest_user como nombre de usuario, la contraseña es contraseña y nos estamos conectando a 192.168.66.5 DB como servidor de base de datos.

sysbench \
--db-driver=mysql \
--mysql-user=sbtest_user \
--mysql_password=password \
--mysql-db=sbtest \
--mysql-host=192.168.66.5 \
--mysql-port=3306 \
--tables=16 \
--table-size=10000 \
/usr/share/sysbench/oltp_read_write.lua prepare

sysbench 1.0.20 (using bundled LuaJIT 2.1.0-beta2)

Creating table 'sbtest1'...
Inserting 10000 records into 'sbtest1'
Creating a secondary index on 'sbtest1'...
.
.
.
Creating table 'sbtest16'...
Inserting 10000 records into 'sbtest16'
Creating a secondary index on 'sbtest16'..

Tiene la base de datos sbtest aquí, cambiemos el esquema predeterminado a la base de datos sbtest, verifique qué tablas tenemos.

Especificamos que el punto de referencia debería crear dieciséis tablas y creó 16 tablas, podemos verlo aquí

mysql> show tables;
+------------------+
| Tables_in_sbtest 
+------------------+
| sbtest1          |
| sbtest2          |
.
.
.
| sbtest16         |
+------------------+
16 rows in set (0.01 sec)

Revisemos algunos registros de una tabla.

mysql> select * from sbtest1 limit 6;

vamos a ejecutar un punto de referencia. Este punto de referencia tendrá una línea de salida por cada segundo porque configuramos la relación, el intervalo es igual a uno y tiene cuatro subprocesos de cliente porque configuramos los subprocesos en cuatro.

--events=N                      limit for total number of events [0]
--time=N                        limit for total execution time in seconds [10]

Las dos configuraciones anteriores (eventos y tiempo) gobiernan cuánto tiempo debe seguir funcionando SysBench. Puede ejecutar una cierta cantidad de consultas o puede seguir ejecutándose durante un tiempo predefinido.

En el servidor sysbench:

sysbench \
--db-driver=mysql \
--mysql-user=sbtest_user \
--mysql_password=password \
--mysql-db=sbtest \
--mysql-host=192.168.66.5 \
--mysql-port=3306 \
--tables=16 \
--table-size=10000 \
--threads=4 \
--time=0 \
--events=0 \
--report-interval=1 \ 
/usr/share/sysbench/oltp_read_write.lua run

WARNING: Both event and time limits are disabled, running an endless test
sysbench 1.0.20 (using bundled LuaJIT 2.1.0-beta2)
Running the test with the following options:
Number of threads: 4
Report intermediate results every 1 second(s)
Initializing random number generator from current time
Initializing worker threads...
Threads started!

[ 1s ] thds: 4 tps: 62.79 qps: 1320.63 (r/w/o: 933.91/257.15/129.57) lat (ms,95%): 80.03 err/s: 0.00 reconn/s: 0.00
[ 2s ] thds: 4 tps: 77.01 qps: 1530.26 (r/w/o: 1065.18/312.05/153.03) lat (ms,95%): 61.08 err/s: 0.00 reconn/s: 0.00
[ 3s ] thds: 4 tps: 74.03 qps: 1463.67 (r/w/o: 1025.47/289.13/149.07) lat (ms,95%): 70.55 err/s: 0.00 reconn/s: 0.00
[ 4s ] thds: 4 tps: 69.99 qps: 1414.84 (r/w/o: 991.89/282.97/139.98) lat (ms,95%): 65.65 err/s: 0.00 reconn/s: 0.00
[ 5s ] thds: 4 tps: 74.02 qps: 1488.34 (r/w/o: 1048.24/292.07/148.03) lat (ms,95%): 74.46 err/s: 0.00 reconn/s: 0.00
[ 6s ] thds: 4 tps: 72.99 qps: 1444.89 (r/w/o: 1003.92/294.98/145.99) lat (ms,95%): 70.55 err/s: 0.00 reconn/s: 0.00
[ 7s ] thds: 4 tps: 63.00 qps: 1271.04 (r/w/o: 890.03/255.01/126.00) lat (ms,95%): 87.56 err/s: 0.00 reconn/s: 0.00
[ 8s ] thds: 4 tps: 72.99 qps: 1439.82 (r/w/o: 1008.87/284.96/145.98) lat (ms,95%): 73.13 err/s: 0.00 reconn/s: 0.00
[ 9s ] thds: 4 tps: 74.00 qps: 1488.01 (r/w/o: 1038.01/302.00/148.00) lat (ms,95%): 73.13 err/s: 0.00 reconn/s: 0.00

entonces podemos ver que está haciendo aproximadamente 70 80 transacciones por segundo en mi máquina, lo que se traduce en aproximadamente más de mil consultas por segundo. Esto se ejecuta en VirtualBox en una computadora portátil.

A partir de estas consultas, podemos ver cuántas de ellas son de lectura, cuántas de ellas son de escritura, cuántas de ellas son otras, cuál es la latencia del percentil 95 para la transacción (r/w/o:1038.01/302.00/148.00), cuánto cuantos errores por segundo (err/s:0.00 ) tenemos y cuantas conexiones por segundo (reconn/s:0.00) tenemos. Debido a que especificamos que el tiempo es igual a cero, esto se ejecutará hasta que presionemos ctrl+c.

Revisemos la lista de procesos de presentación en el host de la base de datos.

mysql> show processlist;
+----+-----------------+--------------------+--------+---------+-------+----------------------------+--------------------------------------+
| Id | User            | Host               | db     | Command | Time  | State                      | Info                                 |
+----+-----------------+--------------------+--------+---------+-------+----------------------------+--------------------------------------+
|  5 | event_scheduler | localhost          | NULL   | Daemon  | 23200 | Waiting on empty queue     | NULL                                 |
| 11 | root            | localhost          | NULL   | Sleep   | 18438 |                            | NULL                                 |
| 19 | root            | localhost          | sbtest | Query   |     0 | starting                   | show processlist                     |
| 23 | root            | localhost          | NULL   | Sleep   |  4098 |                            | NULL                                 |
| 30 | sbtest_user     | 192.168.66.6:37298 | sbtest | Sleep   |     0 |                            | NULL                                 |
| 31 | sbtest_user     | 192.168.66.6:37300 | sbtest | Execute |     0 | waiting for handler commit | COMMIT                               |
| 32 | sbtest_user     | 192.168.66.6:37302 | sbtest | Sleep   |     0 |                            | NULL                                 |
| 33 | sbtest_user     | 192.168.66.6:37304 | sbtest | Execute |     0 | Opening tables             | SELECT c FROM sbtest13 WHERE id=4978 |
+----+-----------------+--------------------+--------+---------+-------+----------------------------+--------------------------------------+

8 filas en conjunto (0.00 seg)

El servidor de la base de datos estaba prácticamente siempre ocupado. Vi que el tiempo de ejecución nunca cambia de cero prácticamente, y fue muy fácil capturar el servidor de la base de datos en acción como cuando se ejecuta "SELECCIONAR c DESDE sbtest13 DONDE id =4978". Y definitivamente, tenemos cuatro conexiones de la máquina de evaluación comparativa

De forma predeterminada, SysBench intentará ejecutar consultas lo más rápido posible. Para simular un tráfico más lento, se puede utilizar esta opción. Puede definir aquí cuántas transacciones deben ejecutarse por segundo.

--rate=N                        average transactions rate. 0 for unlimited rate [0]

En el servidor sysbench

[[email protected] ~]# sysbench \
--db-driver=mysql \
--mysql-user=sbtest_user \
--mysql_password=password \
--mysql-db=sbtest \
--mysql-host=192.168.66.5 \
--mysql-port=3306 \
--tables=16 \
--table-size=10000 \
--threads=4 \
--time=0 \
--events=0 \
--report-interval=1 \
--rate=40 \
/usr/share/sysbench/oltp_read_write.lua run

WARNING: Both event and time limits are disabled, running an endless test
sysbench 1.0.20 (using bundled LuaJIT 2.1.0-beta2)
Running the test with following options:
Number of threads: 4
Target transaction rate: 40/sec
Report intermediate results every 1 second(s)
Initializing random number generator from current time
Initializing worker threads...
Threads started!

[ 1s ] thds: 4 tps: 42.87 qps: 858.43 (r/w/o: 600.20/171.49/86.74) lat (ms,95%): 73.13 err/s: 0.00 reconn/s: 0.00
[ 1s ] queue length: 0, concurrency: 1
[ 2s ] thds: 4 tps: 41.01 qps: 857.25 (r/w/o: 609.17/164.05/84.02) lat (ms,95%): 101.13 err/s: 0.00 reconn/s: 0.00
[ 2s ] queue length: 0, concurrency: 3
[ 3s ] thds: 4 tps: 57.01 qps: 1119.29 (r/w/o: 778.20/228.06/113.03) lat (ms,95%): 73.13 err/s: 0.00 reconn/s: 0.00
[ 3s ] queue length: 0, concurrency: 2
.
.
.
[ 15s ] thds: 4 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s: 0.00 reconn/s: 0.00
[ 15s ] queue length: 145, concurrency: 4
[ 16s ] thds: 4 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s: 0.00 reconn/s: 0.00
[ 16s ] queue length: 179, concurrency: 4

Así que el nuevo parámetro aquí es –rate es igual a 40 lo que significa que tendremos dos líneas por segundo dos líneas de salida y no una. Debido a que establecemos la tasa de llegada de los eventos de evaluación comparativa en 40 por segundo, veremos el TPS actual.

No se garantiza que sea 40/segundo, pero la llegada garantiza que, en promedio, hacemos aproximadamente 40 transacciones por segundo y podemos monitorear la longitud de la cola y la concurrencia en la segunda línea. Si hacemos una lista corta de procesos, es mucho más fácil capturar la base de datos en un estado en el que algunas conexiones están esperando aquí.

Mientras una sesión está ocupada, puede ver que la transacción por segundo es cero (tps:0.00).

mysql> show processlist;
+----+-----------------+--------------------+--------+---------+-------+------------------------+------------------------------------------------------------------------------------------------------+
| Id | User            | Host               | db     | Command | Time  | State                  | Info                                                                                                 |
+----+-----------------+--------------------+--------+---------+-------+------------------------+------------------------------------------------------------------------------------------------------+
|  5 | event_scheduler | localhost          | NULL   | Daemon  | 19162 | Waiting on empty queue | NULL                                                                                                 |
|  8 | root            | localhost          | NULL   | Query   |     0 | starting               | show processlist                                                                                     |                                                                                                |
| 21 | sbtest_user     | 192.168.66.6:49060 | sbtest | Execute |    33 | updating               | UPDATE sbtest8 SET k=k+1 WHERE id=5005                                                               |
| 22 | sbtest_user     | 192.168.66.6:49062 | sbtest | Execute |    22 | updating               | UPDATE sbtest14 SET c='54592761471-89397085016-24424731626-29460127219-18466786462-73074657089-48925 
| 23 | sbtest_user     | 192.168.66.6:49064 | sbtest | Execute |    21 | updating               | UPDATE sbtest10 SET c='68520795048-46094139936-88850487689-12482054639-29231339380-71050139550-93403 |
| 24 | sbtest_user     | 192.168.66.6:49066 | sbtest | Execute |    31 | updating               | DELETE FROM sbtest14 WHERE id=4994                                                                   |
+----+-----------------+--------------------+--------+---------+-------+------------------------+------------------------------------------------------------------------------------------------------+
10 rows in set (0.00 sec)

Podemos ver que esto está durmiendo durante unos segundos, esto era prácticamente imposible en el escenario anterior para obtener algo como esto.

Tráfico con mucho tráfico de escritura con informe final:

Ejecutemos una carga de trabajo de escritura intensa (pero no de solo escritura) y, por ejemplo, el rendimiento del subsistema de E/S de prueba, como mencioné time=300 luego, el benchmark se ejecutará durante 300 segundos y nos dará un informe final para analizarlo.

[[email protected] ~]#   
sysbench \
--db-driver=mysql \
--mysql-user=sbtest_user \
--mysql_password=password \
--mysql-db=sbtest \
--mysql-host=192.168.66.5 \
--mysql-port=3306 \
--tables=16 \
--table-size=10000 \
--threads=8 \
--time=300 \
--events=0 \
--report-interval=1 \
--rate=40 \
/usr/share/sysbench/oltp_read_write.lua run
sysbench 1.0.20 (using bundled LuaJIT 2.1.0-beta2)

Running the test with following options:
Number of threads: 8
Target transaction rate: 40/sec
Report intermediate results every 1 second(s)
Initializing random number generator from current time
Initializing worker threads...
Threads started!

[ 1s ] thds: 8 tps: 39.87 qps: 810.27 (r/w/o: 570.08/159.46/80.73) lat (ms,95%): 82.96 err/s: 0.00 reconn/s: 0.00
[ 1s ] queue length: 0, concurrency: 1
[ 2s ] thds: 8 tps: 43.02 qps: 847.39 (r/w/o: 590.27/172.08/85.04) lat (ms,95%): 125.52 err/s: 0.00 reconn/s: 0.00
[ 2s ] queue length: 0, concurrency: 0
.
.
.
[ 350s ] thds: 8 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s: 0.00 reconn/s: 0.00
[ 350s ] queue length: 6545, concurrency: 1
SQL statistics:
    queries performed:
        read:                            78624
        write:                           22385
        other:                           11205
        total:                           112214
    transactions:                        5589   (15.94 per sec.)
    queries:                             112214 (320.02 per sec.)
    ignored errors:                      27     (0.08 per sec.)
    reconnects:                          0      (0.00 per sec.)

General statistics:
    total time:                          350.6412s
    total number of events:              5589

Latency (ms):
         min:                                   12.45
         avg:                                74639.59
         max:                               213244.02
         95th percentile:                   100000.00
         sum:                            417160677.24

Threads fairness:
    events (avg/stddev):           698.6250/196.36
    execution time (avg/stddev):   52145.0847/15557.93

ANÁLISIS DEL INFORME:

Esto es bastante útil para verificar que el informe final solo le dará promedios. Los resultados intermedios permitirán realizar un seguimiento del rendimiento segundo a segundo. El informe final puede verse como arriba. Aquí encontrará información sobre las consultas ejecutadas, las transacciones ejecutadas, cuántos errores ocurrieron, cualquier conexión perdida, cuál fue el rendimiento y el tiempo total transcurrido. También puede consultar las métricas de latencia y la distribución de consultas entre subprocesos.