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