SolrCloud – co się dzieje, kiedy ZooKeeper pada?

Jednym z pytań, jakie dość często dostaje jest pytanie odnośnie zachowania Solr podczas awarii ZooKeepera. Oczywiście nie mamy tu na myśli awarii pojedynczej instancji w ramach klastra, kiedy quorum jest dalej dostępne,  a po prostu brak działającego klastra ZooKeeper. Ponieważ odpowiedź na to pytanie bardzo łatwo sprawdzić, postanowiłem zrobić krótki wpis pokazujący co się dzieje.

Środowisko testowe

Środowisko testowe jest bardzo proste:

  • Pojedyncza maszyna wirtualna działająca pod kontrolą systemu Linux
  • Pojedyncza instancja ZooKeeper (wystarczająca do testów)
  • Dwie instancje Solr, z pojedyncza kolekcją
  • Solr w wersji 4.6

Aby stworzyć wymienioną kolekcję wykorzystałem następujące polecenie:

curl 'http://localhost:8983/solr/admin/collections?action=CREATE&name=collection1&numShards=2&replicationFactor=1'

Widok testowego klastra prezentuje się następująco:

cloud_view

Indeksujemy dane

Kolejnym krokiem, aby móc dalej przeprowadzić test jest zaindeksowanie kilku przykładowych dokumentów. Ze względu na to, że korzystamy z przykładowej konfiguracji, wykorzystamy przykładowe dokumenty. Polecenia wykorzystanie do zaindeksowania danych były następujące:

curl 'localhost:8983/solr/collection1/update?commit=true' --data-binary @mem.xml -H 'Content-type:application/xml'
curl 'localhost:8983/solr/collection1/update?commit=true' --data-binary @monitor.xml -H 'Content-type:application/xml'
curl 'localhost:8983/solr/collection1/update?commit=true' --data-binary @monitor2.xml -H 'Content-type:application/xml'

Po jego wykonaniu otrzymujemy następującą liczbę dokumentów:

  • Cała kolekcja ma 5 dokumentów
  • Shard zlokalizowany na Solr działającym na porcie 8983 ma 1 dokument
  • Shard zlokalizowany na Solr działającym na porcie 7983 ma 4 dokumenty

Zadawanie zapytań z niedziałającym ZooKeeperem

Przechodzimy do kolejnego kroku testu – po prostu wyłączamy ZooKeepera i próbujemy wykonać następujące polecenie:

curl 'localhost:8983/solr/collection1/select?q=*:*&indent=true'

W odpowiedzi otrzymujemy:

<?xml version="1.0" encoding="UTF-8"?>
<response>
 <lst name="responseHeader">
  <int name="status">0</int>
  <int name="QTime">16</int>
  <lst name="params">
   <str name="indent">true</str>
   <str name="q">*:*</str>
  </lst>
 </lst>
<result name="response" numFound="5" start="0" maxScore="1.0">
<doc>
 <str name="id">TWINX2048-3200PRO</str> 
 <str name="name">CORSAIR  XMS 2GB (2 x 1GB) 184-Pin DDR SDRAM Unbuffered DDR 400 (PC 3200) Dual Channel Kit System Memory - Retail</str>
 <str name="manu">Corsair Microsystems Inc.</str>
 <str name="manu_id_s">corsair</str>
 <arr name="cat">
  <str>electronics</str>
  <str>memory</str>
 </arr>
 <arr name="features">
  <str>CAS latency 2,    2-3-3-6 timing, 2.75v, unbuffered, heat-spreader</str>
 </arr>
 <float name="price">185.0</float>
 <str name="price_c">185,USD</str>
 <int name="popularity">5</int>
 <bool name="inStock">true</bool>
 <str name="store">37.7752,-122.4232</str>
 <date name="manufacturedate_dt">2006-02-13T15:26:37Z</date>
 <str name="payloads">electronics|6.0 memory|3.0</str>
 <long name="_version_">1453219034197655552</long>
</doc>
<doc>
 <str name="id">VS1GB400C3</str>
 <str name="name">CORSAIR ValueSelect 1GB 184-Pin DDR SDRAM Unbuffered DDR 400 (PC 3200) System Memory - Retail</str>
 <str name="manu">Corsair Microsystems Inc.</str>
 <str name="manu_id_s">corsair</str>
 <arr name="cat">
  <str>electronics</str>
  <str>memory</str>
 </arr>
 <float name="price">74.99</float>
 <str name="price_c">74.99,USD</str>
 <int name="popularity">7</int>
 <bool name="inStock">true</bool>
 <str name="store">37.7752,-100.0232</str>
 <date name="manufacturedate_dt">2006-02-13T15:26:37Z</date>
 <str name="payloads">electronics|4.0 memory|2.0</str>
 <long name="_version_">1453219034252181504</long>
</doc>
<doc>
 <str name="id">VDBDB1A16</str>
 <str name="name">A-DATA V-Series 1GB 184-Pin DDR SDRAM Unbuffered DDR 400 (PC 3200) System Memory - OEM</str>
 <str name="manu">A-DATA Technology Inc.</str>
 <str name="manu_id_s">corsair</str>
 <arr name="cat">
  <str>electronics</str>
  <str>memory</str>
 </arr>
 <arr name="features">
  <str>CAS latency 3,     2.7v</str>
 </arr>
 <int name="popularity">0</int>
 <bool name="inStock">true</bool>
 <str name="store">45.18414,-93.88141</str>
 <date name="manufacturedate_dt">2006-02-13T15:26:37Z</date>
 <str name="payloads">electronics|0.9 memory|0.1</str>
 <long name="_version_">1453219034255327232</long>
</doc>
<doc>
 <str name="id">3007WFP</str>
 <str name="name">Dell Widescreen UltraSharp 3007WFP</str>
 <str name="manu">Dell, Inc.</str>
 <str name="manu_id_s">dell</str>
 <arr name="cat">
  <str>electronics</str>
  <str>monitor</str>
 </arr>
 <arr name="features">
  <str>30" TFT active matrix LCD, 2560 x 1600, .25mm dot pitch, 700:1 contrast</str>
 </arr>
 <str name="includes">USB cable</str>
 <float name="weight">401.6</float>
 <float name="price">2199.0</float>
 <str name="price_c">2199,USD</str>
 <int name="popularity">6</int>
 <bool name="inStock">true</bool>
 <str name="store">43.17614,-90.57341</str>
 <long name="_version_">1453219041357332480</long>
</doc>
<doc>
 <str name="id">VA902B</str>
 <str name="name">ViewSonic VA902B - flat panel display - TFT - 19"</str>
 <str name="manu">ViewSonic Corp.</str>
 <str name="manu_id_s">viewsonic</str>
 <arr name="cat">
  <str>electronics</str>
  <str>monitor</str>
 </arr>
 <arr name="features">
  <str>19" TFT active matrix LCD, 8ms response time, 1280 x 1024 native resolution</str>
 </arr>
 <float name="weight">190.4</float>
 <float name="price">279.95</float>
 <str name="price_c">279.95,USD</str>
 <int name="popularity">6</int>
 <bool name="inStock">true</bool>
 <str name="store">45.18814,-93.88541</str>
 <long name="_version_">1453219045997281280</long></doc>
</result>
</response>

Jak widać Solr odpowiedział poprawnie. Dzieje się tak dlatego, że stan klastra opisywany plikiem clusterstate.json jest przechowywany po stronie Solr. Do wykonania zapytania nie jest potrzebna jego aktualizacja , a zatem wszystko powinno działać i działa.

Indeksowanie i niedziałający ZooKeeper

Nie włączając ZooKeepera próbujemy wykonać następujące polecenie:

curl 'localhost:8983/solr/collection1/update?commit=true' --data-binary @hd.xml -H 'Content-type:application/xml'

Czyli po prostu zaindeksować plik hd.xml. Po dłuższym oczekiwanie w odpowiedzi otrzymujemy:

<?xml version="1.0" encoding="UTF-8"?>
<response>
<lst name="responseHeader"><int name="status">503</int><int name="QTime">15096</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ć bez działającego klastra ZooKeepera Solr nie jest w stanie zaindeksować danych.

Włączamy ZooKeepera nie restartując Solr

Włączamy zatem ponownie ZooKeepera nie restartując naszych instancji Solr i znów próbujemy wykonać następujące polecenie:

curl 'localhost:8983/solr/collection1/update?commit=true' --data-binary @hd.xml -H 'Content-type:application/xml'

Tym razem odpowiedź wygląda następująco:

<?xml version="1.0" encoding="UTF-8"?>
<response>
<lst name="responseHeader"><int name="status">0</int><int name="QTime">118</int></lst>
</response>

A zatem indeksowanie powiodło się, co pozwala nam zakładać, iż Solr sam ustanowił połączenie z ZooKeeperem, jak tylko ZooKeeper został uruchomiony. Możemy to zresztą zobaczyć w logach Solr i ZooKeepera.

Podsumowanie

Jak widać ten krótki test pozwolił nam na odpowiedź co się dzieje z Solr kiedy traci połączenie z ZooKeeperem – może dalej serwować dane, aczkolwiek nie jest w stanie ich zaindeksować. Mam nadzieję, że ten wpis pomoże rozwiać niektóre wątpliwości odnośnie SolrCloud i jego przydatności 🙂

Należy pamiętać, iż podczas testu wszystkie shardy z których składała się kolekcja były dostępne i w pełni działające. W następnej części tego wpisu przyjrzymy się, co dzieje się kiedy dochodzi do awarii podczas niedostępności ZooKeeper’a.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *