Delen via


Tijdreeksanalyse

Van toepassing op: ✅Microsoft FabricAzure Data ExplorerAzure MonitorMicrosoft Sentinel

Cloudservices en IoT-apparaten genereren telemetriegegevens die kunnen worden gebruikt om inzicht te krijgen in de servicestatus, fysieke productieprocessen en gebruikstrends. Het uitvoeren van een tijdreeksanalyse is een manier om afwijkingen in het patroon van deze metrische gegevens te identificeren in vergelijking met hun typische basislijnpatroon.

Kusto Query Language (KQL) bevat systeemeigen ondersteuning voor het maken, bewerken en analyseren van meerdere tijdreeksen. In dit artikel leert u hoe KQL wordt gebruikt voor het maken en analyseren van duizenden tijdreeksen in seconden, waardoor bijna realtime bewakingsoplossingen en werkstromen mogelijk zijn.

Tijdreeks maken

In deze sectie maken we een grote reeks reguliere tijdreeksen, eenvoudig en intuïtief met behulp van de make-series operator, en vullen we ontbrekende waarden indien nodig in. De eerste stap in de tijdreeksanalyse is het partitioneren en transformeren van de oorspronkelijke telemetrietabel naar een reeks tijdreeksen. De tabel bevat meestal een tijdstempelkolom, contextuele dimensies en optionele metrische gegevens. De dimensies worden gebruikt om de gegevens te partitioneren. Het doel is om met regelmatige tijdsintervallen duizenden tijdreeksen per partitie te maken.

De invoertabel demo_make_series1 bevat 600.000 records van willekeurig webserviceverkeer. Gebruik de volgende opdracht om tien records te samplen:

demo_make_series1 | take 10 

De resulterende tabel bevat een tijdstempelkolom, drie contextuele dimensiekolommen en geen metrische gegevens:

Tijdstempel BrowserVer OsVer Land/regio
2016-08-25 09:12:35.4020000 Chrome 51.0 Windows 7 Verenigd Koninkrijk
2016-08-25 09:12:41.1120000 Chrome 52.0 Windows 10
2016-08-25 09:12:46.2300000 Chrome 52.0 Windows 7 Verenigd Koninkrijk
2016-08-25 09:12:46.5100000 Chrome 52.0 Windows 10 Verenigd Koninkrijk
2016-08-25 09:12:46.5570000 Chrome 52.0 Windows 10 Republiek Litouwen
2016-08-25 09:12:47.0470000 Chrome 52.0 Windows 8.1 India
2016-08-25 09:12:51.3600000 Chrome 52.0 Windows 10 Verenigd Koninkrijk
2016-08-25 09:12:51.6930000 Chrome 52.0 Windows 7 Nederland
2016-08-25 09:12:56.4240000 Chrome 52.0 Windows 10 Verenigd Koninkrijk
2016-08-25 09:13:08.7230000 Chrome 52.0 Windows 10 India

Omdat er geen metrische gegevens zijn, kunnen we alleen een set tijdreeksen bouwen die het aantal verkeer zelf vertegenwoordigen, gepartitioneerd door het besturingssysteem met behulp van de volgende query:

let min_t = toscalar(demo_make_series1 | summarize min(TimeStamp));
let max_t = toscalar(demo_make_series1 | summarize max(TimeStamp));
demo_make_series1
| make-series num=count() default=0 on TimeStamp from min_t to max_t step 1h by OsVer
| render timechart 
  • Gebruik de make-series operator om een set van drie tijdreeksen te maken, waarbij:
    • num=count(): tijdreeks van verkeer
    • from min_t to max_t step 1h: tijdreeksen worden gemaakt in bins van 1 uur in het tijdsbereik (oudste en nieuwste tijdstempels van tabelrecords)
    • default=0: geef de opvulmethode op voor ontbrekende gegevensvakken om reguliere tijdreeksen te creëren. U kunt ook series_fill_const(), series_fill_forward(), series_fill_backward() en series_fill_linear() gebruiken voor wijzigingen
    • by OsVer: partitie per besturingssysteem
  • De werkelijke tijdreeksgegevensstructuur is een numerieke array van de geaggregeerde waarde voor elk tijdblok. We gebruiken render timechart voor visualisatie.

In de bovenstaande tabel hebben we drie partities. We kunnen een afzonderlijke tijdreeks maken: Windows 10 (rood), 7 (blauw) en 8.1 (groen) voor elke versie van het besturingssysteem, zoals te zien is in de grafiek:

Tijdreekspartitie.

Tijdreeksanalysefuncties

In deze sectie voeren we typische reeksverwerkingsfuncties uit. Zodra een reeks tijdreeksen is gemaakt, ondersteunt KQL een groeiende lijst met functies om ze te verwerken en te analyseren. We beschrijven enkele representatieve functies voor het verwerken en analyseren van tijdreeksen.

Filteren

Filteren is een gangbare praktijk in signaalverwerking en handig voor het verwerken van tijdreekstaken (bijvoorbeeld een ruissignaal, wijzigingsdetectie soepel laten verlopen).

  • Er zijn twee algemene filterfuncties:
    • series_fir(): FIR-filter toepassen. Wordt gebruikt voor eenvoudige berekening van zwevend gemiddelde en differentiatie van de tijdreeks voor wijzigingsdetectie.
    • series_iir(): IIR-filter toepassen. Wordt gebruikt voor exponentiële vereffening en cumulatieve som.
  • Extend de tijdreeks die is ingesteld door een nieuwe reeks met een voortschrijdend gemiddelde van 5 bins grootte aan de query toe te voegen (met de naam ma_num):
let min_t = toscalar(demo_make_series1 | summarize min(TimeStamp));
let max_t = toscalar(demo_make_series1 | summarize max(TimeStamp));
demo_make_series1
| make-series num=count() default=0 on TimeStamp from min_t to max_t step 1h by OsVer
| extend ma_num=series_fir(num, repeat(1, 5), true, true)
| render timechart

Tijdreeksfiltering.

Regressieanalyse

Een gesegmenteerde lineaire regressieanalyse kan worden gebruikt om de trend van de tijdreeks te schatten.

  • Gebruik series_fit_line() om de beste regel aan te passen aan een tijdreeks voor algemene trenddetectie.
  • Gebruik series_fit_2lines() om trendwijzigingen te detecteren, ten opzichte van de basislijn, die handig zijn in bewakingsscenario's.

Voorbeeld van series_fit_line() en series_fit_2lines() functies in een tijdreeksquery:

demo_series2
| extend series_fit_2lines(y), series_fit_line(y)
| render linechart with(xcolumn=x)

Regressie van tijdreeksen.

  • Blauw: oorspronkelijke tijdreeks
  • Groen: aangepaste lijn
  • Rood: twee aangebrachte lijnen

Opmerking

De functie heeft het sprongpunt (niveauwijziging) nauwkeurig gedetecteerd.

Detectie van seizoensgebondenheid

Veel metrische gegevens volgen seizoensgebonden (periodieke) patronen. Gebruikersverkeer van cloudservices bevat meestal dagelijkse en wekelijkse patronen die het hoogst zijn rond het midden van de werkdag en laagste 's nachts en in het weekend. IoT-sensoren meten in periodieke intervallen. Fysieke metingen zoals temperatuur, druk of vochtigheid kunnen ook seizoensgedrag vertonen.

In het volgende voorbeeld wordt seizoensgebondenheidsdetectie toegepast op verkeer van één maand van een webservice (2-uurs bins):

demo_series3
| render timechart 

Tijdreeks seizoensgebondenheid.

  • Gebruik series_periods_detect() om automatisch de perioden in de tijdreeks te detecteren, waarbij:
    • num: de tijdreeks die moet worden geanalyseerd
    • 0.: de minimale periodelengte in dagen (0 betekent geen minimum)
    • 14d/2h: de maximale periodelengte in dagen, waarbij 14 dagen zijn onderverdeeld in tijdvakken van 2 uur.
    • 2: het aantal perioden om te detecteren
  • Gebruik series_periods_validate() als we weten dat een metrische waarde specifieke afzonderlijke perioden moet hebben en we willen controleren of deze bestaan.

Opmerking

Het is een anomalie als er geen specifieke afzonderlijke perioden bestaan

demo_series3
| project (periods, scores) = series_periods_detect(num, 0., 14d/2h, 2) //to detect the periods in the time series
| mv-expand periods, scores
| extend days=2h*todouble(periods)/1d
Perioden Scores Dagen
84 0.820622786055595 7
12 0.764601405803502 1

De functie detecteert dagelijks en wekelijks seizoensgebondenheid. De dagelijkse scores minder dan de wekelijkse omdat weekenddagen verschillen van weekdagen.

Elementengewijze functies

Rekenkundige en logische bewerkingen kunnen worden uitgevoerd op een tijdreeks. Met behulp van series_subtract() kunnen we een resterende tijdreeks berekenen, dat wil gezegd het verschil tussen de oorspronkelijke onbewerkte metrische gegevens en een vloeiende waarde, en zoeken naar afwijkingen in het restsignaal:

let min_t = toscalar(demo_make_series1 | summarize min(TimeStamp));
let max_t = toscalar(demo_make_series1 | summarize max(TimeStamp));
demo_make_series1
| make-series num=count() default=0 on TimeStamp from min_t to max_t step 1h by OsVer
| extend ma_num=series_fir(num, repeat(1, 5), true, true)
| extend residual_num=series_subtract(num, ma_num) //to calculate residual time series
| where OsVer == "Windows 10"   // filter on Win 10 to visualize a cleaner chart 
| render timechart

Tijdreeksbewerkingen.

  • Blauw: oorspronkelijke tijdreeks
  • Rood: vloeiende tijdreeks
  • Groen: resttijdreeks

Tijdreekswerkstroom op schaal

In het onderstaande voorbeeld ziet u hoe deze functies op schaal kunnen worden uitgevoerd op duizenden tijdreeksen in seconden voor anomaliedetectie. Voer de volgende query uit om enkele voorbeeldtelemetrierecords te zien van de metrische gegevens voor het aantal leesbewerkingen van een DB-service gedurende vier dagen:

demo_many_series1
| take 4 
TIJDSTEMPEL Locatie Op DB DataRead
2016-09-11 21:00:00.0000000 Loc 9 5117853934049630089 262 0
2016-09-11 21:00:00.0000000 Loc 9 5117853934049630089 241 0
2016-09-11 21:00:00.0000000 Loc 9 -865998331941149874 262 279862
2016-09-11 21:00:00.0000000 Loc 9 371921734563783410 255 0

En eenvoudige statistieken:

demo_many_series1
| summarize num=count(), min_t=min(TIMESTAMP), max_t=max(TIMESTAMP) 
Num min_t max_t
2177472 2016-09-08 00:00:00.0000000 2016-09-11 23:00:00.0000000

Het opbouwen van een tijdreeks in 1-uurs bins van de leesmetriek, in totaal 96 punten voor vier dagen, resulteert in normale patroonschommelingen.

let min_t = toscalar(demo_many_series1 | summarize min(TIMESTAMP));  
let max_t = toscalar(demo_many_series1 | summarize max(TIMESTAMP));  
demo_many_series1
| make-series reads=avg(DataRead) on TIMESTAMP from min_t to max_t step 1h
| render timechart with(ymin=0) 

Tijdreeksen op schaal.

Het bovenstaande gedrag is misleidend, omdat de enkele normale tijdreeks wordt geaggregeerd uit duizenden verschillende exemplaren die abnormale patronen kunnen hebben. Daarom maken we een tijdreeks per exemplaar. Een exemplaar wordt gedefinieerd door Loc (locatie), Op (bewerking) en DB (specifieke computer).

Hoeveel tijdreeksen kunnen we maken?

demo_many_series1
| summarize by Loc, Op, DB
| count
Aantal
18339

Nu gaan we een set van 18339 tijdreeksen maken van de metrische waarde voor het lezenaantal. We voegen de by component toe aan de instructie make-series, passen lineaire regressie toe en selecteren de bovenste twee tijdreeksen met de belangrijkste dalende trend:

let min_t = toscalar(demo_many_series1 | summarize min(TIMESTAMP));  
let max_t = toscalar(demo_many_series1 | summarize max(TIMESTAMP));  
demo_many_series1
| make-series reads=avg(DataRead) on TIMESTAMP from min_t to max_t step 1h by Loc, Op, DB
| extend (rsquare, slope) = series_fit_line(reads)
| top 2 by slope asc 
| render timechart with(title='Service Traffic Outage for 2 instances (out of 18339)')

Top twee van tijdreeksen.

De exemplaren weergeven:

let min_t = toscalar(demo_many_series1 | summarize min(TIMESTAMP));  
let max_t = toscalar(demo_many_series1 | summarize max(TIMESTAMP));  
demo_many_series1
| make-series reads=avg(DataRead) on TIMESTAMP from min_t to max_t step 1h by Loc, Op, DB
| extend (rsquare, slope) = series_fit_line(reads)
| top 2 by slope asc
| project Loc, Op, DB, slope 
Locatie Op DB helling
Loc 15 37 1151 -102743.910227889
Loc 13 37 1249 -86303.2334644601

In minder dan twee minuten werden bijna 20.000 tijdreeksen geanalyseerd en werden twee abnormale tijdreeksen gedetecteerd waarin het aantal keren gelezen plotseling daalde.

Deze geavanceerde mogelijkheden in combinatie met snelle prestaties leveren een unieke en krachtige oplossing voor tijdreeksanalyse.