SolrCloud: co się dzieje, kiedy ZooKeeper pada – część druga

W poprzednim artykule na temat SolrCloud poruszyliśmy problem awarii ZooKeepera oraz jak reaguje Solr podczas obsługiwania zapytań. W dzisiejszym wpisie przyjrzymy się bliżej, dlaczego dzieje się tak, że jesteśmy w stanie zadawać zapytania, a nie jesteśmy w stanie indeksować danych.

Krótkie przypomnienie

W artykule SolrCloud – co się dzieje, kiedy ZooKeeper pada? pokazaliśmy, iż w przypadku awarii ZooKeeper’a jesteśmy w stanie bezproblemowo zadawać zapytania i dostawać poprawne wyniki wyszukiwania. Oczywiście jest to prawda do chwili, kiedy nie zmieniamy niczego w topologi klastra. Niestety, w przypadku indeksowania, nie jesteśmy w stanie zmieniać indeksu kiedy SolrCloud nie ma aktywnego połączenia z ZooKeeperem, lub kiedy nie ma quorum. Przyjrzyjmy się zatem dlaczego tak się dzieje.

Dlaczego możemy zadawać zapytania?

Sytuacja jest dość prosta – zadawanie zapytań nie jest operacją zmieniającą stan klastra SolrCloud. Jedyne co Solr musi zrobić, to przyjąć zapytanie i wysłać je do odpowiednich instancji Solr. Oczywiście topologia klastra nie jest odczytywana przy każdym zapytaniu, a w związku z tym nie mając aktywnego połączenia z ZooKeeper’em lub gdy nie ma quorum jesteśmy w stanie bez problemów zadawać zapytania.

Jest jeszcze jedna ciekawa opcja, chociaż dużo osób o tym nie wie – możliwość zwracania tylko częściowych wyników wyszukiwania w momencie, kiedy część kolekcji nie jest dostępna. Dodając parametr shards.tolerant=true do naszych zapytań informujemy Solr, że jesteśmy w stanie żyć w częściowymi wynikami, np. wtedy, gdy część kolekcji jest niedostępna. Domyślnie Solr po prostu zwróci błąd.

Dlaczego nie możemy indeksować danych?

Dlaczego nie możemy indeksować danych, jeżeli nie ma połączenia z ZooKeeper’em lub gdy nie ma quorum? Wszystkiemu winien jest brak wystarczającej ilości informacji, aby indeksacja mogła zostać przeprowadzona poprawnie. Dokładniej – Solr (potencjalnie) nie ma informacji o aktualnym stanie klastra, a co za tym idzie nie jest w stanie poprawnie wyliczyć, gdzie ma zostać umieszczony dokument, czy które core’y, na których instancjach Solr są replikami, a które leaderami kolekcji. Wszystko to powoduje, że indeksacja dokumentów nie jest możliwa.

Generalnie, warto pamiętać, iż operacje wymagające aktualizacji stanu Solr, czy też aktualizacji danych, które znajdują się z ZooKeeper nie będą możliwe do wykonania w wypadku braku kworum ZooKeepera (w naszym wypadku braku pojedynczego serwera ZooKeeper).

Oczywiście poprawność tego co napisaliśmy powyżej bardzo łatwo to sprawdzić i właśnie tym zajmiemy się w dalszej części wpisu.

Uruchamiamy ZooKeepera

Krok bardzo prosty. Do testów wystarczy nam pojedyncza instancja ZooKeepera uruchomiona w następujący sposób:

bin/zkServer.sh start

Na konsoli powinniśmy zobaczyć następujące informacje:

JMX enabled by default
Using config: /Users/gro/Solry/zookeeper/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED

I tym samym mamy działającą instancję ZooKeepera.

Uruchamiamy dwie instancje Solr

Do testów wykorzystaliśmy najnowszą, dostępną wersję Solr 5.2.1. Do uruchomienia dwóch instancji Solr korzystamy z następującego polecenia:

bin/solr start -e cloud -z localhost:2181

Podczas uruchamiania wybieramy, iż chcemy mieć 2 instancje, porty na których będą działać nie są ważne.

Dodatkowo wybraliśmy następujące opcje:

  • nazwa kolekcji: gettingstarted
  • liczba shardów: 2
  • liczba replik: 1
  • konfiguracja kolekcji: data_driven_schema_configs

Całość wyglądała mniej, więcej tak:

Zrzut ekranu 2015-06-21 o 11.13.31

Dodajemy kilka dokumentów

Żeby sprawdzić, czy Solr na pewno działa dodajmy kilka dokumentów korzystając z następującego polecenia:

bin/post -c gettingstarted docs/

Jeżeli wszystko poszło zgodnie z planem, to na poniższe polecenie:

curl -XGET 'localhost:8983/solr/gettingstarted/select?indent=true&q=*:*&rows=0'

powinniśmy dostać następującą odpowiedź:

<?xml version="1.0" encoding="UTF-8"?>
<response>
 <lst name="responseHeader">
  <int name="status">0</int>
  <int name="QTime">38</int>
  <lst name="params">
   <str name="q">*:*</str>
   <str name="indent">true</str>
   <str name="rows">0</str>
  </lst>
 </lst>
 <result name="response" numFound="3577" start="0" maxScore="1.0">
 </result>
</response>

Wszystko działa jak należy.

Czas na indeksowanie z wyłączonym Zookeeperem

Zatrzymajmy zatem naszą instancję ZooKeepera poleceniem:

bin/zkServer.sh stop

I spróbujmy jeszcze raz uruchomić następujące polecenie:

bin/post -c gettingstarted docs/

Tym razem, zamiast informacji o tym, że dokumenty są indeksowane powinniśmy widzieć coś w tym stylu:

POSTing file index.html (text/html) to [base]/extract
SimplePostTool: WARNING: Solr returned an error #503 (Service Unavailable) for url: http://localhost:8983/solr/gettingstarted/update/extract?resource.name=%2FUsers%2Fgro%2FSolry%2F5.2.1%2Fdocs%2Findex.html&literal.id=%2FUsers%2Fgro%2FSolry%2F5.2.1%2Fdocs%2Findex.html
SimplePostTool: WARNING: Response: <?xml version="1.0" encoding="UTF-8"?>
<response>
<lst name="responseHeader"><int name="status">503</int><int name="QTime">3</int></lst><lst name="error"><str name="msg">Cannot talk to ZooKeeper - Updates are disabled.</str><int name="code">503</int></lst>
</response>

Jak widać, brak ZooKeepera skutkuje niemożliwością indeksowania. Oczywiście zadawanie zapytań wciąż działa. Ponowne włączenie ZooKeepera i rozpoczęcie indeksowania także będzie skutkowało bezproblemowym indeksowaniem, ze względu na to, że Solr ponownie się z nim połączy.

Krótkie podsumowanie

Oczywiście ten i poprzedni tekst dotykają tylko wierzchołka góry lodowej i pokazuje co się dzieje, gdy brakuje ZooKeepera. Bardzo dobry test dotyczący tego jak SolrCloud zachowuje się nie tylko podczas awarii ZooKeepera, ale także podczas problemów z infrastrukturą sieciową można znaleźć na http://lucidworks.com/blog/call-maybe-solrcloud-jepsen-flaky-networks/. Polecamy wszystkim, którzy mają ochotę dowiedzieć się, jak SolrCloud zachowa się w sytuacjach awaryjnych.

Dodaj komentarz

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