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 e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *