Ich habe ein einfaches Testprogramm geschrieben, um die Leistung der Syslog-Funktion zu messen. Dies sind die Ergebnisse meines Testsystems: (Debian 6.0.2 mit Linux 2.6.32-5-amd64)
Testfall ruft Payload Duration Thoughput auf [] [MB] [s] [MB / s] -------------------- ---------- ---------- ---------- ---------- syslog 200000 10.00 7.81 1.28 syslog% s 200000 10.00 9.94 1.01 write / dev / null 200000 10.00 0.03 343.93 printf% s 200000 10.00 0.13 76.29
Das Testprogramm hat 200000 Systemaufrufe ausgeführt und bei jedem Aufruf 50 Datenbytes geschrieben.
Warum ist Syslog mehr als zehnmal langsamer als Datei-E / A?
Dies ist das Programm, mit dem ich den Test durchgeführt habe:
#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
quelle
quelle
O_SYNC
Flags zuropen()
Funktion undfflush(fp)
nach jedem Aufruf werdenfprintf()
die Ergebnisse[3.86, 3.63, 151.53, 23.00] MB/s
auf meinem Computer gespeichert (Lenovo T61, Debian-Test). Es scheint jetzt besser zu sein, aber überprüfen Sie/etc/rsyslog.conf
, dass es für Syslogs bereits nicht synchron ist.Antworten:
Die Syslog-Aufrufe geben beide pro Aufruf ein send () an einen AF_UNIX-Socket aus. Selbst wenn das syslogd die Daten verwirft, muss es sie zuerst lesen. Das alles braucht Zeit.
Die Schreibvorgänge in / dev / null geben ebenfalls ein write () pro Aufruf aus. Da die Daten jedoch verworfen werden, können sie vom Kernel sehr schnell verarbeitet werden.
Die Aufrufe von fprintf () erzeugen nur ein Schreiben () für jeweils 4096 übertragene Bytes, dh etwa eines von achtzig printf-Aufrufen. In jedem Fall werden nur Daten aus dem libc-Puffer in die Puffer des Kernels übertragen. Das Festschreiben auf die Festplatte ist (zumindest im Vergleich) sehr langsam, aber wenn keine expliziten Synchronisationsaufrufe vorliegen, kann dies später erfolgen (möglicherweise sogar nach Beendigung des Prozesses).
Kurz gesagt: syslog ist langsamer als / dev / null, weil es viel Arbeit leistet und aufgrund der Pufferung langsamer als printf in eine Datei.
quelle