<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">

<head>
<meta http-equiv=Content-Type content="text/html; charset=us-ascii">
<meta name=Generator content="Microsoft Word 12 (filtered medium)">
<!--[if !mso]>
<style>
v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style>
<![endif]-->
<style>
<!--
 /* Font Definitions */
 @font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Tahoma;
        panose-1:2 11 6 4 3 5 4 4 2 4;}
@font-face
        {font-family:Verdana;
        panose-1:2 11 6 4 3 5 4 4 2 4;}
@font-face
        {font-family:Webdings;
        panose-1:5 3 1 2 1 5 9 6 7 3;}
@font-face
        {font-family:"Arial Narrow";
        panose-1:2 11 6 6 2 2 2 3 2 4;}
 /* Style Definitions */
 p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman","serif";}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph
        {mso-style-priority:34;
        margin-top:0cm;
        margin-right:0cm;
        margin-bottom:0cm;
        margin-left:36.0pt;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman","serif";}
span.apple-style-span
        {mso-style-name:apple-style-span;}
span.EmailStyle18
        {mso-style-type:personal-reply;
        font-family:"Calibri","sans-serif";
        color:#1F497D;}
.MsoChpDefault
        {mso-style-type:export-only;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
        {page:WordSection1;}
 /* List Definitions */
 @list l0
        {mso-list-id:1615864592;
        mso-list-type:hybrid;
        mso-list-template-ids:323405498 336134161 336134169 336134171 336134159 336134169 336134171 336134159 336134169 336134171;}
@list l0:level1
        {mso-level-text:"%1\)";
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-18.0pt;}
ol
        {margin-bottom:0cm;}
ul
        {margin-bottom:0cm;}
-->
</style>
<!--[if gte mso 9]><xml>
 <o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
 <o:shapelayout v:ext="edit">
  <o:idmap v:ext="edit" data="1" />
 </o:shapelayout></xml><![endif]-->
</head>

<body lang=EN-NZ link=blue vlink=purple>

<div class=WordSection1>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'>The idea of an rrdcached that is able to copy updates on to a
second remote rrdcached opens up a whole load of exciting possibilities; most
obvious is the ability to set up a hot-standby DR host for your RRD databases,
and have a frontend that can switch between the two.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'>I&#8217;ve written this functionality into a copy of the code
here as a trial/proof of concept, and I have it up and running on two machines,
forwarding updates received from MRTG via a unix socket on one machine on via
tcp to a second.&nbsp; The way I did it was to <o:p></o:p></span></p>

<p class=MsoListParagraph style='text-indent:-18.0pt;mso-list:l0 level1 lfo1'><![if !supportLists]><span
style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><span
style='mso-list:Ignore'>1)<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'>Add an option to rrdcached, -C &lt;address&gt;, to specify where
the chained rrdcached is located.<o:p></o:p></span></p>

<p class=MsoListParagraph style='text-indent:-18.0pt;mso-list:l0 level1 lfo1'><![if !supportLists]><span
style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><span
style='mso-list:Ignore'>2)<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'>Add some code at the end of handle_request_update() to call
rrdc_update with the list of updates we&#8217;ve just processed.&nbsp; This
needs a little extra code to massage the file parameter, which has to be either
relative or absolute depending on whether the ongoing socket is TCP or unix
domain.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'>This means that updates are put into the remote queue at the
same time as being put into the local queue, rather than the local queue
feeding into the remote queue.&nbsp; I felt this was better because (a) it
means there is less latency between update and remote write, and (b) it is much
simpler to implement.&nbsp; The drawback of course is that if the remote daemon
is unavailable you can lose data as it is not buffered, but that would be the
case if you were talking to it directly.&nbsp; In this case, I log an error to
the syslog which can be handled elsewhere.&nbsp; If the local update succeeds,
but the remote fails, then (since rrdcached does not have a warn status) I am
returning an OK (since the local update is OK) but again logging an error to
syslog.&nbsp; This is not ideal but I felt it better than returning a fail &#8211;
if your remote server is down you don&#8217;t want local requests to appear to fail
as well.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'>I suppose I should note that, in this case, if you start daemon
A chaining to B, and start B chaining to A, and then submit an update, it loops
constantly.&nbsp; Fun and excitement ensues.&nbsp; But noone would do this and
expect it to work, now, would they&#8230;&nbsp; err, well, they might.&nbsp; It
might be worth adding some way for a daemon to detect if this is a forwarded
command, and decide if it should be forwarded again or not.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'>I&#8217;d expect a full implementation to relay not just <b>update</b>,
but also <b>create</b>, <b>forget</b>, <b>flush</b> and <b>flushall</b>.&nbsp; Stats
should also be recursively implemented; I&#8217;d envision something like the
values returned by the remote being prefixed with &#8216;Remote&#8217; and
added to the local output.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'>I wouldn&#8217;t expect the replication target to change under
normal circumstances, so setting it once on rrdcached startup and requiring a
restart to change it wouldn&#8217;t be a problem, as this would never happen
(you&#8217;d just set it up and leave it).<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'>Most if not all of the potential problems seem to be related to
placing the chain after the queue.&nbsp; If you place the chain before the
queue, and accept the potential (non-silent) data loss if the remote daemon is
unavailable, then things are far simpler.&nbsp; Also, if you decide that the
responsibility of the rrdcached is to relay commands only and not to be
responsible for ensuring full synchronisation of the RRD files, things are much
simpler.&nbsp; Since the nature of the RRD means that missing data will slowly evaporate
I think this is a fair decision to make.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'>I&#8217;ve not been making too much noise about this because I
want to get the rrdcached create/info/last patches solid first, plus the MRTG
patches I&#8217;ve been working on to take advantage of this functionality.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'>Steve<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'>--- code snippets: from rrd_daemon.c, end of
handle_request_update<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'>&nbsp;</span><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;if
(values_num &lt; 1) {<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;&nbsp;&nbsp;
return send_response(sock, RESP_ERR, &quot;No values updated.\n&quot;);<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;
} else if( copy_daemon ) {<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;&nbsp;&nbsp;
status = rrdc_connect(copy_daemon);<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;&nbsp;&nbsp;
status = rrdc_is_connected(copy_daemon);<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;&nbsp;&nbsp;
if(!status) {<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
RRDD_LOG (LOG_ERR, &quot;handle_request_update: could not connect to remote
rrdcached: %s&quot;,rrd_get_error());<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
rrd_clear_error();<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return send_response(sock, RESP_OK,<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&quot;Errors, enqueued %i value(s) but could not connect to remote
daemon.\n&quot;, values_num);<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;&nbsp;&nbsp;
}<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;&nbsp;&nbsp;
/* now, if we are doing chained updates unix-&gt;unix or tcp-&gt;tcp all will
be<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
OK as we're preserving the orig_file.&nbsp; However if we're doing<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
tcp-&gt;unix we need to use 'file' (IE with the path) and if we're doing<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
unix-&gt;tcp we need to REMOVE the default
path.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
*/<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;&nbsp;&nbsp;
if( ! strncmp( copy_daemon, &quot;unix:&quot;, 5 ) || (*copy_daemon == '/') ) {<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
/* going to a unix socket: 'file' is already expanded. */<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;&nbsp;&nbsp;
} else { /* going to a tcp: strip path if necessary */<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
file = orig_file;<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if( ! strncmp( file, config_base_dir, _config_base_dir_len ) ) {<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
file += _config_base_dir_len + 1; /* skip path and separator */<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
}<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;&nbsp;&nbsp;
}<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;&nbsp;&nbsp;
status = rrdc_update(file,values_num,(const char * const *) values_arr);<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;&nbsp;&nbsp;
if(status) {<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
RRDD_LOG (LOG_ERR, &quot;handle_request_update: could not perform remote
update: %s&quot;,rrd_get_error());<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
rrd_clear_error();<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;return send_response(sock, RESP_OK,<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&quot;Errors, enqueued %i value(s) but could not relay.\n&quot;, values_num);<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;&nbsp;&nbsp;
}<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;&nbsp;&nbsp;
return send_response(sock, RESP_OK,<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&quot;Update successful, enqueued and relayed %i value(s).\n&quot;, values_num);<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;
} else {<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;&nbsp;&nbsp;
return send_response(sock, RESP_OK,<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&quot;Update successful, enqueued %i value(s).\n&quot;, values_num);<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;
}<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'>--- from read_options<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;
while ((option = getopt(argc, argv, &quot;Ogl:s:m:P:f:w:z:t:Bb:p:Fj:a:h<span
style='background:yellow;mso-highlight:yellow'>C:</span>?&quot;)) != -1)<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;
{<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;&nbsp;&nbsp;
switch (option)<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;&nbsp;&nbsp;
{<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<span style='background:yellow;mso-highlight:yellow'>case 'C':<o:p></o:p></span></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";
background:yellow;mso-highlight:yellow'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
copy_daemon = strdup (optarg);<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";
background:yellow;mso-highlight:yellow'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
break;</span><span style='font-size:10.0pt;font-family:"Courier New"'><o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'><o:p>&nbsp;</o:p></span></p>

<div class=MsoNormal align=center style='text-align:center'><span lang=EN-US
style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>

<hr size=2 width="100%" align=center>

</span></div>

<p class=MsoNormal><b><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'>Steve Shipway<o:p></o:p></span></b></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'>ITS Unix Services Design Lead<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'>University of Auckland, New Zealand<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'>Floor 1, 58 Symonds Street, Auckland<o:p></o:p></span></p>

<p class=MsoNormal><i><span style='font-size:10.0pt;font-family:"Calibri","sans-serif";
color:#595959'>Phone: +64 (0)9 3737599 ext 86487<o:p></o:p></span></i></p>

<p class=MsoNormal><i><span style='font-size:10.0pt;font-family:"Calibri","sans-serif";
color:#595959'>DDI: +64 (0)9 924 6487<o:p></o:p></span></i></p>

<p class=MsoNormal><i><span style='font-size:10.0pt;font-family:"Calibri","sans-serif";
color:#595959'>Mobile: +64 (0)21 753 189<o:p></o:p></span></i></p>

<p class=MsoNormal><i><span style='font-size:10.0pt;font-family:"Calibri","sans-serif";
color:#595959'>Email: <a href="mailto:s.shipway@auckland.ac.nz"><span
style='color:#595959'>s.shipway@auckland.ac.nz</span></a><o:p></o:p></span></i></p>

<p class=MsoNormal><span lang=EN-GB style='font-size:18.0pt;font-family:Webdings;
color:green'>P</span><span lang=EN-GB style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:blue'> </span><span lang=EN-GB style='font-size:10.0pt;font-family:"Arial Narrow","sans-serif";
color:green'>Please consider the environment before printing this e-mail</span><span
lang=EN-GB style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:blue'> </span><span lang=EN-GB style='font-size:7.5pt;font-family:"Verdana","sans-serif";
color:navy'><o:p></o:p></span></p>

<p class=MsoNormal><i><span style='font-size:10.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'><o:p>&nbsp;</o:p></span></i></p>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'><o:p>&nbsp;</o:p></span></p>

<div style='border:none;border-left:solid blue 1.5pt;padding:0cm 0cm 0cm 4.0pt'>

<div>

<div style='border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0cm 0cm 0cm'>

<p class=MsoNormal><b><span lang=EN-US style='font-size:10.0pt;font-family:
"Tahoma","sans-serif"'>From:</span></b><span lang=EN-US style='font-size:10.0pt;
font-family:"Tahoma","sans-serif"'> kevin brintnall [mailto:kbrint@rufus.net] <br>
<b>Sent:</b> Wednesday, 29 September 2010 2:11 a.m.<br>
<b>To:</b> Steve Shipway<br>
<b>Cc:</b> rrd-developers@lists.oetiker.ch<br>
<b>Subject:</b> Re: [FORGED] r2130 comments : rrd_parsetime,
create_set_no_overwrite<o:p></o:p></span></p>

</div>

</div>

<p class=MsoNormal><o:p>&nbsp;</o:p></p>

<div>

<p class=MsoNormal>Steve, I'm bringing this back to rrd-developers since there
are a lot of possibilities here...<o:p></o:p></p>

</div>

<div>

<p class=MsoNormal><o:p>&nbsp;</o:p></p>

<div>

<blockquote style='border:none;border-left:solid #CCCCCC 1.0pt;padding:0cm 0cm 0cm 6.0pt;
margin-left:4.8pt;margin-right:0cm'>

<div>

<div>

<p class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto'><span
class=apple-style-span><span style='font-size:11.5pt;color:#1F497D'>I&#8217;m
also working on another option for rrdcached, -C &lt;address&gt;, to chain
update requests on to a second rrdcached, allowing you to run a hot DR server
with constantly updated RRD files.&nbsp; Will probably have to chain on create,
info and stats as well ...</span></span><o:p></o:p></p>

</div>

</div>

</blockquote>

<div>

<p class=MsoNormal><o:p>&nbsp;</o:p></p>

</div>

<div>

<p class=MsoNormal>I've given some thought to this too... &nbsp;There are a
couple problems that I can see:<o:p></o:p></p>

</div>

<div>

<p class=MsoNormal><o:p>&nbsp;</o:p></p>

</div>

<div>

<p class=MsoNormal>(1) it's currently not possible to change much for
rrdcached's running configuration. &nbsp;So, if the replication target ever
changes, we want to avoid a shutdown/start-up sequence. &nbsp;(On my machine,
this can take up to 15 minutes due to extensive journal replay -- which is
another issue altogether).<o:p></o:p></p>

</div>

<div>

<p class=MsoNormal><o:p>&nbsp;</o:p></p>

</div>

<div>

<p class=MsoNormal>(2) A remote daemon that falls behind may cause the number
of values queued to grow without bound. &nbsp;Currently the daemon discards the
cached values as soon as it enqueues the file on the write queue.<o:p></o:p></p>

</div>

<div>

<p class=MsoNormal><o:p>&nbsp;</o:p></p>

</div>

<div>

<p class=MsoNormal>(3) If the remote daemon is unreachable for 2 * (flush
timer) , then all the journal entries required to re-create the state will have
been expired. &nbsp;On some systems, keeping the journals around will not be a
burden. &nbsp;On others, it will (especially if they contribute to the start-up
replay time).<o:p></o:p></p>

</div>

<div>

<p class=MsoNormal><o:p>&nbsp;</o:p></p>

</div>

<div>

<p class=MsoNormal>(4) If we do not maintain infinite journals for (3), then we
are forced to use a different synchronization technique after we've passed
2*(flush timer). &nbsp;This probably includes export/import or scp of the RRD
files.<o:p></o:p></p>

</div>

<div>

<p class=MsoNormal><o:p>&nbsp;</o:p></p>

</div>

<div>

<p class=MsoNormal>To this end, I've been considering a second process that
will &quot;tail&quot; the journal files and repeat the flow back to another
journal. &nbsp;Then, this process could be stopped/started independently,
reconfigured as necessary, etc. &nbsp;It could store a minimal amount of state
(rrd journal file name, seek position) and be restarted easily.<o:p></o:p></p>

</div>

<div>

<p class=MsoNormal><o:p>&nbsp;</o:p></p>

</div>

<div>

<p class=MsoNormal>Optionally, rrdcached could fork()/exec() such a process
each time a journal file was close()'d. &nbsp;This would delay the replay up to
(flush timer) seconds or 1GB of journal write, whichever is less. &nbsp;Also,
it would concentrate (in time) the processing load on the remote machine.<o:p></o:p></p>

</div>

<div>

<p class=MsoNormal><o:p>&nbsp;</o:p></p>

</div>

<div>

<p class=MsoNormal>With regards to what needs replication, I think it would be
sufficient to replicate these: create, update, forget.<o:p></o:p></p>

</div>

<div>

<p class=MsoNormal><o:p>&nbsp;</o:p></p>

</div>

<div>

<p class=MsoNormal>Open to suggestion...<o:p></o:p></p>

</div>

<div>

<p class=MsoNormal><o:p>&nbsp;</o:p></p>

</div>

<div>

<p class=MsoNormal>--&nbsp;<o:p></o:p></p>

</div>

</div>

<p class=MsoNormal style='margin-bottom:12.0pt'>&nbsp;kevin brintnall =~ /<a
href="http://kbrint@rufus.net/">kbrint@rufus.net/</a><o:p></o:p></p>

</div>

</div>

</div>

</body>

</html>