¿Vale la pena la sobrecarga de la invalidación frecuente de la caché de consultas?

22

Actualmente estoy trabajando en una base de datos MySQL donde estamos viendo una gran cantidad de invalidaciones de la caché de consultas, principalmente debido a la gran cantidad de instrucciones INSERT, DELETE y UPDATE que se ejecutan en muchas de las tablas.

Lo que estoy tratando de determinar es si existe o no algún beneficio al permitir que el caché de consultas se use para las instrucciones SELECT que se ejecutan en estas tablas. Como se invalidan tan rápido, me parece que lo mejor sería usar SQL_NO_CACHE en las instrucciones SELECT con estas tablas.

¿Vale la pena la sobrecarga de invalidación frecuente?

Editar: a pedido del usuario @RolandoMySQLDBA a continuación, aquí está la información sobre MyISAM e INNODB.

InnoDB

  • Tamaño de datos: 177.414 GB
  • Tamaño del índice: 114,792 GB
  • Tamaño de la mesa: 292.205 GB

MyISAM

  • Tamaño de datos: 379.762 GB
  • Tamaño del índice: 80,681 GB
  • Tamaño de la mesa: 460.443 GB

Información adicional:

  • Versión: 5.0.85
  • query_cache_limit: 1048576
  • query_cache_min_res_unit: 4096
  • query_cache_size: 104857600
  • query_cache_type: ON
  • query_cache_wlock_invalidate: OFF
  • innodb_buffer_pool_size: 8841592832
  • 24 GB de RAM
Craig Sefton
fuente
2
dom.as/tech/query-cache-tuner lo resume muy bien
Laurynas Biveinis
Jeje, muy perspicaz.
Craig Sefton

Respuestas:

16

Simplemente debe deshabilitar la caché de consultas con

[mysqld]
query_cache_size = 0

y luego reinicie mysql. ¿Por qué sugeriría eso?

Query Cache siempre se topará con InnoDB. Sería bueno que MVCC de InnoDB permitiera que las consultas se atendieran desde el caché de consultas si las modificaciones no afectan las lecturas repetibles para otras transacciones. Desafortunadamente, InnoDB simplemente no hace eso. Aparentemente, tiene muchas consultas que se invalidan con bastante rapidez y probablemente no se reutilicen.

Para InnoDB en MySQL 4.0, la caché de consultas estaba deshabilitada para las transacciones. Para MySQL 4.1+, InnoDB juega al policía de tráfico cuando permite el acceso al caché de consultas por tabla.

Desde la perspectiva de su pregunta, diría que la justificación de eliminar la caché de consultas no es tanto la sobrecarga, sino cómo InnoDB lo maneja.

Para obtener más información sobre cómo InnoDB interactúa con el caché de consultas, lea las páginas 213-215 del libro "High Performance MySQL (Segunda edición)" .

Si todos o la mayoría de sus datos son MyISAM, podría seguir con su idea original de usar SQL_NO_CACHE.

Si tiene una combinación de InnoDB y MyISAM, tendrá que encontrar el equilibrio adecuado para su aplicación en función de cuán altas sean las pérdidas de caché. De hecho, las páginas 209-210 del mismo libro señalan las razones de las fallas de caché:

  • La consulta no se puede almacenar en caché, ya sea porque contiene una construcción no determinista (como CURRENT_DATE) o porque su conjunto de resultados es demasiado grande para almacenar. Ambos tipos de consultas no almacenables en caché incrementan la variable de estado Qcache_not_cached.
  • El servidor nunca antes había visto la consulta, por lo que nunca tuvo la oportunidad de almacenar en caché su resultado.
  • El resultado de la consulta fue previamente almacenado en caché, pero el servidor lo eliminó. Esto puede suceder porque no había suficiente memoria para mantenerlo, porque alguien le indicó al servidor que lo eliminara o porque se invalidó

y las causas raíz de errores de caché altos con pocas consultas que no se pueden almacenar en caché pueden ser:

  • El caché de consultas aún no está caliente. Es decir, el servidor no ha tenido la oportunidad de llenar el caché con conjuntos de resultados.
  • El servidor está viendo consultas que no ha visto antes. Si no tiene muchas consultas repetidas, esto puede suceder incluso después de que el caché se haya calentado.
  • Hay muchas invalidaciones de caché.

ACTUALIZACIÓN 2012-09-06 10:10 EDT

Buscando su última información actualizada, la ha query_cache_limitconfigurado en 1048576 (1M). Esto limita cualquier conjunto de resultados a 1M. Si recupera algo más grande, simplemente no se almacenará en caché. Si bien se ha query_cache_sizeconfigurado en 104857600 (100M), esto solo permite 100 resultados en caché establecidos en un mundo perfecto. Si realiza cientos de consultas, la fragmentación se producirá con bastante rapidez. También tiene 4096 (4K) como el conjunto de resultados de tamaño mínimo. Desafortunadamente, mysql no tiene un mecanismo interno para desfragmentar el caché de consultas.

Si debe tener el caché de consultas y tiene tanta RAM, puede ejecutar lo siguiente:

SET GLOBAL query_cache_size = 0;
SELECT SLEEP(60);
SET GLOBAL query_cache_size = 1024 * 1024 * 1024;

para purgar el caché de consultas. Pierde todos los resultados almacenados en caché, así que ejecute estas líneas durante las horas de menor actividad.

También asignaría lo siguiente:

  • query_cache_size = 1G
  • query_cache_limit = 8M

Eso deja 23G de RAM. Yo plantearía lo siguiente:

  • innodb_buffer_pool_size = 12G
  • key_buffer_size = 4G

Eso deja 7G. Esto debería ser adecuado para OS y conexiones DB.

Tenga en cuenta que el búfer clave almacena en caché solo las páginas de índice MyISAM, mientras que el InnoDB Buffer Pool almacena en caché datos e índices.

Una recomendación más: actualice a MySQL 5.5 para que pueda configurar InnoDB para múltiples CPU y múltiples hilos para E / S de lectura / escritura.

Vea mis publicaciones anteriores sobre el uso de MySQL 5.5 junto con el acceso a múltiples CPU para InnoDB

ACTUALIZACIÓN 2012-09-06 14:56 EDT

Mi método para borrar el caché de consultas es bastante extremo porque almacena datos en caché y forma un segmento de RAM completamente diferente. Como señaló en su comentario, FLUSH QUERY CACHE(como sugirió) o incluso RESET QUERY CACHEsería mejor. Para aclarar, cuando dije "sin mecanismo interno", quise decir exactamente eso. La desfragmentación es necesaria y debe hacerse manualmente. Tendría que ser crontab'd .

Si hace DML (INSERTs, UPDATEs, DELETEs) en InnoDB con más frecuencia que en MyISAM, diría que elimine la caché de consultas por completo, lo que dije al principio.

RolandoMySQLDBA
fuente
Gracias por la respuesta. Tengo ese libro y lo he estado usando extensamente; Soy muy consciente de las razones por las que describe las fallas de caché, pero como mencioné, ya hemos identificado las invalidaciones de caché como un problema clave debido a la fuerte correlación que estamos viendo entre Com_select y Qcache_inserts. Ah, y el DB en cuestión tiene una mezcla de INNODB y MyISAM.
Craig Sefton
Actualizado con la información adicional que solicitó. Gracias.
Craig Sefton
Gracias por la respuesta, espero el resto. Una de las cosas que identificamos fue que aproximadamente el 18% de las consultas no se almacenaban en caché, por lo que definitivamente apreciamos los consejos sobre la configuración. Lamentablemente, el cuadro no está dedicado, pero sus recomendaciones deberían ayudar. La fragmentación es definitivamente un problema también. Todavía estoy realmente preocupado por la cantidad de invalidaciones que estamos viendo (a diferencia de las consultas que no están almacenadas en caché), por lo que aún no estoy seguro de si la sobrecarga vale la pena. Realmente aprecio su comprensión, muchas gracias.
Craig Sefton
Con respecto a su comentario sobre "mysql no tiene un mecanismo interno para desfragmentar el caché de consultas", ¿no puede ejecutar el comando FLUSH QUERY CACHEpara desfragmentarlo? Ver: dev.mysql.com/doc/refman/5.0/en/flush.html
Craig Sefton
Actualicé
3

MALO: query_cache_size = 1G

¿Por qué? Debido a cuánto tiempo llevará una descarga. Es decir, cuando se produce algo de escritura, se escaneará todo el 1GB para encontrar referencias a la tabla que se modificó. Cuanto más grande es el control de calidad, más lento es. Recomiendo un tamaño de no más de 50M, a menos que sus datos rara vez cambien.

El control de calidad está sobrecargado para MyISAM e InnoDB. Saca un Mutex global y lo saca demasiado pronto. Este mutex es una razón por la que MySQL no puede hacer un uso efectivo de más de aproximadamente 8 núcleos.

SQL_NO_CACHE no se nota hasta después de la exclusión mutua está bloqueado! El único uso para esa bandera es el benchmarking.

A menudo es mejor darle la RAM a alguna otra caché.

Rick James
fuente
2

Puedo pensar en un caso perfecto para ello, y lo hemos probado exhaustivamente y lo ejecutamos en producción ... Lo llamo la estrategia de agrupación de "carril rápido" :

Si realiza la división de lectura y escritura con un proxy como MaxScale, o su aplicación es capaz, puede enviar algunas de las lecturas de esas tablas que rara vez se invalidan solo a los esclavos que tienen activada la caché de consultas, y el resto a otros esclavos con ella. apagado.

Hacemos esto y manejamos llamadas de 4M por minuto al clúster durante nuestras pruebas de carga (no un punto de referencia ... el verdadero negocio) como resultado. La aplicación espera en master_pos_wait () por algunas cosas, por lo que se ve limitada por el hilo de replicación, y aunque lo hemos visto con un estado de espera en la invalidación de Qcache a un rendimiento muy alto, esos niveles de rendimiento son incluso más altos que el clúster. capaz de sin Qcache.

Esto funciona porque rara vez hay algo relevante en la pequeña caché de consultas en esas máquinas para invalidar (esas consultas solo son relevantes para tablas actualizadas con poca frecuencia). Estas cajas son nuestro "carril rápido". Para el resto de las consultas que hace la aplicación, no tienen que lidiar con Qcache ya que van a cuadros sin activarlo.

Christopher McGowan
fuente