summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2014-07-07 14:59:57 +0200
committerantirez <antirez@gmail.com>2014-07-07 15:00:01 +0200
commit19853db892aa10a8b00a561b7dc1d48f7176ee38 (patch)
treee844611d1f59c4429baa640766b301492a17c244
parentb2604dc58c69f357a66df54067eec33a4f262cc9 (diff)
downloadredis-19853db892aa10a8b00a561b7dc1d48f7176ee38.tar.gz
Latency: low level time series analysis implemented.
-rw-r--r--src/latency.c50
-rw-r--r--src/latency.h10
2 files changed, 60 insertions, 0 deletions
diff --git a/src/latency.c b/src/latency.c
index 14c4d39ff..185003c7d 100644
--- a/src/latency.c
+++ b/src/latency.c
@@ -122,6 +122,56 @@ int latencyResetEvent(char *event_to_reset) {
return resets;
}
+/* ------------------------ Latency reporting (doctor) ---------------------- */
+
+/* Analyze the samples avaialble for a given event and return a structure
+ * populate with different metrics, average, MAD, min, max, and so forth.
+ * Check latency.h definition of struct latenctStat for more info.
+ * If the specified event has no elements the structure is populate with
+ * zero values. */
+void analyzeLatencyForEvent(char *event, struct latencyStats *ls) {
+ struct latencyTimeSeries *ts = dictFetchValue(server.latency_events,event);
+ int j;
+ uint64_t sum;
+
+ ls->all_time_high = ts ? ts->max : 0;
+ ls->avg = 0;
+ ls->min = 0;
+ ls->max = 0;
+ ls->mad = 0;
+ ls->samples = 0;
+ if (!ts) return;
+
+ /* First pass, populate everything but the MAD. */
+ sum = 0;
+ for (j = 0; j < LATENCY_TS_LEN; j++) {
+ if (ts->samples[j].time == 0) continue;
+ ls->samples++;
+ if (ls->samples == 1) {
+ ls->min = ls->max = ts->samples[j].latency;
+ } else {
+ if (ls->min > ts->samples[j].latency)
+ ls->min = ts->samples[j].latency;
+ if (ls->max < ts->samples[j].latency)
+ ls->max = ts->samples[j].latency;
+ }
+ sum += ts->samples[j].latency;
+ }
+ if (ls->samples) ls->avg = sum / ls->samples;
+
+ /* Second pass, compute MAD. */
+ sum = 0;
+ for (j = 0; j < LATENCY_TS_LEN; j++) {
+ int64_t delta;
+
+ if (ts->samples[j].time == 0) continue;
+ delta = ls->avg - ts->samples[j].latency;
+ if (delta < 0) delta = -delta;
+ sum += delta;
+ }
+ if (ls->samples) ls->mad = sum / ls->samples;
+}
+
/* ---------------------- Latency command implementation -------------------- */
/* latencyCommand() helper to produce a time-delay reply for all the samples
diff --git a/src/latency.h b/src/latency.h
index 1d21d5182..f28fce375 100644
--- a/src/latency.h
+++ b/src/latency.h
@@ -50,6 +50,16 @@ struct latencyTimeSeries {
struct latencySample samples[LATENCY_TS_LEN]; /* Latest history. */
};
+/* Latency statistics structure. */
+struct latencyStats {
+ uint32_t all_time_high; /* Absolute max observed since latest reset. */
+ uint32_t avg; /* Average of current samples. */
+ uint32_t min; /* Min of current samples. */
+ uint32_t max; /* Max of current samples. */
+ uint32_t mad; /* Mean absolute deviation. */
+ uint32_t samples; /* Number of non-zero samples. */
+};
+
void latencyMonitorInit(void);
void latencyAddSample(char *event, mstime_t latency);