Redis Source Analysis (31)---Latency delay analysis and processing

Source: Internet
Author: User
Tags current time redis

When it comes to delaying statistics, one of the nouns that must be thought of is "performance testing," Yes, in Redis's Redis_benchmark file, it does use the information in the deferred file. The official interpretation of this document in Redis:

/* The latency monitor allows to easily observe the sources of latency
 * In a Redis the using the instance command . Different Latency
 * sources are monitored, like disk I/O, execution of commands, fork
 * system call, and so forth.
 *
 * Latency listener can listen to many simple resources in Redis, such as I/O disk operation, execute some instructions,
 * Fork to create the child thread operation and so on listening.
 * ----------------------------------------------------------------------------

In Redis, the whole process is simple, and he maintains a list of statistics for each event, each containing a collection of samples, each containing the creation time of the sample and the delay time of the sample. event== "Sampleserieslist is a dictionary mapping relationship. Here's a look at the key collection point, called the Latencysample acquisition point structure definition:

/* Representation of a latency sample:the sampling time and the latency * observed in milliseconds.////
Delay sample * *
struct Latencysample {
	//Delay Sample creation time
    int32_t/* We don ' t use time_t to force 4 bytes Usage everywhe Re. * *
    //delay time, in milliseconds
    uint32_t latency/* latency in milliseconds. */
};
The dictionary does not maintain a sample node, but rather a node list structure:

/* The Latency Time series for a given event.
    Next, sample to store. //
    Maximum delay uint32_t max//MAX
    Latency observed for this event. *//
    Recent delay record
    struct Latencysample SA Mples[latency_ts_len]; /* Latest history. */
};
In the design of Redis code, because the delay is used to test and analyze the result, the author also designed the data statistic structure used in the later analysis report.

/* Latency statistics structure.
    observed since latest reset. *
    //////Average sample delay time
    uint32_t avg;           /* Average of current samples. * *
    //sample Minimum delay time
    uint32_t min;           /* Min of current samples. * *
    //sample Maximum delay time
    uint32_t Max;           /* Max of current samples.           /* Mean Absolute deviation. * *
    The total number of//samples
    uint32_t samples;       /* Number of non-zero samples.          /* Number of seconds since and now. */
};
The meaning is very direct, then a simple sample how to carry out the detection of the event.

/* Start monitoring an event. We just set the current time.
/* To set up a listener for an event, set the current time *
/#define LATENCYSTARTMONITOR (Var) if (server.latency_monitor_threshold) {\
    var = mstime (); \
} else {\
    var = 0; \
}/* End Monitoring ' An

event, compute the ' difference ' with the ' current ' to
 check The amount of time elapsed. /
//* End of the monitoring, calculate how much time
/#define Latencyendmonitor (Var) if (server.latency_monitor_threshold) {\
    var = Mstime ()-Var; \
}

Very simple, record start time, record end time, the middle difference is the delay time, if beyond the given time range, added to the delay list:

/* ADD The sample only if the elapsed time is >= to the configured threshold. * *
If the delay time exceeds server.latency_monitor_threshold, then add sample to the delay list
/* * #define LATENCYADDSAMPLEIFNEEDED (event, var) \
    if (server.latency_monitor_threshold &&
        (Var) >= server.latency_monitor_threshold) \
          Latencyaddsample ((event), (Var));
We focus on, latencyaddsample, is to add the sampling node to the record, the steps are as follows:

1. According to the incoming event event, in Server.latency_events find the Val with key event events, that is, a latencytimeseries

2. Add a new sample in this latencytimeseries struct latencysample Samples[latency_ts_len]

The implementation code is as follows:

/* ADD The specified sample to the specified time series "event". * This function is usually called via latencyaddsampleifneeded (), which is a macro that only adds the sample if the late Ncy is higher than * server.latency_monitor_threshold.
    * * * Add sample to the specified Event object's sample list/void Latencyaddsample (char *event, mstime_t latency) {//Find the event corresponding to the delay sample record structure
    struct Latencytimeseries *ts = Dictfetchvalue (server.latency_events,event);
    time_t now = time (NULL);

    int prev; /* Create The time series if it is does not exist.
        */if (ts = = NULL) {ts = zmalloc (sizeof (*ts));
        Ts->idx = 0;
        Ts->max = 0;
        memset (ts->samples,0,sizeof (ts->samples));
    If TS is empty, re-add, an event, corresponding to a latencytimeseries Dictadd (Server.latency_events,zstrdup (event), TS);  }/* If the previous sample is in the same second, we update our old sample * If This latency was > of the old One, or just return. * * prev = (Ts->idx + Latency_ts_len-1)% Latency_ts_len; if (Ts->samples[prev].time = Now) {if (Latency > Ts->samples[prev].latency) ts->samples[
        Prev].latency = latency;
    Return
    ///For sample Assignment Ts->samples[ts->idx].time = time (NULL);
    Ts->samples[ts->idx].latency = latency;

    if (Latency > Ts->max) Ts->max = latency;
    ts->idx++;
if (Ts->idx = = latency_ts_len) ts->idx = 0;
 }
After the node is out, of course, the structure of the analysis of statistics, then used the latencystats structure;

/* 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. * * * Analysis of a time event delay results, the results of the information stored in the LATENCYSTATS structure of the * * * analyzelatencyforevent (char *event, struct latencystats *ls) {s
    Truct latencytimeseries *ts = Dictfetchvalue (server.latency_events,event);
    Int J;
	
	uint64_t sum; Initialization delay statistic result structure variable Ls->all_time_high = ts?
    ts->max:0;
    Ls->avg = 0;
    ls->min = 0;
    Ls->max = 0;
    Ls->mad = 0;
    ls->samples = 0;
    Ls->period = 0;

    if (!ts) return; /* The 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 {//Find the delay maximum and minimum delay time 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; /* Track The oldest event time in Ls->period.
    T;period = ts->samples[j].time; }/* So far avg is actually the sum of the latencies, and period are * the oldest event time. We need to make the second a range of seconds.
        */if (ls->samples) {ls->avg = sum/ls->samples;
        Ls->period = Time (NULL)-ls->period;
    if (Ls->period = = 0) Ls->period = 1; }/* Second pass, COMPUTE MAD. *////calculation average relative error, and flatAverage delay compared to sum = 0;

        for (j = 0; J < Latency_ts_len; J + +) {int64_t delta;
        if (Ts->samples[j].time = = 0) continue;
        Delta = (int64_t) ls->avg-ts->samples[j].latency;
        if (Delta < 0) Delta =-delta;
    sum = Delta;
} if (ls->samples) Ls->mad = sum/ls->samples;
 }
Of course, you can also use these collected points, draw a micro-line map, more image display:

#define LATENCY_GRAPH_COLS 80/* Using the delay of the sample point, draw the corresponding micro-line map * * SDS latencycommandgensparkeline (char *event, struct
    Latencytimeseries *ts) {int J;
    struct sequence *seq = Createsparklinesequence ();
    SDS graph = Sdsempty ();

    uint32_t min = 0, max = 0;
        for (j = 0; J < Latency_ts_len; J +) {int i = (ts->idx + j)% Latency_ts_len;
        int elapsed;
        Char *label;

        Char buf[64];
        if (Ts->samples[i].time = = 0) continue; /* Update min and Max.
        */if (seq->length = 0) {min = max = ts->samples[i].latency;
            else {if (Ts->samples[i].latency > Max) max = ts->samples[i].latency;
        if (ts->samples[i].latency < min) min = ts->samples[i].latency; }/* Use as label the number of Seconds/minutes/hours/days * ago the event happened.
        */elapsed = time (NULL)-ts->samples[i].time; if (Elapsed <) SnpriNTF (Buf,sizeof (BUF), "%ds", elapsed);
        else if (elapsed < 3600) snprintf (buf,sizeof (BUF), "%DM", ELAPSED/60);
        else if (elapsed < 3600*24) snprintf (buf,sizeof (BUF), "%dh", elapsed/3600);
        else snprintf (buf,sizeof (BUF), "%dd", elapsed/(3600*24));
        Label = Zstrdup (BUF);
    Sparklinesequenceaddsample (Seq,ts->samples[i].latency,label); Graph = sdscatprintf (graph, "%s-high%lu ms, low%lu ms) \ n", event, (%lu
    Ed long) Max, (unsigned long) min, (unsigned long) ts->max);
    for (j = 0; J < Latency_graph_cols; j +) Graph = Sdscatlen (graph, "-", 1);
    Graph = Sdscatlen (graph, "\ n", 1);
    Call the Sparkline function to draw the micro-line Graph graph = sparklinerender (Graph,seq,latency_graph_cols,4,sparkline_fill);
    Freesparklinesequence (seq);
Returns a micro-line graph string return graph;
 }
The Redis also encapsulates commands for external invocation, which is not parsed, that is, a composite call to the above method:

/*----------------------------Latency API---------------------------------*
/void Latencymonitorinit (void)/* Latency listener initialization, creating an event Dictionary object
/void Latencyaddsample (char *event, mstime_t latency)/* Add sample to the named Event object's sample list */< C2/>int latencyresetevent (char *event_to_reset)/* Resets the delay of event events, deletes the record of event in the dictionary
/void Analyzelatencyforevent ( Char *event, struct latencystats *ls)/* Analyzes the delay result of an event, and the result information is deposited in the LATENCYSTATS structure
/SDS createlatencyreport (void)/ * According to the results of the delay sample, create a better reading analysis report * * * *
latencycommandreplywithsamples (redisclient *c, struct latencytimeseries *ts )
void latencycommandreplywithlatestevents (redisclient *c)
SDS latencycommandgensparkeline (Char *event, struct latencytimeseries *ts)
void Latencycommand (Redisclient *c)
The analysis of Redis delay class files is also over, analysis of such a long time Redis Redis code, feel that every piece of code will have his bright spot exists, analysis of 30 no down, or learned a lot of online learning not to learn, online more is the Redis mainstream thinking of learning, Like some small points, and only their own taste, they can truly experience.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.