This test tries to cater for this. It works like this:
-1) Create 100 RRD files (and sync them to disk)
+1) Create 20k RRD files (and sync them to disk)
-2) Update the 100 RRD file three times in a row.
+2) Update the RRD files several times in a row.
We run the Update several times to see the difference
it makes in the cache.
-3) Go back to 1)
-
NOTE
use strict;
}
main;
+use strict;
+use Time::HiRes qw(time);
+use RRDs;
+use IO::File;
+use Time::HiRes qw( usleep );
+
+sub create($$){
+ my $file = shift;
+ my $time = shift;
+ my $start = time; #since we loaded HiRes
+ RRDs::create ( $file.".rrd", "-b$time", qw(
+ -s300
+ DS:in:GAUGE:400:U:U
+ DS:out:GAUGE:400:U:U
+ RRA:AVERAGE:0.5:1:600
+ RRA:AVERAGE:0.5:6:600
+ RRA:MAX:0.5:6:600
+ RRA:AVERAGE:0.5:24:600
+ RRA:MAX:0.5:24:600
+ RRA:AVERAGE:0.5:144:600
+ RRA:MAX:0.5:144:600
+ ));
+ my $total = time - $start;
+ my $error = RRDs::error;
+ die $error if $error;
+ return $total;
+}
+
+sub update($$){
+ my $file = shift;
+ my $time = shift;
+ my $in = rand(1000);
+ my $out = rand(1000);
+ my $start = time;
+ my $ret = RRDs::updatev($file.".rrd", $time.":$in:$out");
+# print join("",map {" $_ " . $ret->{$_}."\n" } grep /AVERAGE.\[1\]/, sort keys %$ret)."\n** $time\n\n";
+ # sync updates to disk immediately
+# usleep(1) if (rand(3) <1 );
+ my $total = time - $start;
+ my $error = RRDs::error;
+ die $error if $error;
+ return $total;
+}
+
+sub tune($){
+ my $file = shift;
+ my $start = time;
+ RRDs::tune ($file.".rrd", "-a","in:U","-a","out:U","-d","in:GAUGE","-d","out:GAUGE");
+ my $total = time - $start;
+ my $error = RRDs::error;
+ die $error if $error;
+ return $total;
+}
+
+sub infofetch($){
+ my $file = shift;
+ my $start = time;
+ my $info = RRDs::info ($file.".rrd");
+ my $error = RRDs::error;
+ die $error if $error;
+ my $lasttime = $info->{last_update} - $info->{last_update} % $info->{step};
+ my $fetch = RRDs::fetch ($file.".rrd",'AVERAGE','-s',$lasttime-1,'-e',$lasttime);
+ my $total = time - $start;
+ my $error = RRDs::error;
+ die $error if $error;
+ return $total;
+}
+
+sub stddev ($$$){ #http://en.wikipedia.org/wiki/Standard_deviation
+ my $sum = shift;
+ my $squaresum = shift;
+ my $count = shift;
+ return sqrt( 1 / $count * ( $squaresum - $sum*$sum / $count ))
+}
+
+sub makerrds($$$$){
+ my $count = shift;
+ my $total = shift;
+ my $list = shift;
+ my $time = shift;
+ my @files;
+ for (1..$count){
+ my $id = sprintf ("%07d",$total);
+ $id =~ s/^(.)(.)(.)(.)(.)//;
+ push @$list, "$1/$2/$3/$4/$5/$id";
+ -d "$1" or mkdir "$1";
+ -d "$1/$2" or mkdir "$1/$2";
+ -d "$1/$2/$3" or mkdir "$1/$2/$3";
+ -d "$1/$2/$3/$4" or mkdir "$1/$2/$3/$4";
+ -d "$1/$2/$3/$4/$5" or mkdir "$1/$2/$3/$4/$5";
+ push @files, $list->[$total];
+ create $list->[$total++],$time-2;
+ print STDERR ".";
+ }
+ for (@files){
+ my $fd = new IO::File("$_.rrd","r");
+ if (defined $fd) {
+ $fd->sync;
+ $fd->close;
+ } else {
+ warn "failed to sync $_\n";
+ }
+ }
+ return $count;
+}
+
+
+sub main (){
+ mkdir "db-$$" or die $!;
+ chdir "db-$$";
+
+ my $step = 200000; # number of rrds to creat for every round
+
+ my @path;
+ my $time=int(time);
+
+ my $tracksize = 0;
+ my $uppntr = 0;
+
+
+ my %squaresum = ( cr => 0, up => 0 );
+ my %sum = ( cr => 0, up => 0 );
+ my %count =( cr => 0, up => 0 );
+
+ my $printtime = time;
+ while (1) {
+ # enhance the track
+ $time += 300;
+ $tracksize += makerrds $step,$tracksize,\@path,$time;
+ # run benchmark
+ for (0..10){
+ $time += 300;
+ my $count = 0;
+ my $sum = 0;
+ my $squaresum = 0;
+ for (my $i = 0; $i<$tracksize;$i ++){
+ my $elapsed = update($path[$i],$time);
+ $sum += $elapsed;
+ $squaresum += $elapsed**2;
+ $count++;
+ };
+# for (my $i = 0; $i<$tracksize;$i ++){
+# my $fh = new IO::File "$path[$i].rrd","r";
+# if (defined $fh) {
+# $fh->sync;
+# $fh->close;
+# } else {
+# warn "failed to sync $path[$i]\n";
+# }
+# }
+ my $ups = $count/$sum;
+ my $sdv = stddev($sum,$squaresum,$count);
+ printf STDERR "%4d %6.0f Up/s (%6.5f sdv)\n",$count,$ups,$sdv;
+ }
+ print STDERR "\n";
+ exit ;
+ }
+}
+
+main;