Sphinx i Merb - silna konkurencja dla Ferreta i Railsów
Posted by Jarosław Zabiełło Fri, 30 Nov 2007 17:18:00 GMT
Sphinx to alternatywny wobec Lucene/Ferreta silnik wyszukiwania pełnotekstowego. Charakteryzuje się ogromną szybkością działania i małym zużyciem zasobów komputera. Różnica jest tak kolosalna, że jak ktoś pierwszy raz słyszy że Sphinx indeksuje teksty miliony razy szybciej to nie chce wierzyć. Nazywają go odpowiednikiem Nginksa dla wyszukiwania pełnotekstowego. W obu przypadkach autorami są rosyjscy programiści.
Trochę czasu mi zajęło zanim się przekonałem, że do webowego wyszukiwania tekstów, używanie mechanizmów opartych na relacyjnej bazie danych i skryptach Rubiego/Pythona, to raczej kiepski pomysł. W artykule Full text search in Ruby on Rails elegancko wypunktowano różnice między Ferretem MySQL. Ruby on Rails (a właściwie Active Record) posiada nawet gotowy plugin acts_as_ferret który bardzo upraszcza integrację Ferreta z bazą MySQL. W sieci można spotkać sporo artykułów osób zachwyconych możliwościami Ferreta i łatwością użycia plugina acts_as_ferret. Jest tylko jeden drobny problem. Czas indeksowania tekstów.
Próbowałem zaindeksować tabelę (dla MySQL 5) składającą się z ok. 2.5 mln rekordów (zebranych z ponad 100 przekładów Biblii w 19 wersjach językowych). Prób a postąpienia wg wskazówek z pliku README do tego pluginu okazała się strzałem w stopę. Mój dwurdzeniowy MacBook Pro 2.2GHz, 2GB RAM jak rozpoczął tworzenie indeksów jednego dnia po południu, to nie skończył go na drugi dzień. Przerwałem to szaleństwo. Wygenerował jakieś 250 MB indeksów na 1.2GB do stworzenia. Znacznie szybciej było napisać sobie własny skrypt Rubiego do indeksacji. Pomielił jakieś dwie godziny, ale za to nie 2-3 doby! W sumie indeksowanie większych plików do Ferreta blokuje komputer na dłuższy czas. Mało ciekawie.
I wtedy spróbowałem Sphinksa. Różnica byla tak kolosalna, że wpierw myślałem, że jest jakiś błąd w programie. Sphinx tą samą tabelę poindeksował mi w niecała minutę. Wszelkie operacje wyszukiwania różnych boolowskich kombonacji słów trwa niezmiennie 1-2 ms. Jest po prostu natychmiastowe! Algorytm Sphinksa jest niezrównanie lepiej przemyślany. Co z tego, że teoretycznie Lucene czy Ferret mają więcej możliwości, skoro w praktyce 95% z nich posiada też Sphinx? Jak ktoś chce, to do Active Record jest również plugin acts_as_sphinx.
Jestem ciekaw kiedy będą gotowe pluginy acts_as_ferret i acts_as_sphinx do DataMapper’a, znacznie szybszego i ogólnie lepiej przemyślanego ORM’ niż Active Record.
Tak w ogóle, to Railsom wyrasta groźna konkurencja w świecie Rubiego. To nie Nitro, ale Merb może podciąć dominację Railsów. Korzysta z railsowej filozofii, ale dużo szybszy, w pełni wielowątkowy, komponentowy i w wielu punktach lepiej przemyślany (ma lepswzy resolver URL, domyślnie korzysta z Erubis, najszybszego systemu szablonów jaki jest do Rubiego). Merb przypomina mi trochę filozofię leżącą u podstaw pythonowego Pylons. Jest tak samo z definicji nastawiony na elastyczność i łatwość wymiany swych komponentów oraz duży nacisk położono na wydajność. Czyli to, co nagminnie było od zawsze lekceważone przez developerów Railsów skupiających się za bardzo na wymyślaniu nowej funkcjonalności. Nie bez znaczenia jest to, że proces migracji aplikacji z Rails do Merba jest raczej prosty, bo ten drugi potrafi pracować z Active Record. Więc w zasadzie modele można przerzucać bez większego problemu. Może Merb nie zdetronizuje Rails, bo ten tak całkiem nie stoi w miejscu i lada dzień ma wyjść wersja finalna 2.0 (w momencie pisania tekstu jest już RC2). Ale może zmobilizuje developerów Railsów aby trochę popracowali nad jakością już stworzonego kodu. A jak nie, to nic straconego. Dobra konkurencja dla Railsów nie zaszkodzi.


Kanały IRC![[Dilber w Onecie]](/images/larry.png)


Jarosławie, od dłuższego czasu z uznaniem czytuję Twojego bloga, ale teraz pierwszy raz pozwalam sobie na komentarz (to tytułem wstępu).
Też niedawno zainteresowałem się projektem Merb. Czy spotkałeś może jakieś dokładniejsze opisy, tutoriale itd. jak używać Merba razem z Datamapperem?
Pytam, bo mnie się udało znaleźć jedynie takie, które nie wykraczają zbyt daleko poza sam proces instalacji. Mam na myśli jakiś przepis, jak zrobić “w duchu Merb+Datamapper” prostą aplikację od początku do końca – żeby podkreślić wszystkie różnice z Railsami, pokazać ficzery itp.
Od paru miesięcy korzystamy ze Sphinxa w Nokaut.pl i bardzo go sobie chwalimy.
Konfiguracja Merb z DataMapperem jest bardzo prosta. Wystarczy w pliku config/dependencies.rb znaleźć i odkomentować linijkę
Chyba jednak lepszy jest inny ORM – Sequel. Trochę z nim popracowałem. Wygląda nie tylko na dojrzalszy od DataMappera ale także wspaniale się z nim pracuje. Może póżniej coś więcej napiszę. Powiem tylko, że Sequel ma wbudowane migracje, można krokowo rozbudowywać warunki, wszystkie operacje są lazy, składnię ma bardzo podobną do ORM używanego w pythonowym Django. Na każdym kroku można sprawdzić jaki SQL byłby wygenerowany (wystarczy odpalić na końcu dokleić metodę .sql). Odpalenie zapytania zwraca jeden obiekt ORM z wbudowanym iteratorem i dodatkowymi opcjami a nie tak jak (głupio) robi Active Record. No i Sequel ma wsparcie dla sporej ilości baz.
Napisałem sobie w Merb pierwszą aplikację (używam tam Erubis, Sequel i Sphinksa) i muszę przyznać, że to Merb ma zadatki na killer application ktora może zdetronizować Rails. Nie tylko jest szybszy, wielowątkowy i bardziej elastyczny. Jest także prostszy, odrzucono zasadę “wszystko implicite” jaką widać w Rails. W Merb jest mniej magii. Także wyraźnie szybciej i łatwiej się tworzy i debuguje kod niż w Rails. Dużo lepszy projekt moim zdaniem. Aż odeszły mnie ciągotki aby przerzucać się do pythonowego Pylons. :)
Czy umiecie zmusić Sphinxa do działania z językiem polskim? Chodzi mi na przykład o stemmowanie itp.?
niestety, nie :(, poki co nie znalazlem nic na ten temat