sql >> Base de Datos >  >> NoSQL >> MongoDB

Escribe a tu primer asesor

¿Alguna vez se preguntó qué desencadena el aviso en ClusterControl de que su disco se está llenando? ¿O el consejo de crear claves primarias en tablas InnoDB si no existen? Estos asesores son mini scripts escritos en el lenguaje específico de dominio (DSL) de ClusterControl, que es un lenguaje similar a Javascript. Estos scripts se pueden escribir, compilar, guardar, ejecutar y programar en ClusterControl. De eso se tratará la serie de blogs de ClusterControl Developer Studio.

Hoy cubriremos los conceptos básicos de Developer Studio y le mostraremos cómo crear su primer asesor donde elegiremos dos variables de estado y le daremos consejos sobre su resultado.

Los Consejeros

Los asesores son mini scripts que ClusterControl ejecuta, ya sea a pedido o después de un cronograma. Pueden ser cualquier cosa, desde simples consejos de configuración, advertencias sobre umbrales o reglas más complejas para predicciones o tareas de automatización de todo el clúster en función del estado de sus servidores o bases de datos. En general, los asesores realizan análisis más detallados y generan recomendaciones más completas que alertas.

Los asesores se almacenan dentro de la base de datos de ClusterControl y puede agregar asesores nuevos o alterar/modificar los existentes. También tenemos un repositorio Github de asesores donde puede compartir sus asesores con nosotros y otros usuarios de ClusterControl.

El lenguaje utilizado por los asesores es el llamado ClusterControl DSL y es un lenguaje de fácil comprensión. La semántica del lenguaje se puede comparar mejor con Javascript con un par de diferencias, donde las diferencias más importantes son:

  • Los puntos y comas son obligatorios
  • Varios tipos de datos numéricos como enteros y enteros largos largos sin signo.
  • Los arreglos son bidimensionales y los arreglos unidimensionales son listas.

Puede encontrar la lista completa de diferencias en la referencia de DSL de ClusterControl.

La interfaz de Developer Studio

La interfaz de Developer Studio se puede encontrar en Clúster> Administrar> Developer Studio. Esto abrirá una interfaz como esta:

Asesores

El botón de asesores generará una descripción general de todos los asesores con su salida desde la última vez que se ejecutaron:

También puede ver la programación del asesor en formato crontab y la fecha/hora desde la última actualización. Algunos asesores están programados para ejecutarse solo una vez al día, por lo que es posible que sus consejos ya no reflejen la realidad, por ejemplo, si ya resolvió el problema sobre el que se le advirtió. Puede volver a ejecutar manualmente el asesor seleccionándolo y ejecutándolo. Vaya a la sección "compilar y ejecutar" para leer cómo hacerlo.

Asesores de importación

El botón Importar le permitirá importar un tarball con nuevos asesores en ellos. El tarball debe crearse en relación con la ruta principal de los asesores, por lo que si desea cargar una nueva versión del script de tamaño de caché de consultas de MySQL (s9s/mysql/query_cache/qc_size.js), deberá crear el tarball comenzando del directorio s9s.

Asesores de exportación

Puede exportar los asesores o parte de ellos seleccionando un nodo en el árbol y presionando el botón Exportar. Esto creará un tarball con los archivos en la ruta completa de la estructura presentada. Supongamos que deseamos hacer una copia de seguridad de los asesores s9s/mysql antes de realizar un cambio, simplemente seleccionamos el nodo s9s/mysql en el árbol y presionamos Exportar:

Nota:asegúrese de que el directorio s9s esté presente en /home/myuser/.

Esto creará un tarball llamado /home/myuser/s9s/mysql.tar.gz con una estructura de directorio interna s9s/mysql/*

Crear un nuevo asesor

Ya que hemos cubierto las exportaciones e importaciones, ahora podemos comenzar a experimentar. ¡Así que vamos a crear un nuevo asesor! Haga clic en el botón Nuevo para obtener el siguiente diálogo:

En este diálogo, puede crear su nuevo asesor con un archivo vacío o llenarlo previamente con la plantilla específica de Galera o MySQL. Ambas plantillas agregarán las inclusiones necesarias (common/mysql_helper.js) y los conceptos básicos para recuperar los nodos de Galera o MySQL y recorrerlos.

La creación de un nuevo asesor con la plantilla de Galera se ve así:

#include "common/mysql_helper.js"

Aquí puede ver que mysql_helper.js se incluye para proporcionar la base para conectar y consultar nodos MySQL.

Este archivo contiene funciones que puede invocar si es necesario, como por ejemplo readVariable(,) que le permitirá obtener el valor de las variables globales o invocar readStatusVariable(,) que también le permitirá para obtener las variables de estado global en MySQL. Este archivo se puede ubicar en el árbol como se ve a continuación:

var WARNING_THRESHOLD=0;
…
if(threshold > WARNING_THRESHOLD)

El umbral de advertencia actualmente está establecido en 0, lo que significa que si el umbral medido es mayor que el umbral de advertencia, el asesor debe advertir al usuario. Tenga en cuenta que el umbral variable aún no está establecido/utilizado en la plantilla, ya que es un puntapié inicial para su propio asesor.

var hosts     = cluster::Hosts();
var hosts     = cluster::mySqlNodes();
var hosts     = cluster::galeraNodes();

Las declaraciones anteriores buscarán los hosts en el clúster y puede usar esto para recorrerlos. La diferencia entre ellos es que la primera declaración incluye todos los hosts que no son MySQL (también el host CMON), la segunda todos los hosts MySQL y la última solo los anfitriones Galera. Por lo tanto, si su clúster de Galera tiene adjuntos esclavos de lectura asíncronos de MySQL, esos hosts no se incluirán.

Aparte de eso, todos estos objetos se comportarán de la misma manera y contarán con la capacidad de leer sus variables, estado y consultarlos.

Botones de asesor

Ahora que hemos creado un nuevo asesor, hay seis nuevos botones disponibles para este asesor:

Guardar guardará sus últimas modificaciones en el asesor (almacenadas en la base de datos de CMON), Mover moverá el asesor a una nueva ruta y Eliminar obviamente eliminará al asesor.

Más interesante es la segunda fila de botones. La compilación del asesor compilará el código del asesor. Si el código se compila correctamente, verá este mensaje en Mensajes diálogo debajo del código del asesor:

Mientras que si la compilación falla, el compilador le dará una pista de dónde falló:

En este caso, el compilador indica que se encontró un error de sintaxis en la línea 24.

compilar y ejecutar El botón no solo compilará el script, sino que también lo ejecutará y su salida se mostrará en el diálogo Mensajes, Gráfico o Sin procesar. Si compilamos y ejecutamos el script de caché de tablas desde auto_tuners, obtendremos un resultado similar a este:

El último botón es el horario botón. Esto le permite programar (o desprogramar) sus asesores y agregarle etiquetas. Cubriremos esto al final de esta publicación cuando hayamos creado nuestro propio asesor y queramos programarlo.

Mi primer asesor

Ahora que hemos cubierto los conceptos básicos de ClusterControl Developer Studio, finalmente podemos comenzar a crear un nuevo asesor. Como ejemplo, crearemos un asesor para ver la proporción de la tabla temporal. Cree un nuevo asesor de la siguiente manera:

La teoría detrás del asesor que vamos a crear es simple:compararemos la cantidad de tablas temporales creadas en el disco con la cantidad total de tablas temporales creadas:

tmp_disk_table_ratio = Created_tmp_disk_tables / (Created_tmp_tables + Created_tmp_disk_tables) * 100;

Primero, debemos establecer algunos elementos básicos en el encabezado del script, como los umbrales y los mensajes de advertencia y ok. Todos los cambios y adiciones se aplican a continuación:

var WARNING_THRESHOLD=20;
var TITLE="Temporary tables on disk ratio";
var ADVICE_WARNING="More than 20% of temporary tables are written to disk. It is advised to review your queries, for example, via the Query Monitor.";
var ADVICE_OK="Temporary tables on disk are not excessive." ;

Establecimos el umbral aquí en 20 por ciento, que ya se considera bastante malo. Pero más sobre ese tema una vez que hayamos finalizado nuestro asesor.

A continuación, necesitamos obtener estas variables de estado de MySQL. Antes de saltar a conclusiones y ejecutar alguna consulta "MOSTRAR ESTADO GLOBAL COMO 'Created_tmp_%'", ya existe una función para recuperar la variable de estado de una instancia de MySQL, como describimos anteriormente donde esta función se encuentra en common/mysql_helper. js:

statusVar = readStatusVariable(<host>, <statusvariablename>);

Podemos usar esta función en nuestro asesor para buscar las tablas de disco_tmp_creadas y las tablas_tmp_creadas.

    for (idx = 0; idx < hosts.size(); ++idx)
    {
        host        = hosts[idx];
        map         = host.toMap();
        connected     = map["connected"];
        var advice = new CmonAdvice();
        var tmp_tables = readStatusVariable(host, ‘Created_tmp_tables’);
        var tmp_disk_tables = readStatusVariable(host, ‘Created_tmp_disk_tables’);

Y ahora podemos calcular la proporción de tablas de discos temporales:

        var tmp_disk_table_ratio = tmp_disk_tables / (tmp_tables + tmp_disk_tables) * 100;

Y alerta si este ratio es superior al umbral que establecimos al principio:

        if(checkPrecond(host))
        {
           if(tmp_disk_table_ratio > WARNING_THRESHOLD) {
               advice.setJustification("Temporary tables written to disk is excessive");
               msg = ADVICE_WARNING;
           }
           else {
               advice.setJustification("Temporary tables written to disk not excessive");
               msg = ADVICE_OK;
           }
        }

Es importante asignar aquí el aviso a la variable msg, ya que se agregará más adelante al objeto de aviso con la función setAdvice(). El guión completo para completar:

#include "common/mysql_helper.js"

/**
 * Checks the percentage of max ever used connections 
 * 
 */ 
var WARNING_THRESHOLD=20;
var TITLE="Temporary tables on disk ratio";
var ADVICE_WARNING="More than 20% of temporary tables are written to disk. It is advised to review your queries, for example, via the Query Monitor.";
var ADVICE_OK="Temporary tables on disk are not excessive.";

function main()
{
    var hosts     = cluster::mySqlNodes();
    var advisorMap = {};

    for (idx = 0; idx < hosts.size(); ++idx)
    {
        host        = hosts[idx];
        map         = host.toMap();
        connected     = map["connected"];
        var advice = new CmonAdvice();
        var tmp_tables = readStatusVariable(host, 'Created_tmp_tables');
        var tmp_disk_tables = readStatusVariable(host, 'Created_tmp_disk_tables');
        var tmp_disk_table_ratio = tmp_disk_tables / (tmp_tables + tmp_disk_tables) * 100;
        
        if(!connected)
            continue;
        if(checkPrecond(host))
        {
           if(tmp_disk_table_ratio > WARNING_THRESHOLD) {
               advice.setJustification("Temporary tables written to disk is excessive");
               msg = ADVICE_WARNING;
               advice.setSeverity(0);
           }
           else {
               advice.setJustification("Temporary tables written to disk not excessive");
               msg = ADVICE_OK;
           }
        }
        else
        {
            msg = "Not enough data to calculate";
            advice.setJustification("there is not enough load on the server or the uptime is too little.");
            advice.setSeverity(0);
        }
        advice.setHost(host);
        advice.setTitle(TITLE);
        advice.setAdvice(msg);
        advisorMap[idx]= advice;
    }
    return advisorMap;
}

Ahora puede jugar con el umbral de 20, intentar reducirlo a 1 o 2, por ejemplo, y luego probablemente pueda ver cómo este asesor realmente le dará consejos al respecto.

Como puede ver, con un script simple puede comparar dos variables entre sí y generar informes/consejos en función de su resultado. ¿Pero eso es todo? ¡Todavía hay un par de cosas que podemos mejorar!

Mejoras en mi primer asesor

Lo primero que podemos mejorar es que este asesor no tiene mucho sentido. Lo que la métrica realmente refleja es el número total de tablas temporales en el disco desde el último FLUSH STATUS o inicio de MySQL. Lo que no dice es a qué tarifa en realidad crea tablas temporales en el disco. Entonces podemos convertir las tablas de disco_tmp_creadas a una tasa usando el tiempo de actividad del host:

    var tmp_disk_table_rate = tmp_disk_tables / uptime;

Esto debería darnos el número de tablas temporales por segundo y combinado con tmp_disk_table_ratio, esto nos dará una visión más precisa de las cosas. Una vez más, una vez que alcanzamos el umbral de dos tablas temporales por segundo, no queremos enviar una alerta/consejo de inmediato.

Otra cosa que podemos mejorar es no usar la función readStatusVariable(, ) de la biblioteca common/mysql_helper.js. Esta función ejecuta una consulta al host MySQL cada vez que leemos una variable de estado, mientras que CMON ya recupera la mayoría de ellas cada segundo y no necesitamos un estado en tiempo real de todos modos. No es que dos o tres consultas eliminen los hosts en el clúster, pero si muchos de estos asesores se ejecutan de manera similar, esto podría generar montones de consultas adicionales.

En este caso, podemos optimizar esto recuperando las variables de estado en un mapa usando la función host.sqlInfo() y recuperando todo a la vez como un mapa. Esta función contiene la información más importante del host, pero no la contiene toda. Por ejemplo, el tiempo de actividad variable que necesitamos para la tarifa no está disponible en el mapa host.sqlInfo() y debe recuperarse con la función readStatusVariable(, ).

Así es como se verá nuestro asesor ahora, con los cambios/adiciones marcados en negrita:

#include "common/mysql_helper.js"

/**
 * Checks the percentage of max ever used connections 
 * 
 */ 
var RATIO_WARNING_THRESHOLD=20;
var RATE_WARNING_THRESHOLD=2;
var TITLE="Temporary tables on disk ratio";
var ADVICE_WARNING="More than 20% of temporary tables are written to disk and current rate is more than 2 temporary tables per second. It is advised to review your queries, for example, via the Query Monitor.";
var ADVICE_OK="Temporary tables on disk are not excessive.";

function main()
{
    var hosts     = cluster::mySqlNodes();
    var advisorMap = {};

    for (idx = 0; idx < hosts.size(); ++idx)
    {
        host        = hosts[idx];
        map         = host.toMap();
        connected     = map["connected"];
        var advice = new CmonAdvice();
        var hostStatus = host.sqlInfo();
        var tmp_tables = hostStatus['CREATED_TMP_TABLES'];
        var tmp_disk_tables = hostStatus['CREATED_TMP_DISK_TABLES'];
        var uptime = readStatusVariable(host, 'uptime');
        var tmp_disk_table_ratio = tmp_disk_tables / (tmp_tables + tmp_disk_tables) * 100;
        var tmp_disk_table_rate = tmp_disk_tables / uptime;
        
        if(!connected)
            continue;
        if(checkPrecond(host))
        {
           if(tmp_disk_table_rate > RATE_WARNING_THRESHOLD && tmp_disk_table_ratio > RATIO_WARNING_THRESHOLD) {
               advice.setJustification("Temporary tables written to disk is excessive: " + tmp_disk_table_rate + " tables per second and overall ratio of " + tmp_disk_table_ratio);
               msg = ADVICE_WARNING;
               advice.setSeverity(0);
           }
           else {
               advice.setJustification("Temporary tables written to disk not excessive");
               msg = ADVICE_OK;
           }
        }
        else
        {
            msg = "Not enough data to calculate";
            advice.setJustification("there is not enough load on the server or the uptime is too little.");
            advice.setSeverity(0);
        }
        advice.setHost(host);
        advice.setTitle(TITLE);
        advice.setAdvice(msg);
        advisorMap[idx]= advice;
    }
    return advisorMap;
}

Programar mi primer asesor

Después de guardar este nuevo asesor, compilarlo y ejecutarlo, ahora podemos programar este asesor. Dado que no tenemos una carga de trabajo excesiva, probablemente ejecutaremos este asesor una vez al día.

El modo de programación base es similar a Cron, que tiene cada minuto, 5 minutos, hora, día, mes predeterminado y esto es exactamente lo que necesitamos y es muy fácil administrar la programación. Cambiar esto a avanzado desbloqueará los otros campos de entrada atenuados. Estos campos de entrada funcionan exactamente igual que un crontab, por lo que incluso puede programar para un día en particular, un día del mes o incluso configurarlo entre semana.

Siguiendo este blog, crearemos un verificador para SELinux o controles de seguridad para Spectre y Meltdown si los nodos se ven afectados. ¡Estén atentos!