Limity zapytań

Kusto to aparat zapytań ad hoc, który hostuje duże zestawy danych i próbuje spełnić zapytania, przechowując wszystkie odpowiednie dane w pamięci. Istnieje pewne ryzyko, że zapytania będą monopolizować zasoby usługi bez ograniczeń. Usługa Kusto zapewnia kilka wbudowanych zabezpieczeń w postaci domyślnych limitów zapytań. Jeśli rozważasz usunięcie tych limitów, najpierw określ, czy rzeczywiście uzyskasz jakąkolwiek wartość.

Limit współbieżności żądań

Współbieżność żądań to limit, który klaster nakłada na kilka żądań uruchomionych jednocześnie.

  • Wartość domyślna limitu zależy od jednostki SKU uruchomionej w klastrze i jest obliczana jako: Cores-Per-Node x 10.
    • Na przykład w przypadku klastra skonfigurowanego w jednostce SKU D14v2, gdzie każda maszyna ma 16 rdzeni wirtualnych, domyślnym limitem jest 16 cores x10 = 160.
  • Wartość domyślną można zmienić, konfigurując zasady defaultlimitu szybkości żądań grupy obciążeń.
    • Rzeczywista liczba żądań, które mogą być uruchamiane współbieżnie na klastrze, zależy od różnych czynników. Najbardziej dominującymi czynnikami są jednostka SKU klastra, dostępne zasoby klastra i wzorce użycia. Zasady można skonfigurować na podstawie testów obciążeniowych wykonywanych na wzorcach użycia przypominających środowisko produkcyjne.

Aby uzyskać więcej informacji, zobacz Optymalizowanie pod kątem wysokiej współbieżności za pomocą usługi Azure Data Explorer.

Limit rozmiaru zestawu wyników (obcinanie wyników)

Obcięcie wyników jest domyślnie ustawionym limitem dla zestawu wyników zwracanego przez zapytanie. Usługa Kusto ogranicza liczbę rekordów zwracanych do klienta do 500 000, a ogólny rozmiar danych dla tych rekordów do 64 MB. Po przekroczeniu jednego z tych limitów zapytanie kończy się niepowodzeniem z "częściowym niepowodzeniem zapytania". Przekroczenie ogólnego rozmiaru danych spowoduje wygenerowanie wyjątku z komunikatem:

The Kusto DataEngine has failed to execute a query: 'Query result set has exceeded the internal data size limit 67108864 (E_QUERY_RESULT_SET_TOO_LARGE).'

Przekroczenie liczby rekordów zakończy się niepowodzeniem z wyjątkiem z informacją:

The Kusto DataEngine has failed to execute a query: 'Query result set has exceeded the internal record count limit 500000 (E_QUERY_RESULT_SET_TOO_LARGE).'

Istnieje kilka strategii radzenia sobie z tym błędem.

  • Zmniejsz rozmiar zestawu wyników, modyfikując zapytanie tak, aby zwracało tylko interesujące dane. Ta strategia jest przydatna, gdy początkowe zapytanie kończące się niepowodzeniem jest zbyt "szerokie". Na przykład zapytanie nie projektuje kolumn danych, które nie są potrzebne.
  • Zmniejsz rozmiar zestawu wyników, przenosząc przetwarzanie po zapytaniu, takie jak agregacje, do samego zapytania. Strategia jest przydatna w scenariuszach, w których dane wyjściowe zapytania są przekazywane do innego systemu przetwarzania, a następnie wykonuje inne agregacje.
  • Przełącz się z zapytań do używania eksportu danych, gdy chcesz wyeksportować duże zestawy danych z usługi.
  • Poinstruuj usługę, aby pominąć ten limit zapytań przy użyciu set instrukcji wymienionych poniżej lub flag we właściwościach żądania klienta.

Metody zmniejszenia rozmiaru zestawu wyników generowanego przez zapytanie obejmują:

Możesz wyłączyć obcinanie wyników przy użyciu notruncation opcji żądania. Zalecamy, aby niektóre formy ograniczeń nadal obowiązują.

Na przykład:

set notruncation;
MyTable | take 1000000

Można również mieć bardziej uściśliwną kontrolę nad obcinaniem wyników, ustawiając wartość truncationmaxsize (maksymalny rozmiar danych w bajtach, domyślnie 64 MB) i truncationmaxrecords (maksymalna liczba rekordów, domyślnie 500 000). Na przykład następujące zapytanie ustawia obcinanie wyników w 1105 rekordach lub 1 MB, w zależności od tego, co zostanie przekroczone.

set truncationmaxsize=1048576;
set truncationmaxrecords=1105;
MyTable | where User=="UserId1"

Usunięcie limitu obcinania wyników oznacza, że zamierzasz przenieść dane zbiorcze z usługi Kusto.

Limit obcinania wyników można usunąć do celów eksportu przy użyciu polecenia lub do późniejszej .export agregacji. W przypadku wybrania późniejszej agregacji rozważ agregowanie przy użyciu usługi Kusto.

Usługa Kusto udostępnia wiele bibliotek klienckich, które mogą obsługiwać "nieskończenie duże" wyniki, przesyłając je strumieniowo do obiektu wywołującego. Użyj jednej z tych bibliotek i skonfiguruj ją do trybu przesyłania strumieniowego. Na przykład użyj klienta .NET Framework (Microsoft.Azure.Kusto.Data) i ustaw właściwość przesyłania strumieniowego parametry połączenia na true lub użyj wywołania ExecuteQueryV2Async(), które zawsze przesyła strumieniowo wyniki. Aby zapoznać się z przykładem użycia funkcji ExecuteQueryV2Async(), zobacz aplikację HelloKustoV2 .

Przykładowa aplikacja pozyskiwania przesyłania strumieniowego w języku C# może być również przydatna.

Obcinanie wyników jest domyślnie stosowane, a nie tylko do strumienia wyników zwracanego do klienta. Jest ona również domyślnie stosowana do dowolnej podquerii, którą jeden klaster wystawia do innego klastra w zapytaniu między klastrami z podobnymi efektami.

Ustawianie wielu właściwości obcinania wyników

W przypadku używania set instrukcji i/lub określania flag we właściwościach żądania klienta mają zastosowanie następujące elementy.

  • Jeśli notruncation parametr jest ustawiony, a dowolny z truncationmaxsize, truncationmaxrecordslub query_take_max_records jest również ustawiony — notruncation jest ignorowany.
  • Jeśli truncationmaxsizeparametr truncationmaxrecords i/lub query_take_max_records są ustawiane wiele razy , ma zastosowanie niższa wartość dla każdej właściwości.

Limit pamięci używanej przez operatory zapytań (E_RUNAWAY_QUERY)

Usługa Kusto ogranicza pamięć, z jaką każdy operator zapytań może korzystać w celu ochrony przed zapytaniami "ucieczki". Ten limit może zostać osiągnięty przez niektórych operatorów zapytań, takich jak join i summarize, które działają, przechowując znaczne dane w pamięci. Domyślnie limit wynosi 5 GB (na węzeł klastra) i można go zwiększyć, ustawiając opcję maxmemoryconsumptionperiteratorżądania :

set maxmemoryconsumptionperiterator=68719476736;
MyTable | summarize count() by Use

Po osiągnięciu tego limitu jest emitowany częściowy błąd zapytania z komunikatem zawierającym tekst E_RUNAWAY_QUERY.

The ClusterBy operator has exceeded the memory budget during evaluation. Results may be incorrect or incomplete E_RUNAWAY_QUERY.

The DemultiplexedResultSetCache operator has exceeded the memory budget during evaluation. Results may be incorrect or incomplete (E_RUNAWAY_QUERY).

The ExecuteAndCache operator has exceeded the memory budget during evaluation. Results may be incorrect or incomplete (E_RUNAWAY_QUERY).

The HashJoin operator has exceeded the memory budget during evaluation. Results may be incorrect or incomplete (E_RUNAWAY_QUERY).

The Sort operator has exceeded the memory budget during evaluation. Results may be incorrect or incomplete (E_RUNAWAY_QUERY).

The Summarize operator has exceeded the memory budget during evaluation. Results may be incorrect or incomplete (E_RUNAWAY_QUERY).

The TopNestedAggregator operator has exceeded the memory budget during evaluation. Results may be incorrect or incomplete (E_RUNAWAY_QUERY).

The TopNested operator has exceeded the memory budget during evaluation. Results may be incorrect or incomplete (E_RUNAWAY_QUERY).

Jeśli maxmemoryconsumptionperiterator parametr jest ustawiany wiele razy, na przykład we właściwościach żądania klienta i przy użyciu set instrukcji, stosowana jest niższa wartość.

Dodatkowy limit, który może spowodować E_RUNAWAY_QUERY częściowe niepowodzenie zapytania, jest ograniczeniem maksymalnego skumulowanego rozmiaru ciągów przechowywanych przez jednego operatora. Tego limitu nie można zastąpić za pomocą powyższej opcji żądania:

Runaway query (E_RUNAWAY_QUERY). Aggregation over string column exceeded the memory budget of 8GB during evaluation.

Po przekroczeniu tego limitu najprawdopodobniej odpowiedni operator zapytania to join, summarizelub make-series. Aby obejść limit, należy zmodyfikować zapytanie tak, aby używało strategii zapytania mieszania . (Prawdopodobnie poprawi to również wydajność zapytania).

We wszystkich przypadkach E_RUNAWAY_QUERYprogramu dodatkowa opcja (poza zwiększeniem limitu przez ustawienie opcji żądania i zmiana zapytania na użycie strategii mieszania) polega na przełączeniu się na próbkowanie. W dwóch poniższych zapytaniach pokazano, jak wykonać próbkowanie. Pierwsze zapytanie to próbkowanie statystyczne przy użyciu generatora liczb losowych. Drugie zapytanie to próbkowanie deterministyczne, wykonywane przez wyznaczanie wartości skrótu kolumny z zestawu danych, zwykle niektóre identyfikatory.

T | where rand() < 0.1 | ...

T | where hash(UserId, 10) == 1 | ...

Limit pamięci na węzeł

Maksymalna ilość pamięci na zapytanie na węzeł to kolejny limit używany do ochrony przed zapytaniami "ucieczki". Ten limit reprezentowany przez opcję max_memory_consumption_per_query_per_nodeżądania ustawia górną granicę ilości pamięci, która może być używana w jednym węźle dla określonego zapytania.

set max_memory_consumption_per_query_per_node=68719476736;
MyTable | ...

Jeśli max_memory_consumption_per_query_per_node parametr jest ustawiany wiele razy, na przykład we właściwościach żądania klienta i przy użyciu set instrukcji, stosowana jest niższa wartość.

Jeśli zapytanie używa summarizeoperatorów , lub make-seriesjoin, możesz użyć strategii zapytania mieszania, aby zmniejszyć wykorzystanie pamięci na jednej maszynie.

Limit czasu wykonywania

Limit czasu serwera to limit czasu po stronie usługi, który jest stosowany do wszystkich żądań. Limit czasu uruchamiania żądań (zapytania i polecenia zarządzania) jest wymuszany w wielu punktach w usłudze Kusto:

  • biblioteka klienta (jeśli jest używana)
  • punkt końcowy usługi, który akceptuje żądanie
  • aparat usługi, który przetwarza żądanie

Domyślnie limit czasu jest ustawiony na cztery minuty dla zapytań i 10 minut dla poleceń zarządzania. Tę wartość można zwiększyć w razie potrzeby (ograniczona o jedną godzinę).

  • Różne narzędzia klienckie obsługują zmianę limitu czasu w ramach ustawień globalnych lub na połączenie. Na przykład w narzędziu Kusto.Explorer użyj opcji narzędzi>* >Limitczasu połączenia >serwera zapytań.
  • Programowo zestawy SDK obsługują ustawianie limitu czasu za pośrednictwem servertimeout właściwości. Na przykład w zestawie SDK platformy .NET jest to wykonywane za pomocą właściwości żądania klienta, ustawiając wartość typu System.TimeSpan.

Uwagi dotyczące limitów czasu

  • Po stronie klienta limit czasu jest stosowany z tworzonego żądania do momentu, gdy odpowiedź zacznie docierać do klienta. Czas potrzebny do odczytania ładunku z powrotem na kliencie nie jest traktowany jako część limitu czasu. Zależy to od tego, jak szybko obiekt wywołujący pobiera dane ze strumienia.
  • Ponadto po stronie klienta wartość rzeczywistego limitu czasu jest nieco wyższa niż wartość limitu czasu serwera żądana przez użytkownika. Ta różnica polega na umożliwieniu opóźnień sieci.
  • Aby automatycznie użyć maksymalnego dozwolonego limitu czasu żądania, ustaw właściwość norequesttimeout żądania klienta na true.

Uwaga

Zobacz ustawianie limitów czasu, aby zapoznać się z przewodnikiem krok po kroku dotyczącym ustawiania limitów czasu w internetowym interfejsie użytkownika usługi Azure Data Explorer, Kusto.Explorer, Kusto.Cli, Power BI i podczas korzystania z zestawu SDK.

Limit użycia zasobów procesora CPU zapytań

Usługa Kusto umożliwia uruchamianie zapytań i używanie jak najwięcej zasobów procesora CPU w klastrze. Próbuje wykonać sprawiedliwe działanie okrężne między zapytaniami, jeśli jest uruchomionych więcej niż jeden. Ta metoda daje najlepszą wydajność dla funkcji zdefiniowanych przez zapytanie. Czasami możesz ograniczyć zasoby procesora CPU używane dla określonego zapytania. Jeśli na przykład uruchamiasz "zadanie w tle", system może tolerować wyższe opóźnienia, aby zapewnić współbieżne zapytania wbudowane o wysoki priorytet.

Usługa Kusto obsługuje określanie dwóch właściwości żądania podczas uruchamiania zapytania. Właściwości są query_fanout_threads_percent i query_fanout_nodes_percent. Obie właściwości są liczbami całkowitymi, które domyślnie są wartością maksymalną (100), ale mogą zostać zmniejszone dla określonego zapytania do innej wartości.

Pierwszy, query_fanout_threads_percent, steruje współczynnikiem wentylatora do użycia wątku. Po ustawieniu tej właściwości 100%klaster przypisze wszystkie procesory CPU w każdym węźle. Na przykład 16 procesorów CPU w klastrze wdrożonym w węzłach usługi Azure D14. Gdy ta właściwość jest ustawiona na 50%, zostanie użyta połowa procesorów CPU itd. Liczby są zaokrąglane do całego procesora CPU, więc można bezpiecznie ustawić wartość właściwości na 0.

Drugi, query_fanout_nodes_percent, steruje liczbą węzłów zapytań w klastrze do użycia na operację dystrybucji podzapytania. Działa w podobny sposób.

Jeśli query_fanout_nodes_percent lub query_fanout_threads_percent są ustawiane wiele razy, na przykład w obu właściwościach żądania klienta i przy użyciu set instrukcji — mniejsza wartość dla każdej właściwości ma zastosowanie.

Ograniczanie złożoności zapytań

Podczas wykonywania zapytania tekst zapytania jest przekształcany w drzewo operatorów relacyjnych reprezentujących zapytanie. Jeśli głębokość drzewa przekroczy próg wewnętrzny, zapytanie jest uznawane za zbyt złożone do przetwarzania i zakończy się niepowodzeniem z kodem błędu. Błąd wskazuje, że drzewo operatorów relacyjnych przekracza limity.

W poniższych przykładach przedstawiono typowe wzorce zapytań, które mogą spowodować przekroczenie tego limitu i niepowodzenie zapytania:

  • długa lista operatorów binarnych, które są połączone ze sobą. Na przykład:
T 
| where Column == "value1" or 
        Column == "value2" or 
        .... or
        Column == "valueN"

W tym konkretnym przypadku ponownie napisz zapytanie przy użyciu in() operatora .

T 
| where Column in ("value1", "value2".... "valueN")
  • Zapytanie, które ma operator unii, który uruchamia zbyt szeroką analizę schematu, szczególnie że domyślnym rozwiązaniem unii jest zwrócenie schematu unii "zewnętrznej" (co oznacza , że dane wyjściowe będą zawierać wszystkie kolumny tabeli bazowej).

Sugestią w tym przypadku jest przejrzenie zapytania i zmniejszenie kolumn używanych przez zapytanie.