Aby możliwe było wygenerowanie indeksu pozwalającego na sprawne i szybkie wyszukiwanie, konieczne jest dostarczenie danych w ustalonym formacie. W przypadku silnika wyszukiwania znanego jako SphinxSearch, podstawowym źródłem danych jest baza danych, np. MySQL. Nie zawsze jednak możliwe jest dostarczenie danych w ten sposób - przykładowo indeksowane dane przechowywane są na różnych serwerach bądź źródle danych nie wspieranym przez SphinxSearch. W takiej sytuacji przydatna jest możliwość dostarczenia danych (dla indeksera) w formacie XML. Rozwiązanie to jest bardzo elastyczne (możemy generować dane w dowolny sposób), ale niestety dużo wolniejsze niż indeksowanie bezpośrednio z bazy danych. Kompromisem może być natomiast indeksowanie danych ze źródła w formacie TSV - szybsze niż to z XMLa a przy tym równie elastyczne.
tsvpipe
Definicja źródła danych w formacie TSV jest bardzo podobna do tej dla formatu xmlpipe. Oprócz określenia typu (tsvpipe), komendy za pomocą której dostarczone zostaną dane (tsvpipe_command) niezbędne jest zdefiniowanie poszczególnych pól i atrybutów.
Przykładowo:
Indeksowane dane powinny być zgodne z ustalonym formatem: pierwsza kolumna to identyfikator dokumentu a następnie wartości o typach danych w kolejności zdefiniowanej w konfiguracji.
Benchmark
Pierwsze spostrzeżenie, jeśli chodzi o porównanie szybkości indeksowania danych w formacie XML i TSV, jest takie że format XML charakteryzuje duża nadmiarowość danych (tagi XML, konieczność escape’owania danych) która nie występuje w przypadku formatu TSV. Ponadto xmlpipe wymaga, aby poszczególne węzły dokumentu XML (oraz ich atrybuty) zostały zmapowane na pola i atrybuty zawarte w definicji indeksu wyodrębniając jednocześnie ich wartości z dostarczonego zbioru danych. Uwzględniając te założenia, przewaga w szybkości indeksowania TSV nad XML powinna rosnąć wraz ze wzrostem liczby indeksowanych dokumentów. A jak to wygląda w praktyce?
Przeprowadziłem następujące testy:
- indeksowanie z przygotowanego pliku statycznego w formacie TSV / XML
- dane dla indeksera dostarczane są dynamicznie przez skrypt generujący dane w formacie TSV / XML
Dodatkowo w pierwszym przypadku zmierzony został czas generowania danych. Oczywiście wszystkie testy przeprowadzone zostały w jednolitym środowisku, dane generowane były jednolity sposób (skrypt do generowania testowych danych generate_data.php).
Wyniki:
I. plik statyczny (test.tsv, test.xml)
100k | 500k | 1M | 2.5M | 5M | 10M | ||
---|---|---|---|---|---|---|---|
TSV | czas generowania danych | 1.411s | 6.890s | 13.456s | 32.921s | 67.298s | 143.932s |
czas indeksowania danych | 3.023s | 15.950s | 32.986s | 88.815s | 188.468s | 399.714s | |
XML | czas generowania danych | 1.687s | 7.693s | 15.830s | 38.672s | 78.685s | 155.954s |
czas indeksowania danych | 3.097s | 15.363s | 32.249s | 87.420s | 193.434s | 469.150s | |
TSV vs XML | czas generowania danych | -16.36% | -10.43% | -14.99% | -14,87% | -14,47% | -7,71% |
czas indeksowania danych | -2.39% | +3.82% | +2.28% | +1.59% | -2.57% | -14.80% |
II. dane generowane za pomocą skryptu (generate_data.php)
100k | 500k | 1M | 2.5M | 5M | 10M | ||
---|---|---|---|---|---|---|---|
TSV | czas indeksowania danych | 4.863s | 20.501s | 42.556s | 112.720s | 232.924s | 499.994s |
XML | czas indeksowania danych | 4.403s | 22.061s | 45.771s | 119.788s | 245.638s | 525.838s |
TSV vs XML | czas indeksowania danych | +9.46% | -7.07% | -7.02% | -5.90% | -5.18% | -4.91% |
Wyniki przeprowadzonych testów potwierdzają postawioną tezę - indeksowanie danych w formacie TSV jest szybsze niż XML. Różnice czasowe w szybkości indeksowania wzrastają razem z liczbą indeksowanych dokumentów. Składa się na to dłuższy czas generowania danych w formacie XML (różnice mogą sięgać nawet kilkunastu procent) oraz wyodrębniania ich z dostarczonego zbioru danych. W przypadku mniejszych zbiorów danych (pobieranych ze statycznego źródła, np. pliku) koszt wyodrębniania danych z XML jest na tyle niski, iż nie wpływa znacząco na czas generowania indeksu. Zauważalna różnica pojawia się dopiero w przypadku większych zbiorów danych. Stąd też, dla małych zbiorów danych, w przypadku generowania indeksu ze statycznego pliku bądź porównywalnych czasów generowania danych dla indeksera, czas budowania indeksu z XML może być nawet krótszy - w zależności od próby możliwe są wahania w jedną bądź drugą stronę. Drugi z analizowanych scenariuszy pokazuje, że nawet dla stosunkowo niewielkiego indeksu (500k dokumentów) różnica w czasie jego budowania jest już dość znacząca. Jest to dla nas o tyle istotne, iż zazwyczaj indeksy generowane będą na podstawie dynamicznie generowanego zbioru danych a nie statycznego pliku. Warto zwrócić uwagę jeszcze na jeden fakt - otóż liczba operacji IO w obu przypadkach (TSV vs XML) jest identyczna (szczegóły w załączonych szczegółowych wynikach).
Dla zainteresowanych, kompletne wyniki eksperymentów.
Dla prawidłowego działania wyszukiwania, indeksowanie jest równie istotne co usługa wyszukiwania - bądź co bądź zapewnia strukturę danych umożliwiającą uzyskanie wysokiej jakości wyników wyszukiwania w bardzo krótkim czasie. Dlatego też tak istotne jest, aby dane w indeksie były odpowiednio często aktualizowane, co bezpośrednio jest zależne od wydajności mechanizmu indeksowania. W związku z tym, bardzo pożądana jest możliwość elastycznego dostarczania danych dla indeksu, która realizowana jest m.in poprzez formaty XML oraz TSV. Przedstawiona analiza wskazuje TSV jako bardziej pożądany format - szybszy i prostszy. A czy Twoja aplikacja dostarcza już dane dla indeksów Sphinxa w taki sposób?
Przydatne linki:
- http://sphinxsearch.com/blog/2014/08/14/easy-indexing-with-tsvpipe/
- https://github.com/stefobark/index_tsv
- http://sphinxsearch.com/docs/current/tsvpipe.html
- http://sphinxsearch.com/forum/view.html?id=11964
tagi: benchmark , indexer , performance , SphinxSearch , tsv , tsvpipe , xmlpipe