Analiza szeregów czasowych

Usługi w chmurze i urządzenia IoT generują dane telemetryczne, których można użyć do uzyskania szczegółowych informacji, takich jak monitorowanie kondycji usługi, fizycznych procesów produkcyjnych i trendów użycia. Przeprowadzanie analizy szeregów czasowych to jeden ze sposobów identyfikowania odchyleń we wzorcu tych metryk w porównaniu z typowym wzorcem punktu odniesienia.

język zapytań Kusto (KQL) zawiera natywną obsługę tworzenia, manipulowania i analizowania wielu szeregów czasowych. W tym artykule dowiesz się, jak język KQL jest używany do tworzenia i analizowania tysięcy szeregów czasowych w sekundach, umożliwiając rozwiązania do monitorowania niemal w czasie rzeczywistym i przepływy pracy.

Tworzenie szeregów czasowych

W tej sekcji utworzymy duży zestaw zwykłych szeregów czasowych po prostu i intuicyjnie przy użyciu make-series operatora oraz uzupełnimy brakujące wartości zgodnie z potrzebami. Pierwszym krokiem analizy szeregów czasowych jest partycjonowanie i przekształcanie oryginalnej tabeli telemetrii na zestaw szeregów czasowych. Tabela zawiera zwykle kolumnę znacznika czasu, wymiary kontekstowe i opcjonalne metryki. Wymiary są używane do partycjonowania danych. Celem jest utworzenie tysięcy szeregów czasowych na partycję w regularnych odstępach czasu.

Tabela wejściowa demo_make_series1 zawiera 600 000 rekordów dowolnego ruchu usługi internetowej. Użyj następującego polecenia, aby próbkować 10 rekordów:

demo_make_series1 | take 10 

Tabela wynikowa zawiera kolumnę sygnatury czasowej, trzy kolumny wymiarów kontekstowych i bez metryk:

Znacznik czasu BrowserVer OsVer Kraj/region
2016-08-25 09:12:35.4020000 Chrome 51.0 Windows 7 Zjednoczone Królestwo
2016-08-25 09:12:41.1120000 Chrome 52.0 Windows 10
2016-08-25 09:12:46.2300000 Chrome 52.0 Windows 7 Zjednoczone Królestwo
2016-08-25 09:12:46.5100000 Chrome 52.0 Windows 10 Zjednoczone Królestwo
2016-08-25 09:12:46.5570000 Chrome 52.0 Windows 10 Republika Litwy
2016-08-25 09:12:47.0470000 Chrome 52.0 Windows 8.1 Indie
2016-08-25 09:12:51.3600000 Chrome 52.0 Windows 10 Zjednoczone Królestwo
2016-08-25 09:12:51.6930000 Chrome 52.0 Windows 7 Holandia
2016-08-25 09:12:56.4240000 Chrome 52.0 Windows 10 Zjednoczone Królestwo
2016-08-25 09:13:08.7230000 Chrome 52.0 Windows 10 Indie

Ponieważ nie ma metryk, możemy utworzyć tylko zestaw szeregów czasowych reprezentujących samą liczbę ruchu, partycjonowaną przez system operacyjny przy użyciu następującego zapytania:

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 
  • make-series Użyj operatora , aby utworzyć zestaw trzech szeregów czasowych, gdzie:
    • num=count(): szereg czasowy ruchu
    • from min_t to max_t step 1h: szereg czasowy jest tworzony w przedziałach 1-godzinnych w zakresie czasu (najstarsze i najnowsze znaczniki czasu rekordów tabeli)
    • default=0: określ metodę wypełnienia dla brakujących pojemników, aby utworzyć zwykłe szeregi czasowe. Alternatywnie należy użyć series_fill_const(), series_fill_backward()series_fill_forward()i series_fill_linear() w przypadku zmian
    • by OsVer: partycja według systemu operacyjnego
  • Rzeczywista struktura danych szeregów czasowych to tablica liczbowa zagregowanej wartości za każdym razem. Używamy do render timechart wizualizacji.

W powyższej tabeli mamy trzy partycje. Możemy utworzyć oddzielny szereg czasowy: Windows 10 (czerwony), 7 (niebieski) i 8.1 (zielony) dla każdej wersji systemu operacyjnego, jak pokazano na wykresie:

Partycja szeregów czasowych.

Funkcje analizy szeregów czasowych

W tej sekcji wykonamy typowe funkcje przetwarzania serii. Po utworzeniu zestawu szeregów czasowych język KQL obsługuje rosnącą listę funkcji do ich przetwarzania i analizowania. Opiszemy kilka reprezentatywnych funkcji przetwarzania i analizowania szeregów czasowych.

Filtrowanie

Filtrowanie to powszechna praktyka w zakresie przetwarzania sygnałów i przydatna w przypadku zadań przetwarzania szeregów czasowych (na przykład wygładzania sygnału hałaśliwych, wykrywania zmian).

  • Istnieją dwie ogólne funkcje filtrowania:
    • series_fir(): Stosowanie filtru FIR. Służy do prostego obliczania średniej ruchomej i różnicowania szeregów czasowych na potrzeby wykrywania zmian.
    • series_iir(): Stosowanie filtru IIR. Służy do wygładzania wykładniczego i sumy skumulowanej.
  • Extend zestaw szeregów czasowych przez dodanie do zapytania nowej średniej ruchomej serii o rozmiarze 5 pojemników (o nazwie 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

Filtrowanie szeregów czasowych.

Analiza regresji

Usługa Azure Data Explorer obsługuje analizę regresji liniowej segmentowanej w celu oszacowania trendu szeregów czasowych.

  • Użyj series_fit_line(), aby dopasować najlepszy wiersz do szeregu czasowego w celu ogólnego wykrywania trendów.
  • Użyj series_fit_2lines(), aby wykrywać zmiany trendów względem punktu odniesienia, które są przydatne w scenariuszach monitorowania.

Przykład funkcji series_fit_line() i series_fit_2lines() w zapytaniu szeregów czasowych:

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

Regresja szeregów czasowych.

  • Niebieski: oryginalny szereg czasowy
  • Zielony: dopasowana linia
  • Czerwony: dwie dopasowane linie

Uwaga

Funkcja dokładnie wykryła punkt skoku (zmiana poziomu).

Wykrywanie sezonowości

Wiele metryk jest zgodne ze wzorcami sezonowymi (okresowymi). Ruch użytkowników usług w chmurze zwykle zawiera wzorce dzienne i tygodniowe, które są najwyższe w środku dnia roboczego i najniższe w nocy i w weekend. Czujniki IoT są mierzone w okresowych odstępach czasu. Pomiary fizyczne, takie jak temperatura, ciśnienie lub wilgotność, mogą również wykazywać sezonowe zachowanie.

W poniższym przykładzie stosowana jest funkcja wykrywania sezonowości w jednym miesiącu ruchu usługi internetowej (przedziały 2-godzinne):

demo_series3
| render timechart 

Sezonowość szeregów czasowych.

Uwaga

Jest to anomalia, jeśli nie istnieją określone odrębne okresy

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
Okresy Wyniki Dni
84 0.820622786055595 7
12 0.764601405803502 1

Funkcja wykrywa sezonowość codziennie i co tydzień. Dzienny wynik jest mniejszy niż co tydzień, ponieważ dni weekendowe różnią się od dni tygodnia.

Funkcje mądre elementu

Operacje arytmetyczne i logiczne można wykonywać na szeregach czasowych. Korzystając z series_subtract(), możemy obliczyć resztę szeregów czasowych, czyli różnicę między oryginalną metryką pierwotną a wygładzonym, a także wyszukać anomalie w sygnale reszty:

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 in 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

Operacje szeregów czasowych.

  • Niebieski: oryginalny szereg czasowy
  • Czerwony: wygładzony szereg czasowy
  • Zielony: pozostałe szeregi czasowe

Przepływ pracy szeregów czasowych na dużą skalę

W poniższym przykładzie pokazano, jak te funkcje mogą być uruchamiane na dużą skalę w tysiącach szeregów czasowych w sekundach na potrzeby wykrywania anomalii. Aby wyświetlić kilka przykładowych rekordów telemetrycznych metryki liczby odczytów usługi DB w ciągu czterech dni, uruchom następujące zapytanie:

demo_many_series1
| take 4 
TIMESTAMP Loc Operator 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

I proste statystyki:

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

Tworzenie szeregu czasowego w 1-godzinnych przedziałach metryki odczytu (łącznie cztery dni * 24 godziny = 96 punktów), powoduje normalne wahania wzorca:

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) 

Szeregi czasowe na dużą skalę.

Powyższe zachowanie jest mylące, ponieważ pojedynczy normalny szereg czasowy jest agregowany z tysięcy różnych wystąpień, które mogą mieć nietypowe wzorce. W związku z tym tworzymy szereg czasowy na wystąpienie. Wystąpienie jest definiowane przez loc (lokalizację), operację (operację) i bazę danych (konkretną maszynę).

Ile szeregów czasowych możemy utworzyć?

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

Teraz utworzymy zestaw 18339 szeregów czasowych metryki liczby odczytów. Dodamy klauzulę by do instrukcji make-series, zastosuj regresję liniową i wybierzemy dwie pierwsze serie czasowe, które miały najbardziej znaczący trend malejący:

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)')

Pierwsze dwie serie czasowe.

Wyświetl wystąpienia:

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 
Loc Operator DB Nachylenie
Loc 15 37 1151 -102743.910227889
Loc 13 37 1249 -86303.2334644601

W mniej niż dwie minuty przeanalizowano blisko 20 000 szeregów czasowych i dwa nietypowe szeregi czasowe, w których liczba odczytów nagle spadła.

Te zaawansowane możliwości połączone z szybką wydajnością zapewniają unikatowe i zaawansowane rozwiązanie do analizy szeregów czasowych.