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:
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.