फाइल IO की तुलना में syslog इतना धीमा क्यों है?


9

मैंने सिसलॉग फ़ंक्शन के प्रदर्शन को मापने के लिए एक साधारण परीक्षण कार्यक्रम लिखा। यह मेरी परीक्षण प्रणाली के परिणाम हैं: (लिनक्स 2.6.22-5-amd64 के साथ डेबियन 6.0.2)

Test Case             Calls       Payload     Duration    Thoughput 
                      []          [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     

परीक्षण कार्यक्रम ने प्रत्येक कॉल के दौरान 50 बाइट्स डेटा लिखने वाले 200000 सिस्टम कॉल किए।

फाइल IO की तुलना में Syslog दस गुना अधिक धीमा क्यों है?

यह वह कार्यक्रम है जिसका मैंने परीक्षण किया था:

#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 ();
}

संभवतः, "संदेश और प्रतिक्रिया" तंत्र के साथ, syslog कॉल अधिक जटिल हैं, अधिक उपरि है, कई उपयोगकर्ता-अंतरिक्ष प्रक्रियाओं (डिवाइस या कंसोल पर लिखने के विपरीत) के बीच यात्रा करते हैं, और संदेश नहीं आने तक वापस नहीं आएंगे सफलतापूर्वक स्वीकार किया गया।
afrazier

1
रिचर्ड के जवाब के अनुसार, क्या संख्याएं समान दिखती हैं यदि आप फ़र्फ़रफ़ () के बाद फ़्लफ़श (एफपी) जोड़ते हैं?
sep332

@ sep3332 जोड़ा जाने के बाद O_SYNC ध्वज को open() कार्य और fflush(fp) एक के बाद एक fprintf() कॉल, परिणाम बन जाते हैं [3.86, 3.63, 151.53, 23.00] MB/s मेरे कंप्यूटर में (लेनोवो T61, डेबियन परीक्षण)। यह अब बेहतर लगता है लेकिन, जाँच करें /etc/rsyslog.conf, यह पहले से ही syslogs के लिए गैर-सिंक मोड में है।
Xiè Jìléi

जवाबों:


11

Syslog प्रति कॉल में AF_UNIX सॉकेट को एक अंक () दोनों जारी करता है। यहां तक ​​कि अगर syslogd डेटा को छोड़ देता है तो भी इसे पहले पढ़ना होगा। इस सब में समय लगता है।

राइट टू / देव / नल भी प्रति कॉल एक राइट () जारी करते हैं, लेकिन चूंकि डेटा खारिज हो जाता है, इसे कर्नेल द्वारा बहुत तेज़ी से संसाधित किया जा सकता है।

फ़र्फ़रफ़ () कॉल हर 4096 बाइट्स के लिए केवल एक राइट () जनरेट करता है जो ट्रांसफर किया जाता है, यानी लगभग हर अस्सी प्रिंटफ कॉल। प्रत्येक में केवल libc के बफर से कर्नेल के बफ़र्स में डेटा स्थानांतरित करना शामिल है। डिस्क के लिए प्रतिबद्ध (बहुत कम से कम तुलना में) बहुत धीमी गति से होगा, लेकिन किसी भी स्पष्ट सिंक्रनाइज़ेशन कॉल की अनुपस्थिति में बाद में हो सकता है (शायद प्रक्रिया समाप्त होने के बाद भी)।

संक्षेप में: syslog / dev / null की तुलना में धीमा है क्योंकि यह बहुत सारे काम कर रहा है और बफ़र करने के कारण प्रिंटफ़ से फ़ाइल में धीमी है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.