Powrót do kategorii
Backend
tagi
big data, sphinx, sphinxsearch,

Budowanie dużych indeksów danych z wykorzystaniem SphinxSearch

Tadeusz
Tadeusz, 02/01/2015

Prowadząc prace optymalizacyjne, napotkałem problem na przeważanie dużej ilości danych wygenerowanych przez Sphinx’a w jednym indeksie. Mianowicie Sphinx przetwarzając 100 mln rekordów z tabeli chciał stworzyć indeks którego wielkość przekraczała by 4GB. Niestety obecne wersje Sphinxa (32 bitowe), mają ograniczenie, które uniemożliwia taką operację. Sphinx w trakcie reindeksacji zwraca błąd:

ERROR: index offersSearch: too many string attributes (current index format allows up to 4 GB)

Szybkim i skutecznym sposobem okazało się rozdzielenie indeksu na kilka mniejszych części.
Poniżej przedstawię przykład:
Na początku musimy ustawić zmienną dist_threads, która odpowiada za rozdzielenie procesu szukania pomiędzy dostępne zasoby. Przykładowo, jeżeli mamy 2 indeksy i procesor 2 rdzeniowy ustawiamy dist_threads=2. Wówczas Sphinx przydzieli każdemu procesorowi wątek odpowiedzialny za przeszukanie po jednym indeksie.  Następnie przystępujemy do rozdzielenia indeksów. Ponieważ MySQL’owy offset nie ma zastosowania przy generowaniu indeksów Sphinxa najprostszą metodą na rozdzielenie wyników jest zastosowanie dzielenia modulo. Chcąc podzielić wynik na 2 części piszemy zapytanie, do którego dodajemy warunek dzielenie modulo przez 2, na 3 części modulo 3 itd.
W naszym przypadku cały config będzie wyglądał następujo:

searchd {  
  .....
  dist_threads = 2 
}

source source_0 {   
  sql_query = SELECT id,… FROM .. WHERE id % 2 = 0  
  ....
}
source source_1 : source_0 {  
  sql_query = SELECT id,… FROM ... WHERE id % 2 = 1
  ....
}

index index_0 {  
  source = source_0  
  path = /sphinx/source_0 
  type = plain
  ....
}

index index_1 {  
  source = source_1  
  path = /sphinx/source_1 
  type = plain
  ....
}

index all_indexes {  
  type = distributed  
  local =  index_0  
  local =  index_1
}

Następnie musimy przeindeksować index_0 oraz index_1

 /usr/bin/indexer index_0 --rotate
 /usr/bin/indexer index_1 --rotate

do wyszukiwania używamy indeksu all_indexes

search -i all_indexes "szukaj"

W rezultacie powinniśmy otrzymać dane spełniające warunki zapytania z indeksu index_0 oraz index_1.

Podobne artykuły

Sphinx Search – Indeksacja z wykorzystaniem wieloprocesorowego środowiska.

Jak efektywnie wykorzystać wiele wątków procesora dla jednego indexu danych.

Jak stworzyć automatyczną dokumentację CSS?

O tworzeniu dokumentacji przy pomocy DSS oraz Grunt.js.