Optymalizowanie zapytań dziennika w usłudze Azure Monitor
Dzienniki usługi Azure Monitor używają usługi Azure Data Explorer do przechowywania danych dziennika i uruchamiania zapytań do analizowania tych danych. Tworzy i obsługuje klastry usługi Azure Data Explorer oraz zarządza nimi i optymalizuje je pod kątem obciążenia analizy dzienników. Po uruchomieniu zapytania jest on zoptymalizowany i kierowany do odpowiedniego klastra usługi Azure Data Explorer, który przechowuje dane obszaru roboczego.
Dzienniki usługi Azure Monitor i usługa Azure Data Explorer korzystają z wielu mechanizmów optymalizacji zapytań automatycznych. Optymalizacje automatyczne zapewniają znaczący wzrost, ale istnieją pewne przypadki, w których można znacznie zwiększyć wydajność zapytań. W tym artykule opisano zagadnienia dotyczące wydajności i kilka technik ich naprawiania.
Większość technik jest typowych dla zapytań uruchamianych bezpośrednio w usłudze Azure Data Explorer i dziennikach usługi Azure Monitor. Omówiono również kilka unikatowych zagadnień dotyczących dzienników usługi Azure Monitor. Aby uzyskać więcej wskazówek dotyczących optymalizacji usługi Azure Data Explorer, zobacz Najlepsze rozwiązania dotyczące zapytań.
Zoptymalizowane zapytania będą:
- Uruchom szybciej i zmniejsz ogólny czas trwania wykonywania zapytania.
- Mają mniejsze szanse na ograniczenie lub odrzucenie.
Zwróć szczególną uwagę na zapytania, które są używane do cyklicznego i jednoczesnego użycia, takich jak pulpity nawigacyjne, alerty, usługa Azure Logic Apps i usługa Power BI. Wpływ nieskutecznego zapytania w tych przypadkach jest istotny.
Poniżej przedstawiono szczegółowy przewodnik wideo dotyczący optymalizowania zapytań.
Okienko Szczegóły zapytania
Po uruchomieniu zapytania w usłudze Log Analytics wybierz pozycję Szczegóły zapytania w prawym dolnym rogu ekranu, aby otworzyć okienko Szczegóły zapytania. W tym okienku przedstawiono wyniki kilku wskaźników wydajności zapytania. Te wskaźniki wydajności opisano w poniższej sekcji.
Wskaźniki wydajności zapytań
Następujące wskaźniki wydajności zapytań są dostępne dla każdego wykonywanego zapytania:
- Łączny procesor CPU: ogólne zasoby obliczeniowe używane do przetwarzania zapytania we wszystkich węzłach obliczeniowych. Reprezentuje czas używany do przetwarzania, analizowania i pobierania danych.
- Dane używane do przetwarzania zapytania: ogólne dane, do których uzyskiwano dostęp do przetwarzania zapytania. Pod wpływem rozmiaru tabeli docelowej, używanego przedziału czasu, zastosowanych filtrów i liczby przywoływanych kolumn.
- Przedział czasu przetworzonego zapytania: różnica między najnowszymi i najstarszymi danymi, do których uzyskiwano dostęp do przetwarzania zapytania. Pod wpływem jawnego zakresu czasu określonego dla zapytania.
- Wiek przetworzonych danych: różnica między teraz a najstarszymi danymi, do których uzyskiwano dostęp do przetwarzania zapytania. Ma to duży wpływ na wydajność pobierania danych.
- Liczba obszarów roboczych: liczba obszarów roboczych, do których uzyskiwano dostęp podczas przetwarzania zapytań na podstawie niejawnego lub jawnego zaznaczenia.
- Liczba regionów: liczba regionów, do których uzyskiwano dostęp podczas przetwarzania zapytań w oparciu o niejawny lub jawny wybór obszarów roboczych. Zapytania w wielu regionach są znacznie mniej wydajne, a wskaźniki wydajności przedstawiają częściowe pokrycie.
- Równoległość: wskazuje, ile system mógł wykonać to zapytanie na wielu węzłach. Dotyczy tylko zapytań, które mają wysokie użycie procesora CPU. Wpływ na użycie określonych funkcji i operatorów.
Łączna liczba procesorów CPU
Rzeczywisty procesor obliczeniowy, który został zainwestowany w przetwarzanie tego zapytania we wszystkich węzłach przetwarzania zapytań. Ponieważ większość zapytań jest wykonywanych na dużej liczbie węzłów, ta suma zwykle będzie znacznie większa niż czas wykonywania zapytania.
Zapytanie korzystające z ponad 100 sekund procesora CPU jest uznawane za zapytanie, które zużywa nadmierne zasoby. Zapytanie korzystające z ponad 1000 sekund procesora CPU jest uznawane za obraźliwe zapytanie i może być ograniczane.
Czas przetwarzania zapytań jest poświęcany na:
- Pobieranie danych: Pobieranie starych danych zużywa więcej czasu niż pobieranie ostatnich danych.
- Przetwarzanie danych: logika i ocena danych.
Oprócz czasu spędzonego w węzłach przetwarzania zapytań dzienniki usługi Azure Monitor poświęcają czas na:
- Uwierzytelnianie użytkownika i weryfikowanie, czy jest on uprawniony do uzyskiwania dostępu do tych danych.
- Lokalizowanie magazynu danych.
- Analizowanie zapytania.
- Przydzielanie węzłów przetwarzania zapytań.
Tym razem nie jest uwzględniona w zapytaniu łączny czas procesora CPU.
Wczesne filtrowanie rekordów przed użyciem funkcji wysokiego użycia procesora CPU
Niektóre polecenia zapytań i funkcje są duże w ich użyciu procesora CPU. Ten przypadek jest szczególnie prawdziwy w przypadku poleceń, które analizują dane JSON i XML lub wyodrębniają złożone wyrażenia regularne. Takie analizowanie może wystąpić jawnie za pośrednictwem funkcji parse_json() lub parse_xml() lub niejawnie, gdy odwołuje się do kolumn dynamicznych.
Te funkcje zużywają procesor CPU proporcjonalnie do liczby wierszy, które przetwarzają. Najbardziej wydajną optymalizacją jest dodanie where
warunków na wczesnym etapie zapytania. W ten sposób mogą odfiltrować jak najwięcej rekordów przed wykonaniem funkcji intensywnie korzystającej z procesora CPU.
Na przykład następujące zapytania generują dokładnie ten sam wynik. Ale drugi jest najbardziej wydajny, ponieważ warunek where przed analizowaniem wyklucza wiele rekordów:
//less efficient
SecurityEvent
| extend Details = parse_xml(EventData)
| extend FilePath = tostring(Details.UserData.RuleAndFileData.FilePath)
| extend FileHash = tostring(Details.UserData.RuleAndFileData.FileHash)
| where FileHash != "" and FilePath !startswith "%SYSTEM32" // Problem: irrelevant results are filtered after all processing and parsing is done
| summarize count() by FileHash, FilePath
//more efficient
SecurityEvent
| where EventID == 8002 //Only this event have FileHash
| where EventData !has "%SYSTEM32" //Early removal of unwanted records
| extend Details = parse_xml(EventData)
| extend FilePath = tostring(Details.UserData.RuleAndFileData.FilePath)
| extend FileHash = tostring(Details.UserData.RuleAndFileData.FileHash)
| where FileHash != "" and FilePath !startswith "%SYSTEM32" // exact removal of results. Early filter is not accurate enough
| summarize count() by FileHash, FilePath
| where FileHash != "" // No need to filter out %SYSTEM32 here as it was removed before
Unikaj używania ocenianych klauzul where
Zapytania zawierające klauzule where w kolumnie ocenianej, a nie na kolumnach, które są fizycznie obecne w zestawie danych, tracą wydajność. Filtrowanie kolumn ocenianych zapobiega optymalizacjom systemu w przypadku obsługi dużych zestawów danych.
Na przykład następujące zapytania generują dokładnie ten sam wynik. Ale drugi jest bardziej wydajny, ponieważ warunek where odnosi się do wbudowanej kolumny:
//less efficient
Syslog
| extend Msg = strcat("Syslog: ",SyslogMessage)
| where Msg has "Error"
| count
//more efficient
Syslog
| where SyslogMessage has "Error"
| count
W niektórych przypadkach kolumna oceniana jest tworzona niejawnie przez aparat przetwarzania zapytań, ponieważ filtrowanie odbywa się nie tylko w polu:
//less efficient
SecurityEvent
| where tolower(Process) == "conhost.exe"
| count
//more efficient
SecurityEvent
| where Process =~ "conhost.exe"
| count
Używanie skutecznych poleceń agregacji i wymiarów w podsumowaniu i sprzężenia
Niektóre polecenia agregacji, takie jak max(), sum(), count() i avg() mają niski wpływ na procesor CPU ze względu na ich logikę. Inne polecenia są bardziej złożone i obejmują heurystyki i oszacowania, które pozwalają na ich wydajne wykonywanie. Na przykład funkcja dcount() używa algorytmu HyperLogLog, aby zapewnić zbliżone oszacowanie do odrębnej liczby dużych zestawów danych bez faktycznego zliczania każdej wartości.
Funkcje percentylu wykonują podobne przybliżenia przy użyciu najbliższego algorytmu percentyla rangi. Kilka poleceń zawiera opcjonalne parametry, aby zmniejszyć ich wpływ. Na przykład funkcja makeset() ma opcjonalny parametr definiujący maksymalny rozmiar zestawu, który znacząco wpływa na procesor i pamięć.
Sprzężenie i podsumowywanie poleceń może spowodować wysokie wykorzystanie procesora CPU podczas przetwarzania dużego zestawu danych. Ich złożoność jest bezpośrednio związana z liczbą możliwych wartości, określanych jako kardynalność, kolumn, które są używane jako by
w summarize
lub jako join
atrybuty. Aby uzyskać wyjaśnienie i optymalizację join
elementów i summarize
, zobacz ich artykuły w dokumentacji i porady dotyczące optymalizacji.
Na przykład następujące zapytania generują dokładnie taki sam wynik, ponieważ CounterPath
zawsze jest mapowany jeden do jednego na CounterName
i ObjectName
. Drugi jest bardziej wydajny, ponieważ wymiar agregacji jest mniejszy:
//less efficient
Perf
| summarize avg(CounterValue)
by CounterName, CounterPath, ObjectName
//make the group expression more compact improve the performance
Perf
| summarize avg(CounterValue), any(CounterName), any(ObjectName)
by CounterPath
Użycie procesora CPU może również mieć wpływ na where
warunki lub rozszerzone kolumny, które wymagają intensywnego przetwarzania. Wszystkie proste porównania ciągów, takie jak equal == i startswith, mają mniej więcej taki sam wpływ na procesor. Zaawansowane dopasowania tekstu mają większy wpływ. W szczególności operator has jest bardziej wydajny niż operator contains . Ze względu na techniki obsługi ciągów bardziej wydajne jest wyszukiwanie ciągów, które są dłuższe niż cztery znaki niż krótkie ciągi.
Na przykład następujące zapytania generują podobne wyniki w zależności od Computer
zasad nazewnictwa. Ale drugi jest bardziej wydajny:
//less efficient – due to filter based on contains
Heartbeat
| where Computer contains "Production"
| summarize count() by ComputerIP
//less efficient – due to filter based on extend
Heartbeat
| extend MyComputer = Computer
| where MyComputer startswith "Production"
| summarize count() by ComputerIP
//more efficient
Heartbeat
| where Computer startswith "Production"
| summarize count() by ComputerIP
Uwaga
Ten wskaźnik przedstawia tylko procesor z klastra natychmiastowego. W zapytaniu obejmującym wiele regionów będzie ona reprezentować tylko jeden z regionów. W zapytaniu obejmującym wiele obszarów roboczych może nie zawierać wszystkich obszarów roboczych.
Unikaj pełnego analizowania kodu XML i JSON, gdy analizowanie ciągów działa
Pełne analizowanie obiektu XML lub JSON może zużywać wysokie zasoby procesora CPU i pamięci. W wielu przypadkach, gdy potrzebne są tylko jeden lub dwa parametry, a obiekty XML lub JSON są proste, łatwiej jest je przeanalizować jako ciągi. Użyj operatora analizy lub innych technik analizowania tekstu. Zwiększenie wydajności będzie bardziej znaczące, ponieważ liczba rekordów w obiekcie XML lub JSON zwiększa się. Jest to niezbędne, gdy liczba rekordów osiągnie dziesiątki milionów.
Na przykład następujące zapytanie zwraca dokładnie te same wyniki co poprzednie zapytania bez wykonywania pełnego analizowania KODU XML. Zapytanie przyjmuje pewne założenia dotyczące struktury plików XML, takie jak FilePath
element pojawia się po FileHash
, a żaden z nich nie ma atrybutów:
//even more efficient
SecurityEvent
| where EventID == 8002 //Only this event have FileHash
| where EventData !has "%SYSTEM32" //Early removal of unwanted records
| parse EventData with * "<FilePath>" FilePath "</FilePath>" * "<FileHash>" FileHash "</FileHash>" *
| summarize count() by FileHash, FilePath
| where FileHash != "" // No need to filter out %SYSTEM32 here as it was removed before
Dane używane do przetwarzania zapytania
Krytycznym czynnikiem przetwarzania zapytania jest ilość danych skanowanych i używanych do przetwarzania zapytań. Usługa Azure Data Explorer używa agresywnych optymalizacji, które znacznie zmniejszają ilość danych w porównaniu z innymi platformami danych. Mimo to w zapytaniu istnieją krytyczne czynniki, które mogą mieć wpływ na używany wolumin danych.
Zapytanie, które przetwarza ponad 2000 KB danych, jest traktowane jako zapytanie, które zużywa nadmierne zasoby. Zapytanie, które przetwarza ponad 20 000 KB danych, jest uznawane za obraźliwe zapytanie i może zostać ograniczone.
W dziennikach usługi Azure Monitor kolumna TimeGenerated
jest używana jako sposób indeksowania danych. Ograniczenie TimeGenerated
wartości do tak wąskiego zakresu, jak to możliwe, poprawi wydajność zapytań. Wąski zakres znacznie ogranicza ilość danych, które należy przetworzyć.
Unikaj niepotrzebnego używania operatorów wyszukiwania i unii
Innym czynnikiem zwiększającym przetwarzane dane jest użycie dużej liczby tabel. Ten scenariusz zwykle występuje, gdy search *
są używane polecenia i union *
. Te polecenia wymuszają na systemie ocenę i skanowanie danych ze wszystkich tabel w obszarze roboczym. W niektórych przypadkach w obszarze roboczym mogą znajdować się setki tabel. Staraj się unikać używania search *
lub dowolnego wyszukiwania bez określania zakresu do określonej tabeli.
Na przykład następujące zapytania generują dokładnie ten sam wynik, ale ostatni z nich jest najbardziej wydajny:
// This version scans all tables though only Perf has this kind of data
search "Processor Time"
| summarize count(), avg(CounterValue) by Computer
// This version scans all strings in Perf tables – much more efficient
Perf
| search "Processor Time"
| summarize count(), avg(CounterValue) by Computer
// This is the most efficient version
Perf
| where CounterName == "% Processor Time"
| summarize count(), avg(CounterValue) by Computer
Dodawanie wczesnych filtrów do zapytania
Inną metodą zmniejszenia ilości danych jest posiadanie warunków na wczesnym etapie zapytania. Platforma Azure Data Explorer zawiera pamięć podręczną, która informuje o tym, które partycje zawierają dane istotne dla określonego where
warunku. Jeśli na przykład zapytanie zawiera where EventID == 4624
element , zapytanie będzie dystrybuowane tylko do węzłów obsługujących partycje z pasującymi zdarzeniami.
Następujące przykładowe zapytania generują dokładnie ten sam wynik, ale drugi jest bardziej wydajny:
//less efficient
SecurityEvent
| summarize LoginSessions = dcount(LogonGuid) by Account
//more efficient
SecurityEvent
| where EventID == 4624 //Logon GUID is relevant only for logon event
| summarize LoginSessions = dcount(LogonGuid) by Account
Unikaj wielu skanowań tych samych danych źródłowych przy użyciu funkcji agregacji warunkowej i zmaterializowania funkcji
Jeśli zapytanie ma kilka podzapytania, które są scalane przy użyciu operatorów sprzężenia lub unii, każde podzapytywanie skanuje całe źródło oddzielnie. Następnie scala wyniki. Ta akcja mnoży liczbę skanowań danych, co jest krytycznym czynnikiem w dużych zestawach danych.
Techniką, która pozwala uniknąć tego scenariusza, jest użycie funkcji agregacji warunkowej. Większość funkcji agregacji używanych w operatorze podsumowania ma wersję warunkową, której można użyć dla jednego operatora podsumowania z wieloma warunkami.
Na przykład następujące zapytania pokazują liczbę zdarzeń logowania i liczbę zdarzeń wykonywania procesu dla każdego konta. Zwracają te same wyniki, ale pierwsze zapytanie skanuje dane dwa razy. Drugie zapytanie skanuje je tylko raz:
//Scans the SecurityEvent table twice and perform expensive join
SecurityEvent
| where EventID == 4624 //Login event
| summarize LoginCount = count() by Account
| join
(
SecurityEvent
| where EventID == 4688 //Process execution event
| summarize ExecutionCount = count(), ExecutedProcesses = make_set(Process) by Account
) on Account
//Scan only once with no join
SecurityEvent
| where EventID == 4624 or EventID == 4688 //early filter
| summarize LoginCount = countif(EventID == 4624), ExecutionCount = countif(EventID == 4688), ExecutedProcesses = make_set_if(Process,EventID == 4688) by Account
Innym przypadkiem, w którym podzapytania są niepotrzebne, jest wstępne filtrowanie dla operatora analizy, aby upewnić się, że przetwarza tylko rekordy zgodne z określonym wzorcem. Są one niepotrzebne, ponieważ operator analizy i inne podobne operatory zwracają puste wyniki, gdy wzorzec nie jest zgodny. Następujące dwa zapytania zwracają dokładnie te same wyniki, ale drugie zapytanie skanuje dane tylko raz. W drugim zapytaniu każde polecenie analizy jest istotne tylko dla jego zdarzeń. Następnie extend
operator pokazuje, jak odwoływać się do pustej sytuacji danych:
//Scan SecurityEvent table twice
union(
SecurityEvent
| where EventID == 8002
| parse EventData with * "<FilePath>" FilePath "</FilePath>" * "<FileHash>" FileHash "</FileHash>" *
| distinct FilePath
),(
SecurityEvent
| where EventID == 4799
| parse EventData with * "CallerProcessName\">" CallerProcessName1 "</Data>" *
| distinct CallerProcessName1
)
//Single scan of the SecurityEvent table
SecurityEvent
| where EventID == 8002 or EventID == 4799
| parse EventData with * "<FilePath>" FilePath "</FilePath>" * "<FileHash>" FileHash "</FileHash>" * //Relevant only for event 8002
| parse EventData with * "CallerProcessName\">" CallerProcessName1 "</Data>" * //Relevant only for event 4799
| extend FilePath = iif(isempty(CallerProcessName1),FilePath,"")
| distinct FilePath, CallerProcessName1
Jeśli powyższe zapytanie nie pozwala uniknąć używania podzapytania, inną techniką jest wskazówka aparatu zapytań, że istnieje jedno źródło danych używanych w każdej z nich przy użyciu funkcji materialize(). Ta technika jest przydatna, gdy dane źródłowe pochodzą z funkcji używanej kilka razy w zapytaniu. Materialize
jest skuteczny, gdy dane wyjściowe podzapytania są znacznie mniejsze niż dane wejściowe. Aparat zapytań będzie buforowy i ponownie używa danych wyjściowych we wszystkich wystąpieniach.
Zmniejsz liczbę pobranych kolumn
Ponieważ usługa Azure Data Explorer to kolumnowy magazyn danych, pobieranie każdej kolumny jest niezależne od innych. Liczba pobieranych kolumn bezpośrednio wpływa na ogólny wolumin danych. Kolumny powinny być uwzględniane tylko w danych wyjściowych, które są potrzebne, podsumowując wyniki lub wyświetlając określone kolumny.
Usługa Azure Data Explorer oferuje kilka optymalizacji w celu zmniejszenia liczby pobranych kolumn. Jeśli okaże się, że kolumna nie jest potrzebna, na przykład jeśli nie jest przywoływalna w poleceniu podsumowania , nie zostanie pobrana.
Na przykład drugie zapytanie może przetwarzać trzy razy więcej danych, ponieważ musi pobrać nie jedną kolumnę, ale trzy:
//Less columns --> Less data
SecurityEvent
| summarize count() by Computer
//More columns --> More data
SecurityEvent
| summarize count(), dcount(EventID), avg(Level) by Computer
Przedział czasu przetworzonego zapytania
Wszystkie dzienniki w dziennikach usługi Azure Monitor są partycjonowane zgodnie z kolumną TimeGenerated
. Liczba partycji, do których uzyskuje się dostęp, jest bezpośrednio związana z przedziałem czasu. Skrócenie zakresu czasu to najbardziej wydajny sposób zapewniania wykonywania zapytań monitu.
Zapytanie z czasem przekraczającym 15 dni jest uznawane za zapytanie, które zużywa nadmierne zasoby. Zapytanie z przedziałem czasu przekraczającym 90 dni jest uznawane za obraźliwe zapytanie i może zostać ograniczone.
Zakres czasu można ustawić przy użyciu selektora zakresu czasu na ekranie usługi Log Analytics, zgodnie z opisem w temacie Zakres zapytania dziennika i zakres czasu w usłudze Azure Monitor Log Analytics. Ta metoda jest zalecana, ponieważ wybrany zakres czasu jest przekazywany do zaplecza przy użyciu metadanych zapytania.
Alternatywną metodą jest jawne uwzględnienie warunku TimeGenerated
where w zapytaniu. Użyj tej metody, ponieważ zapewnia, że przedział czasu jest stały, nawet jeśli zapytanie jest używane z innego interfejsu.
Upewnij się, że wszystkie części zapytania mają TimeGenerated
filtry. Jeśli zapytanie ma podzapytania pobierające dane z różnych tabel lub tej samej tabeli, każde zapytanie musi zawierać własne warunek where .
Upewnij się, że wszystkie podzapytania mają filtr TimeGenerated
Na przykład w poniższym zapytaniu Perf
tabela zostanie przeskanowana tylko w ciągu ostatniego dnia. Tabela Heartbeat
zostanie przeskanowana pod kątem całej jego historii, co może potrwać do dwóch lat:
Perf
| where TimeGenerated > ago(1d)
| summarize avg(CounterValue) by Computer, CounterName
| join kind=leftouter (
Heartbeat
//No time span filter in this part of the query
| summarize IPs = makeset(ComputerIP, 10) by Computer
) on Computer
Typowym przypadkiem, w którym taki błąd występuje, jest zastosowanie arg_max() w celu znalezienia ostatniego wystąpienia. Na przykład:
Perf
| where TimeGenerated > ago(1d)
| summarize avg(CounterValue) by Computer, CounterName
| join kind=leftouter (
Heartbeat
//No time span filter in this part of the query
| summarize arg_max(TimeGenerated, *), min(TimeGenerated)
by Computer
) on Computer
Tę sytuację można łatwo poprawić, dodając filtr czasu w zapytaniu wewnętrznym:
Perf
| where TimeGenerated > ago(1d)
| summarize avg(CounterValue) by Computer, CounterName
| join kind=leftouter (
Heartbeat
| where TimeGenerated > ago(1d) //filter for this part
| summarize arg_max(TimeGenerated, *), min(TimeGenerated)
by Computer
) on Computer
Innym przykładem tego błędu jest wykonanie filtrowania zakresu czasu tuż po połączeniu w kilku tabelach. Podczas wykonywania unii każde podzapytywanie powinno mieć zakres. Możesz użyć instrukcji let , aby zapewnić spójność określania zakresu.
Na przykład następujące zapytanie przeskanuje wszystkie dane w Heartbeat
tabelach i Perf
, a nie tylko ostatniego dnia:
Heartbeat
| summarize arg_min(TimeGenerated,*) by Computer
| union (
Perf
| summarize arg_min(TimeGenerated,*) by Computer)
| where TimeGenerated > ago(1d)
| summarize min(TimeGenerated) by Computer
Aby naprawić zapytanie:
let MinTime = ago(1d);
Heartbeat
| where TimeGenerated > MinTime
| summarize arg_min(TimeGenerated,*) by Computer
| union (
Perf
| where TimeGenerated > MinTime
| summarize arg_min(TimeGenerated,*) by Computer)
| summarize min(TimeGenerated) by Computer
Ograniczenia pomiaru zakresu czasu
Pomiar jest zawsze większy niż określony rzeczywisty czas. Jeśli na przykład filtr zapytania wynosi 7 dni, system może skanować 7,5 lub 8,1 dni. Ta wariancja jest taka, ponieważ system partycjonuje dane na fragmenty zmiennych rozmiarów. Aby upewnić się, że wszystkie odpowiednie rekordy są skanowane, system skanuje całą partycję. Ten proces może obejmować kilka godzin, a nawet więcej niż dzień.
Istnieje kilka przypadków, w których system nie może zapewnić dokładnego pomiaru zakresu czasu. Taka sytuacja występuje w większości przypadków, gdy zakres zapytania jest krótszy niż dzień lub w zapytaniach obejmujących wiele obszarów roboczych.
Ważne
Ten wskaźnik przedstawia tylko dane przetwarzane w bezpośrednim klastrze. W zapytaniu obejmującym wiele regionów będzie ona reprezentować tylko jeden z regionów. W zapytaniu obejmującym wiele obszarów roboczych może nie zawierać wszystkich obszarów roboczych.
Wiek przetworzonych danych
Usługa Azure Data Explorer używa kilku warstw magazynowania: w pamięci, lokalnych dysków SSD i znacznie wolniejszych obiektów blob platformy Azure. Im nowsze dane, tym większa szansa, że jest przechowywana w bardziej wydajnej warstwie z mniejszym opóźnieniem, co zmniejsza czas trwania zapytania i procesor CPU. Poza samymi danymi system ma również pamięć podręczną metadanych. Im starsze dane, tym mniejsze prawdopodobieństwo, że jego metadane będą znajdować się w pamięci podręcznej.
Zapytanie przetwarzające dane, które ma więcej niż 14 dni, jest traktowane jako zapytanie, które zużywa nadmierne zasoby.
Niektóre zapytania wymagają użycia starych danych, ale istnieją również przypadki, w których stare dane są używane przez pomyłkę. Ten scenariusz występuje, gdy zapytania są wykonywane bez podawania zakresu czasu w metadanych, a nie wszystkie odwołania do tabeli zawierają filtr w kolumnie TimeGenerated
. W takich przypadkach system przeskanuje wszystkie dane przechowywane w tabeli. Gdy przechowywanie danych jest długie, może obejmować długie zakresy czasu. W związku z tym dane, które są tak stare, jak okres przechowywania danych, są skanowane.
Takie przypadki mogą być na przykład:
- Nie ustawiaj zakresu czasu w usłudze Log Analytics przy użyciu podzapytania, które nie jest ograniczone. Zobacz poprzedni przykład.
- Korzystanie z interfejsu API bez parametrów opcjonalnych zakresu czasu.
- Używanie klienta, który nie wymusza zakresu czasu, na przykład takiego jak łącznik usługi Power BI.
Zobacz przykłady i uwagi w poprzedniej sekcji, ponieważ są one również istotne w tym przypadku.
Liczba regionów
Istnieją sytuacje, w których pojedyncze zapytanie może być wykonywane w różnych regionach. Na przykład:
- Gdy kilka obszarów roboczych jest jawnie wyświetlanych i znajduje się w różnych regionach.
- Gdy zapytanie o zakresie zasobów pobiera dane, a dane są przechowywane w wielu obszarach roboczych, które znajdują się w różnych regionach.
Wykonywanie zapytań między regionami wymaga, aby system serializować i przesyłać w zapleczu duże fragmenty danych pośrednich, które są zwykle znacznie większe niż wyniki końcowe zapytania. Ogranicza również zdolność systemu do przeprowadzania optymalizacji i heurystyki oraz używania pamięci podręcznych.
Jeśli nie ma powodu do skanowania wszystkich tych regionów, dostosuj zakres, aby obejmował mniej regionów. Jeśli zakres zasobów jest zminimalizowany, ale wiele regionów jest nadal używanych, może się to zdarzyć z powodu błędnej konfiguracji. Na przykład dzienniki inspekcji i ustawienia diagnostyczne mogą być wysyłane do różnych obszarów roboczych w różnych regionach lub może istnieć wiele konfiguracji ustawień diagnostycznych.
Zapytanie obejmujące więcej niż trzy regiony jest traktowane jako zapytanie, które zużywa nadmierne zasoby. Zapytanie obejmujące ponad sześć regionów jest uznawane za obraźliwe zapytanie i może zostać ograniczone.
Ważne
Gdy zapytanie jest uruchamiane w kilku regionach, pomiary procesora CPU i danych nie będą dokładne i będą reprezentować pomiar tylko jednego z regionów.
Liczba obszarów roboczych
Obszary robocze to kontenery logiczne używane do segregowania i administrowania danymi dzienników. Zaplecze optymalizuje umieszczanie obszarów roboczych w klastrach fizycznych w wybranym regionie.
Użycie wielu obszarów roboczych może wynikać z wystąpień, gdy:
- Kilka obszarów roboczych jest jawnie wymienionych.
- Zapytanie o zakresie zasobów pobiera dane, a dane są przechowywane w wielu obszarach roboczych.
Wykonywanie zapytań między regionami i między klastrami wymaga, aby system serializować i przesyłać na zapleczu duże fragmenty danych pośrednich, które są zwykle znacznie większe niż wyniki końcowe zapytania. Ogranicza również zdolność systemu do przeprowadzania optymalizacji i heurystyki oraz używania pamięci podręcznych.
Zapytanie obejmujące więcej niż pięć obszarów roboczych jest traktowane jako zapytanie, które zużywa nadmierne zasoby. Zapytania nie mogą obejmować więcej niż 100 obszarów roboczych.
Ważne
- W niektórych scenariuszach obejmujących wiele obszarów roboczych pomiary procesora CPU i danych nie będą dokładne i będą reprezentować pomiar tylko kilku obszarów roboczych.
- Zapytania między obszarami roboczymi mają jawny identyfikator: identyfikator obszaru roboczego lub identyfikator zasobu obszaru roboczego platformy Azure, zużywają mniej zasobów i są bardziej wydajne.
Równoległość
Dzienniki usługi Azure Monitor używają dużych klastrów usługi Azure Data Explorer do uruchamiania zapytań. Te klastry różnią się w skali i potencjalnie mogą się różnić do kilkudziesięciu węzłów obliczeniowych. System automatycznie skaluje klastry zgodnie z logiką umieszczania i pojemnością obszaru roboczego.
Aby efektywnie wykonywać zapytanie, jest on partycjonowany i dystrybuowany do węzłów obliczeniowych na podstawie danych wymaganych do jego przetwarzania. W niektórych sytuacjach system nie może wykonać tego kroku wydajnie, co może prowadzić do długiego czasu trwania zapytania.
Zachowania zapytań, które mogą zmniejszyć równoległość, obejmują:
- Korzystanie z funkcji serializacji i okien, takich jak operator serializacji, next(), prev()i funkcje wiersza . W niektórych z tych przypadków można używać funkcji szeregów czasowych i analizy użytkowników. Nieefektywna serializacji może również wystąpić, jeśli następujące operatory nie są używane na końcu zapytania: zakres, sortowanie, kolejność, top, top-hitters i getschema.
- Użycie funkcji agregacji dcount() wymusza, aby system miał centralną kopię unikatowych wartości. Jeśli skala danych jest wysoka, rozważ użycie
dcount
opcjonalnych parametrów funkcji w celu zmniejszenia dokładności. - W wielu przypadkach operator sprzężenia obniża ogólną równoległość. Sprawdź
shuffle join
jako alternatywę, gdy wydajność jest problematyczna. - W zapytaniach dotyczących zakresu zasobów kontrola dostępu oparta na rolach (RBAC) lub kontrola RBAC platformy Azure może utrzymywać się w sytuacjach, w których istnieje duża liczba przypisań ról platformy Azure. Taka sytuacja może prowadzić do dłuższych kontroli, które doprowadziłyby do mniejszego równoległości. Na przykład zapytanie może być wykonywane w ramach subskrypcji, w której istnieją tysiące zasobów, a każdy zasób ma wiele przypisań ról na poziomie zasobu, a nie w subskrypcji lub grupie zasobów.
- Jeśli zapytanie przetwarza małe fragmenty danych, jego równoległość będzie niska, ponieważ system nie rozłoży go na wiele węzłów obliczeniowych.