[rrd-developers] rrdcached client and unnecessary lstat syscalls
Martin Sperl
rrdtool at martin.sperl.org
Wed Aug 10 14:40:53 CEST 2011
Hi!
I have made one observation when using rrdtool to update some rrdfiles
that are updated via rrdcached in my C-Programm.
For an update that essentially would look like this on the command-line:
rrdtool update --daemon /socket \
/home/msperl/xymon-4.3.4/testdata/servername/ifstat-lo/lo.rrd\
1312899067:5453845452:5372645:0:0:0:0:0:0:5453845452:5372645:0:0:0:0:0
I get an strace output of:
04:42:26.968621 read(3, "0 errors, enqueued 1 value(s).\n", 4096) = 31
04:42:26.968704 lstat("/home", {st_mode=S_IFDIR|0755, st_size=16384,
...}) = 0
04:42:26.968755 lstat("/home/msperl", {st_mode=S_IFDIR|0755,
st_size=4096, ...}) = 0
04:42:26.968805 lstat("/home/msperl/xymon-4.3.4", {st_mode=S_IFDIR|0755,
st_size=4096, ...}) = 0
04:42:26.968857 lstat("/home/msperl/xymon-4.3.4/testdata",
{st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
04:42:26.968910 lstat("/home/msperl/xymon-4.3.4/testdata/servername",
{st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
04:42:26.968967
lstat("/home/msperl/xymon-4.3.4/testdata/servername/ifstat-lo",
{st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
04:42:26.969027
lstat("/home/msperl/xymon-4.3.4/testdata/servername/ifstat-lo/lo.rrd",
{st_mode=S_IFREG|0644, st_size=5755424, ...}) = 0
04:42:26.969092 write(3, "update
/home/msperl/xymon-4.3.4/testdata/servername/ifstat-lo/lo.rrd
1312899067:5453845452:5372645:0:0:0:0:0:0:5453845452:5372645:0:0:0:0:0\n",
166) = 166
04:42:26.969159 read(3, "0 errors, enqueued 1 value(s).\n", 4096) = 31
So we see that for a simple update we spend about: 0.000388s on
lstat-ing those directories (and that repeatedly!).
That is 72% of the time the whole processing loop takes (0.00538s)!
If I use the same code, but without the daemon configured, then I do not
get this kind of behaviour.
This is obviously wasting CPU cycles unnecessarily.
Why do we need to do this in the first place? (it essentially seems to
be the realpath c-library call that is triggering this in rrd_client.c
line).
Is there a way to avoid this unnecessary overhead as when updating 1000s
of files this adds up quickly to significant cost...
(Especially as it only seems to get enforced on the client)
Thanks,
Martin
P.s: just using relative paths with sockets does (almost) the same thing:
getcwd("/home/msperl/xymon-4.3.4"..., 4096) = 25
lstat("/home/msperl/xymon-4.3.4/testdata", {st_mode=S_IFDIR|0755,
st_size=4096, ...}) = 0
lstat("/home/msperl/xymon-4.3.4/testdata/servername",
{st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat("/home/msperl/xymon-4.3.4/testdata/servername/ifstat-lo",
{st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat("/home/msperl/xymon-4.3.4/testdata/servername/ifstat-lo/lo.rrd",
{st_mode=S_IFREG|0644, st_size=5755424, ...}) = 0
I only see the workaround as using tcp connections instead of unix sockets:
05:28:52.962651 read(3, "0 errors, enqueued 1 value(s).\n", 4096) = 31
05:28:52.962732 write(3, "update ./testdata/servername/ifstat-lo/lo.rrd
1312806435:5412637430:5334438:0:0:0:0:0:0:5412637430:5334438:0:0:0:0:0\n",
143) = 143
05:28:52.962798 read(3, "0 errors, enqueued 1 value(s).\n", 4096) = 31
Here my whole update cycle takes now 0.000147 seconds instead of the
0.000538 seconds, so it takes only 27% of the time for issuing the
update when I use the network sockets!
So maybe we want to improve here...
More information about the rrd-developers
mailing list