Escribí un programa de prueba simple para medir el rendimiento de la función syslog. Estos son los resultados de mi sistema de prueba: (Debian 6.0.2 con Linux 2.6.32-5-amd64)
Caso de prueba Llamadas Duración de la carga útil Pensamiento [] [MB] [s] [MB / s] -------------------- ---------- ---------- ---------- ---------- syslog 200000 10.00 7.81 1.28 syslog% s 200000 10.00 9.94 1.01 escribir / dev / nulo 200000 10.00 0.03 343.93 printf% s 200000 10.00 0.13 76.29
El programa de prueba realizó 200000 llamadas al sistema escribiendo 50 bytes de datos durante cada llamada.
¿Por qué Syslog es más de diez veces más lento que el archivo IO?
Este es el programa que utilicé para realizar la prueba:
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <syslog.h>
#include <unistd.h>
const int iter = 200000;
const char msg[] = "123456789 123456789 123456789 123456789 123456789";
struct timeval t0;
struct timeval t1;
void start ()
{
gettimeofday (&t0, (void*)0);
}
void stop ()
{
gettimeofday (&t1, (void*)0);
}
void report (char *action)
{
double dt = (double)t1.tv_sec - (double)t0.tv_sec +
1e-6 * ((double)t1.tv_usec - (double)t0.tv_usec);
double mb = 1e-6 * sizeof (msg) * iter;
if (action == NULL)
printf ("Test Case Calls Payload Duration Thoughput \n"
" [] [MB] [s] [MB/s] \n"
"-------------------- ---------- ---------- ---------- ----------\n");
else {
if (strlen (action) > 20) action[20] = 0;
printf ("%-20s %-10d %-10.2f %-10.2f %-10.2f\n",
action, iter, mb, dt, mb / dt);
}
}
void test_syslog ()
{
int i;
openlog ("test_syslog", LOG_PID | LOG_NDELAY, LOG_LOCAL0);
start ();
for (i = 0; i < iter; i++)
syslog (LOG_DEBUG, msg);
stop ();
closelog ();
report ("syslog");
}
void test_syslog_format ()
{
int i;
openlog ("test_syslog", LOG_PID | LOG_NDELAY, LOG_LOCAL0);
start ();
for (i = 0; i < iter; i++)
syslog (LOG_DEBUG, "%s", msg);
stop ();
closelog ();
report ("syslog %s");
}
void test_write_devnull ()
{
int i, fd;
fd = open ("/dev/null", O_WRONLY);
start ();
for (i = 0; i < iter; i++)
write (fd, msg, sizeof(msg));
stop ();
close (fd);
report ("write /dev/null");
}
void test_printf ()
{
int i;
FILE *fp;
fp = fopen ("/tmp/test_printf", "w");
start ();
for (i = 0; i < iter; i++)
fprintf (fp, "%s", msg);
stop ();
fclose (fp);
report ("printf %s");
}
int main (int argc, char **argv)
{
report (NULL);
test_syslog ();
test_syslog_format ();
test_write_devnull ();
test_printf ();
}
linux
debian-squeeze
syslog
ceving
fuente
fuente
O_SYNC
indicador a laopen()
función yfflush(fp)
después de cadafprintf()
llamada, los resultados se convierten[3.86, 3.63, 151.53, 23.00] MB/s
en mi computadora (Lenovo T61, prueba de Debian). Parece mejor ahora pero, compruebe/etc/rsyslog.conf
, ya está en modo no sincronizado para syslogs.Respuestas:
Las llamadas de syslog emiten un envío () a un socket AF_UNIX por llamada. Incluso si el syslogd descarta los datos, todavía tendrá que leerlos primero. Todo esto lleva tiempo.
Las escrituras en / dev / null también emiten una escritura () por llamada, pero como los datos se descartan, el núcleo puede procesarlos muy rápidamente.
Las llamadas fprintf () solo generan una escritura () por cada 4096 bytes que se transfieren, es decir, aproximadamente una cada ochenta llamadas printf. Cada uno solo implica transferir datos desde el búfer de libc a los búferes del núcleo. La confirmación en el disco será (al menos en comparación) muy lenta, pero en ausencia de cualquier llamada de sincronización explícita puede ocurrir más tarde (tal vez incluso después de que finalice el proceso).
En resumen: syslog es más lento que / dev / null porque está haciendo mucho trabajo y más lento que printf en un archivo debido al almacenamiento en búfer.
fuente