Merge branch 'mg/jitter'
authorFlorian Forster <octo@leeloo.lan.home.verplant.org>
Tue, 18 Aug 2009 19:39:03 +0000 (21:39 +0200)
committerFlorian Forster <octo@leeloo.lan.home.verplant.org>
Tue, 18 Aug 2009 19:39:03 +0000 (21:39 +0200)
src/collectd.conf.pod
src/rrdtool.c

index b31bb87..49a3b78 100644 (file)
@@ -2939,6 +2939,14 @@ updates per second, writing all values to disk will take approximately
 "collection3" you'll end up with a responsive and fast system, up to date
 graphs and basically a "backup" of your values every hour.
 
+=item B<RandomTimeout> I<Seconds>
+
+When set, the actual timeout for each value is chosen randomly between
+I<CacheTimeout>-I<RandomTimeout> and I<CacheTimeout>+I<RandomTimeout>. The
+intention is to avoid high load situations that appear when many values timeout
+at the same time. This is especially a problem shortly after the daemon starts,
+because all values were added to the internal cache at roughly the same time.
+
 =back
 
 =head2 Plugin C<sensors>
index c63f883..811aea0 100644 (file)
@@ -40,6 +40,7 @@ struct rrd_cache_s
        char **values;
        time_t first_value;
        time_t last_value;
+       int random_variation;
        enum
        {
                FLAG_NONE   = 0x00,
@@ -76,7 +77,8 @@ static const char *config_keys[] =
        "RRARows",
        "RRATimespan",
        "XFF",
-       "WritesPerSecond"
+       "WritesPerSecond",
+       "RandomTimeout"
 };
 static int config_keys_num = STATIC_ARRAY_SIZE (config_keys);
 
@@ -103,6 +105,7 @@ static rrdcreate_config_t rrdcreate_config =
  * ALWAYS lock `cache_lock' first! */
 static int         cache_timeout = 0;
 static int         cache_flush_timeout = 0;
+static int         random_timeout = 1;
 static time_t      cache_flush_last;
 static c_avl_tree_t *cache = NULL;
 static pthread_mutex_t cache_lock = PTHREAD_MUTEX_INITIALIZER;
@@ -739,7 +742,7 @@ static int rrd_cache_insert (const char *filename,
                        filename, rc->values_num,
                        (unsigned long)(rc->last_value - rc->first_value));
 
-       if ((rc->last_value - rc->first_value) >= cache_timeout)
+       if ((rc->last_value + rc->random_variation - rc->first_value) >= cache_timeout)
        {
                /* XXX: If you need to lock both, cache_lock and queue_lock, at
                 * the same time, ALWAYS lock `cache_lock' first! */
@@ -750,6 +753,18 @@ static int rrd_cache_insert (const char *filename,
                        status = rrd_queue_enqueue (filename, &queue_head, &queue_tail);
                        if (status == 0)
                                rc->flags = FLAG_QUEUED;
+
+                       /* Update the jitter value. Negative values are
+                        * slightly preferred. */
+                       if (random_timeout > 0)
+                       {
+                               rc->random_variation = (rand () % (2 * random_timeout))
+                                       - random_timeout;
+                       }
+                       else
+                       {
+                               rc->random_variation = 0;
+                       }
                }
                else
                {
@@ -988,6 +1003,23 @@ static int rrd_config (const char *key, const char *value)
                        write_rate = 1.0 / wps;
                }
        }
+       else if (strcasecmp ("RandomTimeout", key) == 0)
+        {
+               int tmp;
+
+               tmp = atoi (value);
+               if (tmp < 0)
+               {
+                       fprintf (stderr, "rrdtool: `RandomTimeout' must "
+                                       "be greater than or equal to zero.\n");
+                       ERROR ("rrdtool: `RandomTimeout' must "
+                                       "be greater then or equal to zero.");
+               }
+               else
+               {
+                       random_timeout = tmp;
+               }
+       }
        else
        {
                return (-1);