Wpisy z Maj, 2008

Ganglib pomoże wyszukiwać?

Wyszukiwanie pełnotekstowe nie jest trywialne, nie istnieje jego jedyne dobre rozwiązanie.

Widziałem już różne rozwiązania:

  • LIKE %%,

  • FULL TEXT w MyISAM,

  • Lucene,

  • Sphinx Search.

Często stosowane są strategie kolejnego przechodzenie przez powyższe.

  1. Mamy 100 – 200 artykulów? Nie jest problemem uzycie standardu SQL i składni LIKE – nie wymaga to od nas żadnej pracy.

  2. Jeśli to przestaje wystarczać, możemy dodac indeks FULL TEXT (o ile korzystamy z tabel MyISAM w mySQL) – wystarczy drobna modyfikacja kwerend (zamiast LIKE, MATCH AGAINST …). FULL TEXT działa bardzo szybko, niepozbawiony jest jednak wad. Przy tabelach obciążonych dużą ilością modyfikacji danych całe rozwiązanie zaczyna niebezpiecznie zwalniać (indeks przy każdej zmianie musi być przebudowywany)…

  3. Lucene i Sphinx (jest szybszy) to wyjścia zdecydowanie lepsze – które nie tracą na szybkosći wraz ze wzrostem ilości przetwarzanych danych i nie są zależne od charakteru operacji.

Niestety w tym momencie przestajemy korzystać z bazy danych a zwracamy się do dedykowanego indeksu wyszukiwania. Co za tym idzie musimy dosyć istotnie zmodyfikować modele pobierania danych.

Czy nie byloby pięknie napisać zapytania raz a wymieniać tylko mechanizmy które je przetwarzają.

Taki scenariusz jest możliwy przy wykorzystaniu naszego gangliba.

Proste zapytanie: $qr->select(‘*’)->from(‘articles’)->like(‘content’,’%napis%’);
  1. Początkowo może być wykonywane bezpośrednio na bazie danych korzystając ze strategii opartych na PDO.

  2. Jeśli napotkamy problem, możemy zmodyfikować strategię lub dialekt sql (budujący zapytania) aby zamiast LIKE wstawiał do zapytań MATCH AGAINST … Dokonujemy zmiany tylko w jednym miejscu, zmieniając kod kilku linijek kodu.

  3. Jeśli chcemy przenieść się na dedykowany indeks wyszukiwawczy – wystarczy, że utworzymy nową strategię (Div_Db_Distributor_Strategy_Sphinx? ;) ) i poprosimy dystrybutor danych aby z niej korzystał. W kodzie strategii definiujemy w jaki sposób ma być obsługiwana klauzula LIKE – tj. tłumaczona na odpowiednei wywołanie API sphinxa.

To wszystko :-)

ps. Korzystając ze sphinxa możemy emulować wykrozystanie wielu klauzul SQL nie tylko LIKE – np. ORDER BY, GROUP BY, WHERE (po wartościach liczbowych) – daje to naprawdę duże możliwości. Możemy przecież połączyć w jednej strategii sphinxa + pobieranie danych o zwróconych przezeń dokumentach z bazy danych i/lub cache.

Jak efektywnie wyszukiwać

 Od dawna używam engine wyszukiwania Sphinx Search (http://sphinxsearch.com) – wyniki uzyskiwane przy jego wykorzystaniu robią spore wrażenie.

Z moich doświadczeń przy blogfrogu – przeszukanie 500 000 tyś. wpisów (zaciągniętych z RSS + pełna treść wpisu ze strony HTML) zajmuje aktualnie ok. 0.02 s. Prze indeksowanie wszystkich wpisów, to ok. 25 minut pracy na jednej maszynie.

To, że wyniki te są dużo lepsze niż wszystkich konkurentów razem wziętych to jedna sprawa dla której warto zwrócić na to rozwiązanie uwagę.

Moim zdaniem ciekawszą i dającą większe możliwości funkcjonalnością jest wprowadzone niedawno wyszukiwanie rozproszone. Sphinx od wersji 0.98 potrafi automatycznie wysyłać zapytania jednocześnie do wielu serwerów – które przeszukują fragmenty indeksu. Wyniki są automatycznie scalane, usuwane są duplikaty.

W tym momencie zaczęło mi świtać….

Testy które przeprowadzano wskazują, że Sphinx bardzo często działa dużo szybciej nie tylko przy przeszukiwaniu pełnotekstowym, ale także przy wykonywaniu zapytań odnośnie atrybutów liczbowych dokumentów (np. zapytania ala SELECT … WHERE ID = 234).

Wydajność rozproszonych indeksów Sphinxa a wydajność rozproszonych baz danych MySQL – bez porównania.

Zaczyna to trochę w sposobie działania, przypominać BigTable – z tą różnicą ;) że sphinx nie potrafi przechowywać danych innych od liczbowych. Dlatego działa tak strasznie szybko.

Sphinx nie jest rozproszoną bazą danych, ale przy użyciu odpowiednich strategii cacheowania i składowania danych można pomyśleć o jego użyciu nawet w tej roli.

Pomysłów jest wiele.

Chciałbym aby nasz Ganglib wkrótce wzbogacił się wkrótce o jego obsługę.

 

Kto pokona erlanga?

Wydajne używanie wielowątkowości staje się coraz bardziej ważne przy tworzeniu aplikacji internetowych – np. wykorzystać siłę mechanizmów takich jak BigTable, SimpleDb.

W tej sytuacji warto przyjrzeć się bliżej językowi erlang .

Erlang został stworzony w firmie Ericsson na potrzeby programowania systemów czasu rzeczywistego wykorzystywanych w telekomunikacji (np. central telefonicznych). Aplikacje napisane w erlangu nie mają sobie równych – chociażby serwer www YAWS (w teście obsłużył do 80 000 jednoczesnych połączeń, podczas gdy Apache padł przy … 4 000) czy serwer Jabbera ejabberd.

Jeśli erlang jest tak niesamowicie wydajny to dlaczego jest tak niesamowicie niepopularny?

Erlang nie jest zwykłym językiem programowania jak Ruby, PHP czy Java. Erlang jest językiem funkcyjnym .

Kod w nim jest bardzo krótki ale trzeba się przestawić:)

Przykład?

 %% fancier project queries

    {ok, [Yaws4]} = language:projects_where(

          Erlang, "name='Yaws'"),

    true = Yaws4 == Yaws1,

    {ok, [Yaws5]} = language:projects_with(

          Erlang, "limit 1"),

    true = Yaws4 == Yaws5,

Dobra książka o erlangu.

Skalowanie aplikacji … jest proste?

Skalowanie aplikacji – w sensie, warstwy serwerów aplikacji  – jeśli mamy dobry projekt nie powinno być trudne. Trochę gorzej ma się sprawa skalowania bazy danych (swoją drogą najczęstszego wąskiego gardła aplikacji)- ale o tym problemie opowiem w najbliższych postach.

Dzisiaj ogólnie o technikach skalowania środowiska aplikacji.

Jeśli nasz kod jest już dobrze napisany i zoptymalizowany nie pozostaje nam nic więcej jak rozbudowywać bazę serwerów na których nasza aplikacja pracuje

Generalnie wyróżniamy dwa podejścia do problemu:

  •  skalowanie pionowe – tutaj sprawa jest prosta. Rozbudowujemy nasze serwery, jak długo się da. Lepszy procesr (więcej procesorów!), więcej ramu, szybsze dyski -czynimy z naszego serwera demona prędkości. Biznesowo patrząc takie rozwiązanie wydaje się być bardzo korzystne. Nasza aplikacja przyspiesza, mamy co prawda koszty związane ze sprzętem – ale są ona bardzo małe w porównaniu do czasu programistów… A czas programistów jest zaoszczędzony ponieważ skalowanie pionowe nie wymaga żadnych zmian w kodzie aplikacji. Przez to zalecane jest jako deska ratunkowa gdy coś zaczyna iść źle lub po prostu w pierwszym etapie rozwoju naszego serwisu.

    Niestety skalując pionowo szybko dochodzimy do ściany… Zakupy lepszego sprzętu mogą być po prostu niemożliwe (bariera technologiczna). Szybko może okazać się zakupy nie przynoszą oczekiwanych rezultatów a stosunek ich ceny do odnoszonych korzyści zaczyna rosnąć wykładniczo.

    Lepszym rozwiązaniem, stosowanym przez największych jest:

  • skalowanie poziome – nie rozbudowujemy naszych wypasionych serwerów w nieskończoność, w zamian za to używamy dużej ilości pospolitych maszyn – i wykorzystujemy siłę przetwarzania rozproszonego. Etap ten jest dla sporych i średnich serwisów nieunikniony, ogromne zyski ze skalowania poziomego odnoszą najwięksi – MySpace, Flickr, Nasza-klasa…

    Skalowanie poziome wydaje się być prostym rozwiązaniem – zwłaszcza na poziomie serwerów WWW. Mówiąc w skrócie, skalowanie poziome polega na:

    • połączeniu kilku, kilkunastu, klikuset serwerów w sieć,
    • równoważeniu ruchu między wszystkie maszyny za pomocą load-balancera (sprzętowego,  czy też programowaego – np. Perlball lub LVM),
    • pliki aplikacji, danych znajdują się w jednym miejscu – na wydzielonym serwerze dyskowym – podłączone przez NFS. Tak jest najprościej, ale nie najlepiej.

Wykorzystując skalowanie poziome tak naprawdę dużo oszczędzamy. Poniższy rysunek pokazuje stosunek ceny od jakości (ilości CPU) przy obu wspomnianych wyżej technikach:

Hmm … zatem -czy to wszystko? I gdzie jest haczyk?

Skalowanie poziome wiąże się z pewnymi trudnościami na poziomie aplikacji. Najczęściej wymaga pewnych zmian w kodzie.

Wiążą się z nim dwa główne problemy (można się doszukać wielu więcej – np. związanych z systemem plików, połączeniami do bazy danych ,,,)z którymi musi się zmierzyć projektant:

  • Co zrobić ze stanem sesji użytkowników (odwiedzający raz korzysta z serwera 1 ale po odświeżeniu strony już z serwera 2 – a stan sesji domyślnie pamiętany jest na serwerze :) )?
  • Jak zarządzać rozproszonym środowiskiem (powyżej 1000 serwerów nie ma dnia, aby jeden z nich się nie zepsuł)?

Na szczęście istnieją pewne rozwiązania:

  • do zarządzania stanem sesji najlepiej wykorzystać brak sesji … lub memcache jeśli sesje są wymagane,
  • do zarządzania środowiskiem można korzystać z rozwiązań typu Capistrano

Jeśli nasza aplikacja będzie przystosowana do skalowania poziomego możemy sięgnąć po EC2 amazona, rightscale.com

Liznęliśmy temat :-)

PHP nie śmierdzi

Zapraszam do przeczytania ciekawej opinii Davida Heineimeier Hansona – twórcy frameworka Rails.

W skrócie – PHP nie śmierdzi, a cały jazz wokoło RoR bywa naprawdę przesadzony.

Niektórzy mężczyźni również – całe życie zmieniają życiowe partnerki – z nadzieją, że ta kolejna będzie właśnie tą. Jest ładniejsza, młodsza, prostsza w użyciu ;) … ale okazuje się, że trzeba w nią dużo inwestować, ma niezbyt bogate wnętrze i jeszcze kilka innych cech, które powodują dalsze poszukiwania.

Jak sobie z tym radzi fotka.pl?

Hazan umieścił na swoim blogu ciekawy wywiad z Rafałem Agnieszczakiem o architekturze fotka.pl. Polecam lekturę.

Rafał pisze konkretnie:

Wspominany przez Rafała GRID służący do skalowania bazy danych – jako żywo przypomina mi nasz Ganglib :-)

Wywiad dla PR-Szczecin

Podczas Infotrendy 2008 udzieliłem krótkiego wywiadu dla Polskiego Radia Szczecin nt. problemów ze skalowalnością aplikacji internetowych. Zapraszam do pobrania wywiadu w formacie mp3 i posłuchania.

Skalowalność w dużym obrazie

Jeśli jesteś zainteresowany skalowalnością z pułapu 30 km. n. p. m. zapraszam do obejrzenia mojej prezentacji
z Infotrendy 2008.

Co jest kluczem?

Technologia to tylko narzędzie. Najbardziej zaawansowane technologie komercyjne, czy też topowe rozwiązania Open Source – mogą stać się pułapką. Jeśli nie mamy dobrego projektu. Aplikacji.

Jedyną pewną rzeczą jest … zmiana!

Jeśli nasz projekt nie będzie wystarczająco elastyczny i nie zostaną w nim uwzględnione potencjalne problemy wynikające ze skali, nie łudźmy się, że technologia rozwiąże nasze problemy. To nie moja teoria ;) Tak wskazuje praktyka (zobacz też: ciekawa seria wpisów na Antyweb.pl)

Czym jest dobry projekt aplikacji?

Sądz, że warto zwrócić uwagę na następujące elementy:

  • podział aplikacji na warstwy (chociażby MVC!). Bardzo rzadko wąskim gardłem są wszystkie elementy systemu ;) Jeśli chcemy mieć możliwość niezależnego rozwijania, wymieniania, optymalizacji poszczególnych komponentów aplikacji warto pomyśleć o dobrej modularyzacji. Jeśli komponenty naszej aplikacji będą wystarczająco luźno powiązane zmiana DBMSa ograniczy się do wymiany modeli (wg. mnie warto iść z modelami jeszcze dalej – zobacz ganglib), jeśli generowanie wyników będzie czasochłonne – zmodyfikujemy tylko widoki itd. Proste, podstawowe, tyle.
  • jeśli dzielisz aplikację na warstwy – podziel i środowisko (nawet wirtualnie). Oddzielenie klastra baz danych od klastra serwerów aplikacji pozwala lepiej utylizować sprzęt i dłużej pozostawać przy skalowaniu pionowym środowiska aplikacji. Ale warto pamiętać o tym już od samego początku, nawet gdy storage, bazę danych i aplikację mamy na jednej maszynie

 

  • projektując i kodując – stawaj na ramionach gigantów. Wzorce projektowe i frameworki są twoimi przyjaciółmi :) … o ile są stosowane z rozwagą. Co jest do wszystkiego jest do niczego ;) Warto pamiętać o ograniczeniach technologii której używamy. Barokowa obiektowość w niektórych technologiach (PHP + Zend Framework? Magento?) nie jest szybka. Coś za coś. Parcie na elastyczność powinno być zawsze weryfikowane przez zdrowy rozsądek (wspomina sie o tym, ale mało – m.in. Cal Henderson i architektura Flickr) …
  • … poparty testami. (Profiluj, testuj, optymalizuj)*. Ale nie za wcześnie. Na wstępnym etapie projektowania, gdy jeszcze dużo wymagań się zmienia optymalizacja może niebezpiecznie zmniejszyć elastyczność.
  • wykrywaj wąskie gardła i eliminuj je…
  • … chociażby korzystając odpowiednio z Cache (Memcached?)

To tyle? Tak :)

Jeśli projekt naszej aplikacji jest odpowiedni nic nie stoi na przeszkodzie aby spokojnie rozwijać środowisko w którym ona pracuje.

O tym już w kolejnych wpisach.

Z czego korzystają najwięksi…

Nawiązując do poprzedniego postu, a dokładnie do fragmentu mówiącego o technologiach lepszych i gorszych, chciałbym przedstawić dzisiaj bardzo ciekawe zestawienie.

Z czego korzystają najwięksi

Tabelka przedstawia z jakich technologii korzystają największe serwisy internetowe.

Jeśli przyjrzymy się dokładnie zauważamy ciekawe wnioski:

  • 7 z 9 serwisów korzysta z Linuxa jako systemu operacyjnego oraz serwera Apache jako głównego serwera aplikacji,
  • 4 z 9 serwisów są wykonane w PHP ( tylko 1 w Pythonie i 2 w ASP.NET),
  • 7 z 9 serwisów korzysta z bezpłatnego silnika danych MySQL(!).

A gdzie RoR, J2EE?

Kiedyś spotkałem się ze stwierdzeniem, że nowy język programowania jest jak nowa dziewczyna – wydaje się być lepszy. Ale to nie on jest lepszy, tylko Ty jesteś lepszym… programistą! :) Bo znasz ograniczenia i możliwości kolejnej technologii – nowe dobre praktyki.

Tak naprawdę, nie ma technologii bardziej lub mniej skalowalnych – wszystko zależy od ich umiejętnego wykorzystania.

Okazuje się jednak iż bardziej kompleksowe rozwiązania – co prawda wyręczają programistę w wielu aspektach, ale często … mogą być ślepą uliczką – rozwiązaniem które będzie bardzo ciężko skalować – bez dokonywania dużych (i drogich!) zmian w core całej platformy.

W przypadku technologii komercyjnych – jest podobnie. MySQL jest tak popularny, ponieważ stosunkowo łatwo i tanio skaluje się go poziomo. Używając MSSQL lub Oracle – napotykamy bariery co krok – pierwszą z nich będą z pewnością koszty licencji.

Warto się nad tym zastanowić podejmując wiążące decyzje :)

Następna strona »