Solr 4.1: Kompresja pól typu stored

Pomimo tego, że wersja 4.0 Solr i Lucene jest jeszcze bardzo świeża stwierdziliśmy, że czas przyjrzeć się zmianom nadchodzącym w wersji 4.1. Jedną z tych zmian jest wprowadzenie kompresji dla pól typu stored, a tym samym zmniejszenie wielkości indeksu, kiedy korzystamy z przechowywania oryginalnej wartości pól. Zobaczmy więc, jak to działa.

Trochę teorii

W przypadku kiedy nasz indeks składa się z dużej ilości pól oznaczonych jako stored mogą one stanowić nawet większą część miejsca zajmowanego przez indeks. Skąd wiedzieć ile zajmują pola typu stored ? Wystarczy spojrzeć do katalogu z indeksem i policzyć ile zajmują pliki z rozszerzeniem .fdt. Pomimo tego, że duża ilość pól tego typu nie wpływa bezpośrednio na wydajność Solr, to jednak wielkość indeksu wpływa na to jak zachowuje się cache I/O, a tym samym, im większy indeks, tym bardziej prawdopodobne, że będziemy mieli dość dużo operacji odczytu, a tym samym nasze zapytania będą wykonywane wolniej. Do tego, ze względu na to, że musimy zapisać więcej danych – indeksowanie także będzie wolniejsze.

Wraz z Lucene 4.1 pola oznaczone jako stored będą kompresowane algorytmem LZ4 (http://code.google.com/p/lz4/), który powinien znacznie zmniejszyć wielkość indeksu, gdy korzystamy z dużej ilości tego typu pól, a jednocześnie nie powinien mocno obciążać maszyny podczas wykonywania kompresji.

Dane testowe

Do testów wykorzystaliśmy dane polskiej wikipedii z dnia 2012.11.10 zawierające artykuły (http://dumps.wikimedia.org/plwiki/20121110/plwiki-20121110-pages-articles.xml.bz2). Rozpakowany plik XML z danymi zajmował około 4.7GB.

Struktura indeksu

Następująca struktura indeksu została przygotowana, aby zaindeksować powyższe dane:

<field name="id" type="string"  indexed="true" stored="true" required="true"/>
<field name="title" type="text" indexed="true" stored="true"/>
<field name="revision" type="int" indexed="true" stored="true"/>
<field name="user" type="string" indexed="true" stored="true"/>
<field name="userId" type="int" indexed="true" stored="true"/>
<field name="text" type="text" indexed="true" stored="true"/>
<field name="timestamp" type="date" indexed="true" stored="true"/>
<field name="_version_" type="long" indexed="true" stored="true"/>

Konfiguracja DIH

Konfiguracja DIH użyta do importu danych Wikipedii wyglądała następująco:

<dataConfig>
 <dataSource type="FileDataSource" encoding="UTF-8" />
 <document>
  <entity name="page" processor="XPathEntityProcessor" stream="true" forEach="/mediawiki/page/" url="/home/data/wikipedia/plwiki-20121110-pages-articles.xml" transformer="RegexTransformer,DateFormatTransformer">
   <field column="id" xpath="/mediawiki/page/id" />
   <field column="title" xpath="/mediawiki/page/title" />
   <field column="revision" xpath="/mediawiki/page/revision/id" />
   <field column="user" xpath="/mediawiki/page/revision/contributor/username" />
   <field column="userId" xpath="/mediawiki/page/revision/contributor/id" />
   <field column="text" xpath="/mediawiki/page/revision/text" />
   <field column="timestamp" xpath="/mediawiki/page/revision/timestamp" dateTimeFormat="yyyy-MM-dd'T'hh:mm:ss'Z'" />
   <field column="$skipDoc" regex="^#REDIRECT .*" replaceWith="true" sourceColName="text"/>
  </entity>
 </document>
</dataConfig>

Czas indeksowania

Czas indeksowania był bardzo podobny w obu przypadkach dla tej samej liczby dokumentów, dokładnie było ich 1.301.394. W przypadku Solr 4.0 czas indeksowania wyniósł 14 minut i 33 sekundy, w przypadku Solr 4.1 wyniósł 14 minut i 43 sekundy. Zatem Solr 4.1 był minimalnie wolniejszy, a ze względu na to, że test był wykonywany na moim laptopie, można przyjąć iż wydajność indeksowania będzie podobna.

Wielkość wynikowego indeksu

Wielkość indeksu, czyli to co nas najbardziej interesuje. W przypadku Solr 4.0 indeks, który powstał w wyniku zaindeksowania danych miał około 5.1GB, czyli dokładnie 5.464.809.863 bajtów. W przypadku Solr 4.1 rozmiar indeksu wyniósł około 3.24GB, czyli dokładnie 3.480.457.399 bajtów. Zatem porównyjąc indeks stworzony przez Solr 4.0 do indeksu stworzonego przez Solr 4.1 zyskaliśmy około 35% miejsca na dysku.

Podsumowanie

Widać jak na dłoni, iż zysk z kompresowania pól oznaczonych jako stored jest duży. Pomimo tego, iż potrzebna jest dodatkowa moc procesora na kompresję i dekompresję danych, zysk polegający na zmniejszeniu obciążenia I/O będzie większy, niż strata cykli procesora. Nie dziwię się zatem, iż kompresja pól oznaczonych jako stored jest włączona domyślnie w Lucene 4.1, a zatem i w Solr 4.1. Jeżeli jednak chcielibyśmy wyłączyć to zachowanie, na chwilę obecną konieczna jest własna implementacja odpowiedniego codec’a, który nie korzysta z kompresji. Jednak aby skorzystać z własnego formatu indeksu nie musimy utrzymywać własnej wersji Lucene, co znów pokazuje potęgę codec’ów wprowadzonych wraz z Lucene 4.0.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *