2012-05-05 10 views
12

Después de notar que nuestra base de datos se ha convertido en un cuello de botella importante en nuestros sistemas de producción en vivo, decidí construir un punto de referencia simple para llegar al fondo del problema.InnoDB Bottleneck: ACID relajante para mejorar el rendimiento

El punto de referencia: tiempo de cuánto tiempo se necesita para aumentar la misma fila en una tabla InnoDB 3000 veces, donde la fila se indexa por su clave principal, y la columna que se actualiza no es parte de ningún índice. Realizo estas 3000 actualizaciones usando 20 clientes simultáneos que se ejecutan en una máquina remota, cada uno con su propia conexión separada al DB.

Me interesa saber por qué los diferentes motores de almacenamiento que he evaluado, InnoDB, MyISAM y MEMORY, tienen los perfiles que hacen. También espero entender por qué a InnoDB le va tan mal en comparación.

InnoDB (20 clientes simultáneos): Cada actualización toma 0.175s. Todas las actualizaciones se realizan después de 6.68s.

MyISAM (20 clientes simultáneos): Cada actualización toma 0.003s. Todas las actualizaciones se realizan después de 0.85s.

Memoria (20 clientes simultáneos): Cada actualización lleva 0.0019s. Todas las actualizaciones se realizan después de 0.80s.

Al pensar que la simultaneidad podría estar causando este comportamiento, también comparé a un único cliente haciendo 100 actualizaciones secuencialmente.

InnoDB: Cada actualización lleva 0.0026s.

MyISAM: Cada actualización toma 0.0006s.

MEMORIA: Cada actualización toma 0.0005s.

La máquina actual es una instancia de Amazon RDS (http://aws.amazon.com/rds/) con la mayoría de las configuraciones predeterminadas.

Supongo que la respuesta estará en las siguientes líneas: InnoDB fsyncs después de cada actualización (dado que cada actualización es una transacción compatible con ACID), mientras que MyISAM no lo hace ya que ni siquiera admite la transacción. Es probable que MyISAM esté realizando todas las actualizaciones en la memoria y descargando regularmente al disco, que es como su velocidad se acerca al motor de almacenamiento MEMORY. Si esto es así, ¿hay alguna manera de utilizar InnoDB para su soporte de transacción, pero tal vez relajar algunas restricciones (a través de configuraciones) para que las escrituras se realicen más rápido a costa de algo de durabilidad?

Además, ¿hay alguna sugerencia sobre cómo mejorar el rendimiento de InnoDB a medida que aumenta el número de clientes? Claramente está escalando peor que los otros motores de almacenamiento.

actualización

He encontrado https://blogs.oracle.com/MySQL/entry/comparing_innodb_to_myisam_performance, que es precisamente lo que estaba buscando. El establecimiento de innodb-flush-log-at-trx-commit = 2 nos permite relajar las restricciones de ACID (el enjuague en el disco ocurre una vez por segundo) para el caso donde ocurre un corte de energía o falla del servidor. Esto nos da un comportamiento similar al MyISAM, pero aún así nos beneficiamos de las funciones de transacción disponibles en InnoDB.

Al ejecutar los mismos puntos de referencia, vemos una mejora de 10 veces en el rendimiento de escritura.

InnoDB (20 clientes simultáneos): Cada actualización toma 0.017s. Todas las actualizaciones se realizan después de 0.98s.

¿Alguna otra sugerencia?

+0

myisam no es compatible con ACID. InnoDB es. Si relaja las contraints, entonces ya no es compatible con ACID, y también podría NO usar innodb. –

+0

Usted * está * usando transacciones ... ¿verdad? Cuando una transacción finaliza InnoDB * debe * realizar un enjuague de hardware para garantizar el ["D" en ACID] ​​(http://en.wikipedia.org/wiki/ACID#Durability). Incluso los DB ACID rápidos están ** limitados a aproximadamente 30-50 * transacciones */segundo ** en discos de husillo "estándar". (Sin embargo, no es difícil obtener miles de * actualizaciones */segundo. Hay una diferencia). –

+2

Es cierto, no necesitamos el cumplimiento total de ACID. Pero, ¿y si queremos una forma más débil de ACI (no D) para características como el aislamiento de transacciones? Dado que nuestros datos no son demasiado sensibles, y usamos Amazon RDS con Multi-AZ, los choques raros y los fallos de energía no nos preocupan. – BrainCore

Respuesta

5

Encontré https://blogs.oracle.com/MySQL/entry/comparing_innodb_to_myisam_performance, que es precisamente lo que estaba buscando. El establecimiento de innodb-flush-log-at-trx-commit = 2 nos permite relajar las restricciones de ACID (el enjuague en el disco ocurre una vez por segundo) para el caso donde ocurre una falla de energía o un bloqueo del servidor. Esto nos da un comportamiento similar al MyISAM, pero aún así nos beneficiamos de las funciones de transacción disponibles en InnoDB.

Al ejecutar los mismos puntos de referencia, vemos una mejora de 10 veces en el rendimiento de escritura.

InnoDB (20 clientes concurrentes): cada actualización toma 0.017s. Todas las actualizaciones se realizan después de 0.98s.

4

Hemos hecho algunas pruebas similares en nuestra aplicación y notamos que si no se abre explícitamente ninguna transacción, cada instrucción de SQL se trata dentro de una transacción, lo cual lleva mucho más tiempo en ejecutarse. Si la lógica de su negocio lo permite, puede colocar varios comandos SQL dentro de un bloque de transacción, lo que reduce la carga general de ACID. En nuestro caso, hemos tenido una gran mejora en el rendimiento con este enfoque.

Cuestiones relacionadas