[syslog-ng] time_sleep() and inadvertent admission control

Balazs Scheidler bazsi at balabit.hu
Mon Jan 28 20:52:36 CET 2008


On Mon, 2008-01-28 at 10:26 -0800, Evan Rempel wrote:
> Balazs Scheidler wrote:
> > On Thu, 2008-01-24 at 14:18 -0500, John Morrissey wrote:
> >> About a year ago, I noticed heavy CPU consumption during certain workloads
> >> (many processes sending a small number of log messages per process, such as
> >> a busy Postfix machine) due to io_iter spinning very rapidly on poll(). We
> >> kludged around it by adding the time_sleep() directive, to add an artificial
> >> delay at the end of the io_iter loop and prevent the loop from rolling over
> >> too quickly:
> >>
> >> http://marc.info/?l=syslog-ng&m=114009552929622&w=2
> >>
> >> We started using time_sleep(30) across all of our machines, since that delay
> >> value didn't seem to cause any problems for our workloads and we wanted to
> >> keep the configuration uniform.
> >>
> >> We noticed recently that time_sleep() exhibits some inadvertent admission
> >> control behavior. When poll() indicates that the listener socket has
> >> activity (new connections), syslog-ng seems to accept() only once on it,
> >> allowing one new connection per poll(). As a result, it only allows:
> >>
> >>   1000 / time_sleep()
> >>
> >> connections per second. Accordingly, with time_sleep(30), only 33
> >> connections would be allowed every second. 
> > 
> > 
> > Thanks for the detailed analysis (and for the original idea too :), I
> > think the following solutions exist:
> > 
> >  * do multiple accepts per poll loop; or
> >  * increase the I/O priority for the listeners
> > 
> > The first one easily increases the incoming connection rate and is
> > simple to implement, the second is more complex and might cause further
> > unexpected behaviour:
> > 
> > if the priority of the listeners is increased, that would mean that any
> > incoming connection might starve the incoming message stream, e.g. if
> > there's a continous stream of incoming connections, then long-living
> > connections might be starved.
> > 
> > So I'd choose the first option, what do you think?
> 
> Would it be possible to have an acceptor thread that does not use the time_sleep()
> and let the I/O reader threads honor this setting? That way there would
> not be any starvation and there would not be any interaction from time_sleep() and accepting
> connections.
> 
> Just throwing this idea out there as I am not aware of the architecture of the code.

The same can be achieved by much simpler changes. I could do a poll() call for all 
listener fds and if that returns nothing in 10msecs, I'd sleep for time_sleep()-10msec 
and then poll for everything, but I'm not sure this is worth it. Doing multiple 
accepts in each poll iteration should be just as good.

Syslog-ng is not multithreaded now (this is something I'm planning to change).

-- 
Bazsi



More information about the syslog-ng mailing list