<html>
  <head>

    <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    I have written a cache service that periodically flushes collected
    stats to their respective files. I have an RPC thread that receives
    stats from other services. This thread maps the stats (and template)
    to the respective RRD file. Periodically, 6 worker threads are
    launched to flush the mapped stats to their RRD files. Simple
    enough.<br>
    <br>
    I am using rrdlib version 1.4.8 and below is how I am calling
    rrd_update_r()<br>
    <br>
    <title>Snippet</title>
    <pre style="font-family:Consolas;font-size:13;color:black;background:white;"><span style="color:blue;">struct</span>&nbsp;RRDCache
{
    std::string&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmplt_;
    std::list&lt;std::string&gt;&nbsp;values_;
};

<span style="color:blue;">bool</span>&nbsp;vRRDSrv::_Flush(<span style="color:blue;">const</span>&nbsp;std::string&amp;&nbsp;path,&nbsp;RRDCache&amp;&nbsp;cache)
{
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">if</span>(cache.values_.empty())&nbsp;<span style="color:blue;">return</span>&nbsp;<span style="color:blue;">true</span>;
 
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">unsigned</span>&nbsp;<span style="color:blue;">long</span>&nbsp;start&nbsp;=&nbsp;vTime::UTCTime();
&nbsp;&nbsp;&nbsp;&nbsp;pGDbgLog(LogExInf,<span style="color:#a31515;">"WRITING&nbsp;%u&nbsp;POINTS&nbsp;TO&nbsp;%s"</span>,cache.values_.size(),path.c_str());
 
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">int</span>&nbsp;err,&nbsp;argc&nbsp;=&nbsp;0;
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">const</span>&nbsp;<span style="color:blue;">char</span>**&nbsp;argv&nbsp;=&nbsp;(<span style="color:blue;">const</span>&nbsp;<span style="color:blue;">char</span>**)_alloca(cache.values_.size()&nbsp;*&nbsp;<span style="color:blue;">sizeof</span>(<span style="color:blue;">const</span>&nbsp;<span style="color:blue;">char</span>*));
&nbsp;&nbsp;&nbsp;&nbsp;std::list&lt;std::string&gt;::const_iterator&nbsp;dv_i;
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">for</span>(dv_i=cache.values_.begin();dv_i!=cache.values_.end();dv_i++)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;argv[argc++]&nbsp;=&nbsp;(*dv_i).c_str();
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">if</span>((err=rrd_update_r(path.c_str(),cache.tmplt_.c_str(),argc,argv))&nbsp;!=&nbsp;0)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pGDbgLog(LogExWarn,<span style="color:#a31515;">"RRD&nbsp;UPDATE&nbsp;ERROR&nbsp;(%d:%s)&nbsp;ON&nbsp;%s"</span>,err,rrd_get_error(),path.c_str());
 
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">unsigned</span>&nbsp;<span style="color:blue;">long</span>&nbsp;stop&nbsp;=&nbsp;vTime::UTCTime()&nbsp;-&nbsp;start;
&nbsp;&nbsp;&nbsp;&nbsp;pGDbgLog(LogExInf,<span style="color:#a31515;">"TOOK&nbsp;%u&nbsp;SECONDS&nbsp;TO&nbsp;WRITE&nbsp;%u&nbsp;POINTS&nbsp;TO&nbsp;%s&nbsp;"</span>,stop,cache.values_.size(),path.c_str());
 
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue;">return</span>&nbsp;err&nbsp;==&nbsp;0;
}
</pre>
    <br>
    These are the values used to create the RRD.<br>
    <br>
    <blockquote>step: 300<br>
      DS:dups:GAUGE:600:0:4294967295<br>
      DS:pl:GAUGE:600:0:100<br>
      DS:rtt:GAUGE:600:0:10000000<br>
      DS:ttl:GAUGE:600:0:510<br>
      RRA:AVERAGE:0.5:1:2016<br>
      RRA:AVERAGE:0.5:6:1680<br>
      RRA:AVERAGE:0.5:24:4320<br>
      RRA:AVERAGE:0.5:144:2920<br>
    </blockquote>
    <br>
    Its taking anywhere from 210 to 320 seconds to write a single point
    to the RRD. This cannot be right, but I am at a loss on why. <br>
    <br>
    I also tried smaller RRAs.<br>
    <br>
    <blockquote>DS:dups:GAUGE:600:0:4294967295<br>
      DS:pl:GAUGE:600:0:100<br>
      DS:rtt:GAUGE:600:0:10000000<br>
      DS:ttl:GAUGE:600:0:510<br>
      RRA:AVERAGE:0.5:1:600<br>
      RRA:AVERAGE:0.5:6:700<br>
      RRA:AVERAGE:0.5:24:775<br>
      RRA:AVERAGE:0.5:288:797<br>
    </blockquote>
    <br>
    This made very little difference. The timing was basically the same.<br>
    <br>
    Other things I have tried are copying the RRD to ramdirve, doing the
    update on the copy, and then moving the modified file back in place.
    This was only marginally better.<br>
    <br>
    I am not sure what else to do other tinkering with the rrdlib source
    code itself. I am tempted to modify the rrdlib to load the file in
    memory, modify it, then write it back - just to see the timing on
    that.<br>
    <br>
    Any thoughts, suggestions would be greatly appreciated.<br>
    <br>
    Kevin<br>
  </body>
</html>