Friday, September 15th, 2006...12:41 am

Wydajność zapytań do katalogu Active Directory

Jump to Comments

W zasadzie trudno jest napisać dokładny przewodnik jak tworzyć wydajne zapytania do Active Directory, na wydajność takiego zapytania składa się wiele czynników. Można jednak pokusić się o zebranie kilku uwag na ten temat co i właśnie czynię.

fActive Directory jest oparte na katalogu LDAP, który to został stworzony w celu szybkiego i łatwego dostępu do zasobów usług katalogowych. Wszelkie operacje wyszukiwania, tworzenia, usuwania obiektów w katalogu sprowadzają się do wykonania odpowiednich operacji na katalogu. Z tych wszystkich operacji nawięcej wykonywanych jest różnego rodzaju operacji wyszukujących dane w katalogu. Operacje te przy źle zoptymalizowanych zapytaniach mogą stanowić duże obciążenie dla serwera katalogu Active Directory.

Jak możemy zdefiniować optymalne zapytanie?  Przyjmijmy że jest to takie zapytanie, w którym przetwarzana jest minimalna liczba wymaganych obiektów, a im więcej z nich odpowiada warunkom zapytania tym lepszej jakości jest nasz filtr. Oczywiście to nie zawsze jest idealne kryterium, ale zbliża nas do optymalnej wydajności, tworząc sytuację w której nie wykonujemy zapytań na wszytkich obiektach w domenie, tylko po to żeby znaleźć pojedynczy obiekt.

Zbudowanie optymalnych zapytań dla naszych potrzeb w aplikacjach lub skryptach może wymagać kilku prób z różnego rodzajami filtrów ale istnieje kilka podstawowych zasad których warto sie trzymać.

1. Wybór miejsca rozpoczęcia zapytania 

Każde z zapytań kierowanych do serwera LDAP ma zdefiniowane (w sposób jawny lub niejawny) trzy elementy:

  • search root: czyli miejsce poczÄ…tku wyszukiwania,
  • scope: czyli zakres w jakim zostanie przeprowadzona operacja wyszukiwania,
  • filtr: czyli kryteria wedÅ‚ug których zostanÄ… wybrane okreÅ›lone obiekty.

Dodatkowo dla zapytania określona może być również lista atrybutów obiektów, które zostaną zwrócone.

Często spotykanym przypadkiem w wielu aplikacjach korzystających z Active Directory jest rozpoczynanie zapytania w ścieżce głównej domeny, czyli ustawienie search root na DC=Domena,DC=PL. Efektem tego, przy odpowiednio ustawionym zakresie zapytania jest przeważnie przeszukanie wszystkich obiektów w ramach domeny. Na pierwszy rzut oka wydaje się to już nie być szczęśliwym rozwiązaniem, szczególnie w przypadku zapytań mających zwrócic niezbyt duża liczbę obiektów.

Tip: Starajmy się więc jeżeli jest to tylko możliwe doprecyzować miejsce rozpoczęcia wykonywania zapytania do określonych jednostek organizacyjnych lub framgentów katalogu, tak aby unikać przeszukiwania całości drzewa domeny, tylko po to aby znaleźć kilku użytkowników w jednym z OU.

2. Jak głęboko w katalogu będzie wykonane zapytanie 

Dla każdego zapytania LDAP możemy określić jeden z trzech zakresów:

  1. subtree: zapytanie zostanie wykonane rozpoczynając od miejsca określonego przez search base dla wszystkich obiektów znajdujących sie w tym miejscu katalogu i wszystkich obiektów potomnych w strukturze katalogu. W przypadku ustalenia miejsca rozpoczęcia wyszukiwania na określony kontener, przeszukane zostaną obiekty w tym kontenerze oraz we wszytskich kontenerach znajdujących się poniżej tego kontenera.
  2. one level: zapytanie zostanie wykonane dla obiektów tylko w tym miejscu struktury katalogu, które zostało określone. Jeżeli jako podstawa zapytania określone zostanie pojedyncze OU to operacja wykonana zostanie tylko na obiektach znajdujących się w tym OU.
  3. base: oznacza ze zapytanie wykonane zostanie tylko dla obiektu który został wskazany jako podstawa zapytania. Do czego jest to przydatne? W szczególności do tego aby uzyskać z katalogu dla wskazanego obiektu wartości atrybutów konstruowanych i w kilku podobnych przypadkach.

Jak widać określenie zakresu zapytania może mieć znaczący wpływ na liczbę przetwarzanych w zapytaniu obiektów, dlatego warto czasami pomysleć czy zamiast wskazania zakresu jako subtree nie warto w tym wypadku użyć chociażby one level.

Tip:  W przypadku zapytań z użyciem zakresu subtree zawsze starajmy się jak najbardziej przybliżyć podstawę wyszukiwania do lokalizacji obiektów, których poszukujemy. Jeżeli wiemy że w naszym katalogu obiekty użytkowników tworzone są w określonym OU to rozpocznijmy wyszukiwanie właśnie od tego OU, nie zaś od podstawy domeny. W przypadku zapytań kierowanych do obiektów w konkretnym kontenerze użyjmy zakresu one level zamiast subtree. Efekt będzie ten sam a unikniemy przeszukiwania struktury OU.

3. Używanie optymalnych, lub zbliżonych do optymalnych filtrów w zapytaniach 

Chyba najcześciej w naszych zapytaniach szukamy danych dotyczących kont użytkowników. Większość osób piszących skrypty w tym celu posługuję się filtrem LDAP:

(objectClass=user)

Filtr ten jest niezbyt poprawny z conajmniej dwóch powodów:

  • objectClass nie jest atrybutem indeksowanym, co znaczÄ…co pogarsza czas wyszukiwania obiektów.
  • w przypadku użycia atrybutu objectClass jako parametru wyszukiwaniw uwzglÄ™dniane sÄ… również wszystkie obiekty potomne tej klasy, czyli na przykÅ‚ad dla klasy user zwrócone zostanÄ… również obiekty komputerów (klasa computer jest klasÄ… potomnÄ… user).

O wiele lepszy w tym przypadku wydaje się być atrybut objectCategory który jest atrybutem indeksowanym, jednak wiele obiektów różnych klas może posiadać tą samą wartość objectCategory. Chociażby obiekty klasy user oraz contact są oba obiektami kategorii Person.

idealnym połączeniem w tym przypadku jest więc użycie połączenia atrybutów objectClass i objectCategory w ramach pojedynczego filtru:

(&(objectClass=user)(objectCategory=Person)).

Innym przykÅ‚adem filtru LDAP mocno obciążajÄ…cego katalog jest zapytanie z użyciem znaku maski ‘*’ znajdujÄ…cego siÄ™ na poczÄ…tku wyszukiwanego ciÄ…gu, czyli na przykÅ‚ad:

(&(objectClass=user)(objectCategory=Person)(samAccountName=*nowak)).

Wynika to z tego że serwer Active Directory nie jest w stanie korzystać ze standardowego mechanizmu indeksów w przypadku gdy znak maski znajduje się na początku wyszukiwanego ciągu znaków. W Windows 2003 wprowadzony został specjalny rodzaj indeksu (tuple) wspomagający tego rodzaju wyszukiwanie, ale nie wszystkie atrybuty z niego korzystają.

Kolejnym przykÅ‚adem zapytania, które może znaczÄ…co wpÅ‚ynąć na wydajność jest zapytanie z użyciem znaku negacji ‘!’. Powód jak powyżej – nie zawsze uda siÄ™ w przypadku tego typu zapytaÅ„ skorzystać z indeksów atrybutów, co wymusza drogie przeszukiwanie katalogu.

Temat konstruowania efektywnych filtrów LDAP możnaby ciągnąć dłużej i może uda mi się napisać osobny kawałek tesktu na blogu temu poświęcony. Te trzy elementy które wymieniłem są najczęściej spotykanymi błędami wpływającymi na wydajność zapytań, które udało mi się zauważyć wiele razy w różnego rodzaju skryptach i oprogramowaniu.

——————–

W zasadzie te trzy punkty pozwalają nam na kontrolowanie podstawowych elementów zapytania. W przypadku optymalizacji zapytań dodatkową rolę mogą odgrywać też takie elementy jak lista zwracanych atrybutów, typ atrybutów użytych w zapytaniach itp.

Active Directory posiada mechanizm pozwalający nam na łatwy dostęp do danych statystycznych dotyczących wykonywanych zapytań. W przypadku gdy chcemy testować dokładność i wydajność naszych zapytań warto się tymi mechanizmami posłużyć. Dostęp do nich możemy uzyskać na różne sposoby, na przykład testując nasze zapytania z użyciem narzędzia adfind i używając przełącznika -stat (i pokrewnych, polecam adfind -??? ).

Inny sposób pozwalający na przetestowanie naszych zapytań kierowanych do DC bezpośrednio ze skrytpu czy aplikacji to użycie klucza rejestru 15 Field Engineering utworzonego w gałęzi HKLM\SYSTEM\CurrentControlSet\Services\NTDS\Diagnostics. Klucz ten pozwala na logowanie w dzienniku zdarzeń dokładnych statystyk dotyczących zapytań LDAP kierowanych do kontrolera domeny. Klucz ten działa również dla instancji ADAM. Dokładny opis logowania i diagnozowania zapytań LDAP z użyciem tej metody można znaleźć na stronach ActiveDir.org. Jedną z użytecznych możliwości dostępnych w ramach tego mechanizmy jest możliwość zdefiniowania parametrów, przy których zapytanie uznawane jest za nieefektywne i zostanie zalogowane w dzienniku zdarzeń.

Jeżeli zainteresował Was ten klucz rejestru, to chociaż nie jest to bezpośrednio związane z tematem tego postu może warto zajrzeć do jednego z postów na blogu Jorge, w którym zebrał on wpisy rejestru związanie z diagnostyką i logowaniem.

Leave a Reply