Zabbix-API y tiempo de ejecución

En la entrada de hoy voy a comentar una cosa curiosa que me sucedió y a la que le sigo dando vueltas. El software empleado es Zabbix con algunas pequeñas modificaciones que le había aplicado, para tener unos mapas con un poco más de información.
Pongámonos en situación. Zabbix, desde la versión 1.8 trae un API de consulta bastante potente y de la que ya hablamos en otras ocasiones aquí. El propio interfaz gráfico hace uso de ella para obtener sus datos. Especialmente en la versión 2.0 de Zabbix, el uso del API es cada vez más extendido en el frontend. El problema es saber cómo trabajar con un API. No el API de Zabbix, sino cualquier API. ¿Debemos hacer muchas consultas pequeñas? ¿Sólo una y más grande? Mi conclusión, cuando menos para Zabbix, es más óptimo sacar los datos en cuantas menos consultas mejor.
Veamos un ejemplo del fallo.
...
$options = array(
   'nodeids' => get_current_nodeid(true),
   'hostids' => $hostids,
   'output' => array('status'),
   'nopermissions' => true,
   'preservekeys' => true,
   'selectScreens' => API_OUTPUT_COUNT,
);
$hosts = API::Host()->get($options);
foreach ($hosts as $db_element) {
 ...
 if ($db_element['elementtype'] == SYSMAP_ELEMENT_TYPE_HOST) {
  $options = array(
     'hostids' => $db_element["elementid"],
     'output' => array('value', 'description'),
     'nopermissions' => true,
     'filter' => array('value_flags' => null),
     'monitored' => true,
     'skipDependent' => true,
     'only_true' => 1
  );
  $triggers = API::Trigger()->get($options);
  if(count($triggers) > 0) {
   ...
  }
 ...
 }
...
Esta es la parte del código original de Zabbix, en el fichero include/maps.inc.php. Aunque aquí se presenta de forma simplificada, la idea es que se hace una consulta al API (API::Host()) de la que se obtienen los datos de estado de un listado de equipos. Esos equipos son los que pertenecen a un mapa. Después de trabajar con ellos, para un añadido propio, se hace una nueva llamada al API, en la que para cada elemento de tipo HOST se hace una nueva llamada al API de la que se sacan los trigger's que tenga activo el host en cuestión.
Hasta aquí todo correcto y funciona a la perfección. Con un mapa de 10 elementos, por ejemplo, todo es correcto. El problema viene cuando el mapa comienza a tener más de 20 elementos de tipo HOST.  Si el número de elementos (hablando siempre de tipo HOST) es de 7, las llamadas al API será 7, si son 12, 12 y así siempre. Esto es lógico, ¿no?
La lógica también dice que si una llamada tarda en ejecutarse 0.1 segundos, 10 llamadas tardarán 1 segundo. Que yo sepa, el API de Zabbix no hace ningún tipo de filtrado por llamadas excesivas ni nos bloquea por demasiadas peticiones, por lo tanto, lo que me pasó es algo muy curioso.
Si el número de equipos de tipo HOST que tenía en un mapa pasaba de 15, en sacar los datos tardaba entorno a ~20 segundos. Lo normal sería que tardase 2 segundos, podemos asumir incluso 5 segundos, pero si los mapas tenían entorno a 20 equipos, el tiempo no era proporcional al número de llamadas, sino que se disparaba. Esto no entraba dentro de lo esperado, para nada.
Por suerte, la solución fue sencilla y mucho más óptima en cuando a número de llamadas, pero siempre quedará ahí patente el por qué de la tardanza en la ejecución. La base de datos no tenía problema, al servidor web no le subía la carga. Es y quizás seguirá siendo un misterio.

Puede que la informática no siempre sea determinista o que los algoritmos de basen, no siempre sean así.

La entrada Zabbix-API y tiempo de ejecución la puedes leer en Puppet Linux.


No hay comentarios :

Publicar un comentario

Formulario de contacto

Nombre

Correo electrónico *

Mensaje *

Últimos comentarios