„Something went wrong” – mój ulubiony generyczny komunikat błędu 🙂 Dzisiejszy wpis nie będzie o tego typu tajemniczych komunikatach ze strony Elasticsearcha. Na szczęście ten rzuca znacznie dokładniejsze informacje. Dziś będzie o pomyłkach jakie popełniłem podczas tworzenia zapytań w pierwszym projekcie wykorzystującym Elasticsearcha. Niestety moje pomyłki nie kończyły się błędami. Kończyły się czymś znacznie gorszym – jakże niechcianymi spowolnieniami wyszukiwania. Będzie to swoiste „lessons learned” z punktu widzenia programisty.

Cykl artykułów "Uczymy się Elasticsearch"

Ten wpis jest częścią cyklu, w którym staram się pokazać w jaki sposób możesz zbudować przyjazną dla użytkownika wyszukiwarkę, wykorzystując do tego celu potężny silnik wyszukiwania jakim jest Elasticsearch.

Do tej pory w ramach cyklu ukazały się następujące artykuły:

  1. instalacja, uruchomienie i pierwsze zapytanie
  2. kilka słów na temat Elastic Stack
  3. przydatne narzędzia
  4. indeks odwrócony Apache Lucene
  5. wyszukiwanie pełnotekstowe
  6. trafność
  7. przygotowanie tekstu do optymalnego wyszukiwania
  8. coś poszło nie tak, czyli seria moich fackupów
  9. zaczarowany zakreślacz
  10. ...

Co może spowolnić Twoje zapytania?

Nie będę przytaczał dziś bardzo szczegółowych analiz tego o ile (mili)sekund spadła wydajność konkretnych zapytań w poszczególnych przypadkach. Nie o to tu chodzi, szczególnie, że czasy zapytań są zależne od wielu czynników (np. od wydajności, czy obciążenia maszyny). Niemniej jednak wymienię miejsca, w których ja się naciąłem, więc kiedy Tobie trafią się spowolnienia, to będziesz wiedzieć gdzie szukać potencjalnych winowajców.

Fuzinness

piątej części cyklu napomknąłem o możliwościach ustawienia fuzzy matchingu w niektórych zapytaniach. Wszystko dzięki odpowiedniemu użyciu parametru fuzziness. Ów parametr wykorzystywany jest również przez dedykowany rodzaj zapytania o nazwie Fuzzy Query. Jeżeli zerkniesz w jego dokumentację, to zobaczysz w niej przejrzyste ostrzeżenie, że zapytania tego typu mogą być ciężkie w momencie gdy ustawimy parametr prefix_length na zero. Niestety zero jest jego domyślną wartością, więc pominięty może sprawiać kłopoty (w pewnych szczególnych okolicznościach).

Highlighting

Jeżeli w oparciu o Elasticsearch budujesz wyszukiwarkę dla użytkowników, to dostarcza on kilku ciekawych ficzerów, które mogą się im spodobać. Jednym z nich jest highlighting, czyli możliwość pokazania użytkownikowi dlaczego akurat dany dokument został wyszukany. W ogólności działa to naprawę sprawnie. Spowolnienie występuje praktycznie zawsze, ale w większości przypadków nie jest odczuwalne, gdyż rezultaty z highlightingiem w gorszych przypadkach wrócą do nas w kilkadziesiąt lub kilkaset milisekund (w porównaniu do kilku, kilkudziesięciu milisekund bez highlightingu). Mimo tego zdarzyło mi się niestety, że zapytania z highlightingiem trwały po kilka, kilkanaście sekund (nawet przy wybraniu najbardziej efektywnych algorytmów), podczas gdy te same zapytania bez zakreślania zamykały się maksymalnie w jednej sekundzie.

Wrzucanie zbyt dużej ilości danych w jedno pole

W moim przypadku gorszą wydajność powyższych dwóch narzędzi nie powodował sam fakt ich użycia, ale to na jakich danych działały. Projekt, nad którym pracowałem wykorzystywał Elasticsearcha do pełnotekstowego wyszukiwania po zawartości plików. W pewnym momencie odkryłem, że w jedno pole zawierające całą treść danego dokumentu lecą napisy o długości kilkudziesięciu milionów znaków. Dopiero po tym fakcie trafiłem na informację, że highlighting może się pocić przy „większych tekstach” i że w kolejnej wersji analiza takich pól pod kątem zakreślania będzie ograniczona do miliona znaków.

Ograniczenie długości wrzucanej treści do miliona znaków pomogła znacząco, a ograniczenie do 100 tysięcy sprawiło, że przestałem narzekać na highlighting i fuzziness 🙂 Co więcej ten zabieg przyspieszył wszystkie zapytania. Również te, które nie wykorzystywały „problematycznego” zaznaczania, czy przybliżonego dopasowywania. Dodatkowo mimo nałożonego ograniczenia na długość danych i tak 98% plików lądowało w Elasticsearchu w całości.

Jeżeli więc masz za zadanie wyszukiwać pełnotekstowo w dużych plikach i zauważysz podobne problemy, to rozważ podzielenie treści i wrzucenie jej w kilka pól lub pomyśl o jakiejś innej alternatywie.

Przeszukiwanie zbyt dużej ilości pól

Kolejnym błędem, który można również nieświadomie popełnić jest wyszukiwanie w zbyt dużej liczbie pól na raz. W tym przypadku rozmiar danych w tych polach nie ma dużego znaczenia. Mogą być naprawdę krótkie. O co tu chodzi? Niektóre z zapytań, jak na przykład wspomniane przeze mnie wcześniej zapytanie multi_match, pozwalają określić listę pól, w których ma być wyszukiwane zadane wyrażenie. Przesadzenie z ową listą może być przyczyną zauważalnych spowolnień. U mnie było.

Wrzucanie śmieci do indeksu

Innym problemem może być nieodpowiednie przygotowanie tekstu do wyszukiwania. Szerzej o tym pisałem w poprzednim wpisie. Generalnie chodzi o to, że jeżeli będziemy wrzucać do indeksu wszystko co nam pod rękę podleci w zupełnie nieprzemyślanej formie, to nie przyniesie to nikomu pożytku. Prawdopodobnie trafią tam nadmiarowe fragmenty, które po pierwsze niepotrzebnie napompują rozmiar naszego pola, a po drugie będą wymagały analizy tak samo jak i dane właściwe. Wszystko to sprawi, że Elasticsearch będzie musiał się przyjrzeć większej ilości danych, które w żaden sposób nie pomogą wynikom wyszukiwania.

Zbyt skomplikowane zapytania

Elasticsearch dostarcza długą listę rodzajów zapytań (zarówno pełnotekstowych, jak i różnych innych). I nie jest tak, że w jednym odpytaniu serwera jesteśmy ograniczeni do użycia tylko jednego z nich. Na wspomnianej liście znajdują się również zapytania logiczne pozwalające łączyć, składać i budować skomplikowane „podzapytania”. I tu powinna zapalić Ci się lampeczka. Jeżeli można kombinować, to można również… przekombinować 🙂 You have been warned!

Przekombinowanie z konfiguracją zapytań

Przekombinować można nie tylko ze składaniem mniejszych zapytań w złożone drzewka, ale i podczas konfigurowania poszczególnych z nich. Większość zapytań dostarcza obszerną ilość parametrów, dzięki którym jesteśmy w stanie ustawić wszystko pod siebie. Czasem zamiast chodzić po omacku warto jednak zaufać domyślnym wartościom ustawionym przez twórców silnika. Ich lata pracy i doświadczenia z różnymi przypadkami pozwoliły wyważyć im co będzie najlepsze w znacznej większości sytuacji. I powiem Ci, że jest duża szansa, że Ty również znajdujesz się w tej puli. Polecam więc zacząć tak domyślnie jak się tylko da, skonfrontować rezultaty z oczekiwaniami użytkowników i dopiero wtedy dostrajać dalej.

Co jeszcze?

Mimo relatywnie krótkiego stażu pracy z Elasticsearchem wydaje mi się, że przedstawiona powyżej lista potknięć jest całkiem obszerna. Wierzę, że będzie dobrym punktem wyjścia do sprawdzenia gdzie mogą leżeć potencjalne przyczyny spowolnień Twojego wyszukiwania. Jeżeli mimo wszystko byłoby Ci mało, to możesz dodatkowo zajrzeć do artykułu Tune for search speed, który prezentuje więcej potencjalnych rzeczy, na które warto zwrócić uwagę.

Zawsze istnieje alternatywa

To czego nauczyły mnie początkowe tygodnie pracy z Elasticsearchem mogę zawrzeć w jednym zdaniu: „zawsze istnieje alternatywa”. No może „zawsze” to zbyt mocne słowo, ale dla większości problematycznych przypadków można znaleźć alternatywne rozwiązanie, które będzie „tańsze” pod względem pamięci i czasu, a które przyniesie zbliżenie satysfakcjonujące rezultaty. Wprawa w znajdowaniu od razu tego co dobre przyjdzie z czasem.

Kluczowe znaczenie ma również przemyślenie tematu oraz konsultacja z użytkownikami jak to wszystko ma działać i co ich tak naprawdę zadowoli. Teraz już wiem, że proste rzeczy, które Elasticsearch dostarcza bez konieczności większego dostrajania będą w dużej mierze naprawdę satysfakcjonującym rozwiązaniem. Może okazać się, że wyciąganie najcięższych dział wcale nie będzie konieczne.

To tyle na teraz. A jak było u Ciebie? Pamiętasz jakieś ciekawe przypadki, które wpływały na wydolność Twojego Elasticsearcha? Z ogromnym zainteresowaniem przeczytam o nich w komentarzach, więc śmiało. Nie krępuj się 🙂

Bądź na bieżąco!

Podobają Ci się treści publikowane na moim blogu? Nie chcesz niczego pominąć? Zachęcam Cię do subskrybowania kanału RSS, polubienia fanpage na Facebooku, zapisania się na listę mailingową:




Uwaga! Jeżeli w ciągu 24-godzin od zapisania się na listę mailingową nie otrzymasz wybranego przez siebie prezentu to skontaktuj się ze mną.

Zgoda? Zapisując się do newslettera wyrażasz zgodę na przesyłanie Ci starannie wyselekcjonowanych informacji marketingowych. Powyższe dane są przechowywane w systemie MailChimp i nie są udostępniane nikomu więcej.

lub śledzenia mnie na Twitterze. Generalnie polecam wykonanie wszystkich tych czynności, bo często zdarza się tak, że daną treść wrzucam tylko w jedno miejsce. Zawsze możesz zrobić to na próbę, a jeśli Ci się nie spodoba – zrezygnować :)

Chcesz więcej? W takim razie zapraszam Cię do dołączenia do powiązanych grup na Facebooku, gdzie znajdziesz dodatkowe informacje na poruszane tutaj tematy, możesz podzielić się własnymi doświadczeniami i przemyśleniami, a przede wszystkim poznasz ludzi interesujących się tą samą tematyką co Ty.

W grupie Programista Na Swoim znajdziesz wiele doświadczonych osób chętnych do porozmawiania na tematy krążące wokół samozatrudnienia i prowadzenia programistycznej działalności gospodarczej. Vademecum Juniora przeznaczone jest zaś do wymiany wiedzy i doświadczeń na temat życia, kariery i problemów (niekoniecznie młodego) programisty.

1 000 000 zł

Milion złotych. Tak, milion złotych. Milion złotych to cel, który sobie postawiłem jakiś czas temu. Chcę zarobić milion złotych na tym blogu. Do tej pory zebrało się 37 102,41 zł, więc jak widzisz jest już co pokazać, ale do celu nadal sporo brakuje. Jeszcze nie wiem do końca jak, ale to zrobię. Na pewno nigdy nie będę pobierał żadnych opłat za dostęp do treści, bo tymi chcę się po prostu dzielić.

Wysoko ponad ten milion stawiam na szerzenie wiedzy i dotarcie do jak największej liczby osób. I tu mam prośbę do Ciebie: jeśli uważasz, ten artykuł za wartościowy, to udostępnij go proszę swoim znajomym. Przy lewej lub dolnej (na małych wyświetlaczach) krawędzi ekranu znajdziesz przyciski, które Ci to ułatwią. Jeżeli ich nie widzisz, to najprawdopodobniej zostały zablokowane przez Twój program do blokowania reklam. Niezależnie od tego, czy prześlesz ten wpis dalej, czy nie, to ja i tak dziękuję Ci serdecznie za doczytanie do tego miejsca! Do przeczytania niebawem.

PS. Jeśli mój blog przypadł Ci do gustu tak bardzo, że chciał(a)byś mi się w jakiś sposób odwdzięczyć, to mam dla Ciebie kilka ciekawych propozycji, z których możesz skorzystać. Szczególnie gorąco zachęcam do wsparcia poprzez serwis Patronite, ale jeżeli zdecydujesz się na którąkolwiek z wymienionych opcji, to serdecznie Ci za to DZIĘKUJĘ!

Picture Credits
Tribute to Patrons