<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>tolerancja &#8211; Solr.pl</title>
	<atom:link href="https://solr.pl/tag/tolerancja/feed/" rel="self" type="application/rss+xml" />
	<link>https://solr.pl</link>
	<description>All things to be found - Blog related to Apache Solr &#38; Lucene projects - https://solr.apache.org</description>
	<lastBuildDate>Sat, 14 Nov 2020 11:47:31 +0000</lastBuildDate>
	<language>pl-PL</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9</generator>
	<item>
		<title>SolrCloud &#8211; tolerancja odczytu i zapisu</title>
		<link>https://solr.pl/2018/12/31/solrcloud-tolerancja-odczytu-i-zapisu/</link>
					<comments>https://solr.pl/2018/12/31/solrcloud-tolerancja-odczytu-i-zapisu/#respond</comments>
		
		<dc:creator><![CDATA[Rafał Kuć]]></dc:creator>
		<pubDate>Mon, 31 Dec 2018 11:47:02 +0000</pubDate>
				<category><![CDATA[Solr]]></category>
		<category><![CDATA[indeksowanie]]></category>
		<category><![CDATA[replikacja]]></category>
		<category><![CDATA[solr]]></category>
		<category><![CDATA[solrcloud]]></category>
		<category><![CDATA[tolerancja]]></category>
		<category><![CDATA[zapytania]]></category>
		<guid isPermaLink="false">http://sematext.solr.pl/?p=770</guid>

					<description><![CDATA[SolrCloud, podobnie jak większość systemów rozproszonych podlega pewnym zasadom. Np. CAP mówi o tym, iż rozproszony system jest w stanie zapewnić dwie z trzech wymienionych funkcjonalności w tym samym czasie &#8211; dostępność, spójność, odporność na rozłączanie sieci. Oczywiście nie będziemy]]></description>
										<content:encoded><![CDATA[
<p>SolrCloud, podobnie jak większość systemów rozproszonych podlega pewnym zasadom. Np. <a href="https://en.wikipedia.org/wiki/CAP_theorem">CAP</a> mówi o tym, iż rozproszony system jest w stanie zapewnić dwie z trzech wymienionych funkcjonalności w tym samym czasie &#8211; dostępność, spójność, odporność na rozłączanie sieci.  Oczywiście nie będziemy rozmawiać o podstawach systemów rozproszonych, ale skupimy się jak możemy kontrolować tolerancję zapisu i odczytu w SolrCloud. <br></p>



<span id="more-770"></span>



<h2 class="wp-block-heading">Tolerancja zapisu</h2>



<p>Tolerancja zapisu to dość skomplikowany temat. Po pierwsze, wraz z wprowadzeniem Solr 7.0 dostaliśmy różne rodzaje replik. Mamy repliki typu NRT, które zapisują dane do loga transakcyjnego, a indeksowanie odbywa się na każdej z replik. Mamy repliki typu TLOG, gdzie nowe dane zapisywane są do loga transakcyjnego, a samo indeksowanie nie następuje i występuje tylko binarna replikacja. W końcu repliki typu PULL, gdzie Solr nie korzysta z loga transakcyjnego replikując segmenty od lidera.</p>



<p>Nie będziemy się dzisiaj jednak zajmować dokładną analizą, jak działają poszczególne typy replik i skupimy się na domyślnym typie, czyli replikach NRT. Repliki te były z nami od początku SolrCloud i na szczęście są dalej <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p>W przypadku replik NRT procedura indeksowania danych działa następująco &#8211; na początku lider przyjmuje dane, zapisuje je w logu transakcyjnym i wysyła do swoich replik (zakładamy, że wszystkie są typu NRT). Każda z replik zapisuje dane w logu transakcyjnym. W tym momencie nasze dane są już bezpieczne i Solr może zwrócić potwierdzenie przyjęcia danych. Oczywiście, gdzieś w między czasie, w zależności od konfiguracji tworzony jest odwrócony indeks. Co się stanie kiedy nie wszystkie shardy będą dostępne? Indeksowanie nie powiedzie się. Aby to przetestować wystarczy, że uruchomimy dwie instancje Solr następującymi komendami: </p>



<pre class="wp-block-code"><code class="">$ bin/solr start -c</code></pre>



<pre class="wp-block-code"><code class="">$ bin/solr start -z localhost:9983 -p 6983</code></pre>



<p>A następnie stworzymy kolekcję:</p>



<pre class="wp-block-code"><code class="">$ bin/solr create_collection -c test_index -shards 2 -replicationFactor 1</code></pre>



<p>Zabijemy jedną z instancji:</p>



<pre class="wp-block-code"><code class="">$ bin/solr stop -p 6983</code></pre>



<p>I spróbujemy zaindeksować dane:</p>



<pre class="wp-block-code"><code class="">$ curl -XPOST -H 'Content-type:application/json' 'localhost:8983/solr/test_index/update' -d '{
 "id" : 2,
 "name" : "Test document"
}'</code></pre>



<p>Oczywiście, tak jak mogliśmy się spodziewać Solr zwróci bład:</p>



<pre class="wp-block-code"><code class="">{
  "responseHeader":{
    "status":503,
    "QTime":4011},
  "error":{
    "metadata":[
      "error-class","org.apache.solr.common.SolrException",
      "root-error-class","org.apache.solr.common.SolrException"],
    "msg":"No registered leader was found after waiting for 4000ms , collection: test_index slice: shard2 saw state=DocCollection(test_index//collections/test_index/state.json/8)={\n  \"pullReplicas\":\"0\",\n  \"replicationFactor\":\"1\",\n  \"shards\":{\n    \"shard1\":{\n      \"range\":\"80000000-ffffffff\",\n      \"state\":\"active\",\n      \"replicas\":{\"core_node3\":{\n          \"core\":\"test_index_shard1_replica_n1\",\n          \"base_url\":\"http://192.168.1.11:8983/solr\",\n          \"node_name\":\"192.168.1.11:8983_solr\",\n          \"state\":\"active\",\n          \"type\":\"NRT\",\n          \"force_set_state\":\"false\",\n          \"leader\":\"true\"}}},\n    \"shard2\":{\n      \"range\":\"0-7fffffff\",\n      \"state\":\"active\",\n      \"replicas\":{\"core_node4\":{\n          \"core\":\"test_index_shard2_replica_n2\",\n          \"base_url\":\"http://192.168.1.11:6983/solr\",\n          \"node_name\":\"192.168.1.11:6983_solr\",\n          \"state\":\"down\",\n          \"type\":\"NRT\",\n          \"force_set_state\":\"false\",\n          \"leader\":\"true\"}}}},\n  \"router\":{\"name\":\"compositeId\"},\n  \"maxShardsPerNode\":\"-1\",\n  \"autoAddReplicas\":\"false\",\n  \"nrtReplicas\":\"1\",\n  \"tlogReplicas\":\"0\"} with live_nodes=[192.168.1.11:8983_solr]",
    "code":503}}</code></pre>



<p>W tym wypadku nie jesteśmy w stanie zrobić nic &#8211; nie chcemy, aby nasze dane wylądowały gdziekolwiek. Musimy czekać, aż Solr powróci do stanu używalności, albo sami go do niego doprowadzimy <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p>Co jednak w przypadku, kiedy mamy wiele replik i tylko niektóre z nich nie są dostępne? W tym wypadku zapis się powiedzie, a w najnowszych wersjach Solr poinformuje nas o stanie replikacji poprzez umieszczenie w odpowiedzi parametru <em>rf</em>, czyli replication factor. </p>



<p>Stwórzmy sobie zatem jeszcze jedną kolekcję, tym razem składającą się z jednego lidera i jego repliki:</p>



<pre class="wp-block-code"><code class="">$ bin/solr create_collection -c test_index_2 -shards 1 -replicationFactor 2</code></pre>



<p>Jeżeli spróbujemy zaindeksować dane takim samym poleceniem jak wcześniej (oczywiście zmieniając nazwę kolekcji) odpowiedź Solr w wersji 7.6.0 będzie wyglądała następująco:</p>



<pre class="wp-block-code"><code class="">{
  "responseHeader":{
    "rf":2,
    "status":0,
    "QTime":316}}</code></pre>



<p>Jak widać parametr <em>rf</em> ustawiony został na wartość <em>2</em>, co mówi nam, że indeksowanie powiodło się zarówno na liderze, jak i jego replice. Jeżeli zatrzymalibyśmy instancję Solr działającą na porcie <em>6983</em> i spróbowali ponowić indeksowanie Solr poinformuje nas, iż tylko jedna replika danych została zapisana:</p>



<pre class="wp-block-code"><code class="">{
  "responseHeader":{
    "rf":1,
    "status":0,
    "QTime":4}}</code></pre>



<p>We wcześniejszych wersjach Solr, aby otrzymać tą informację należało dodać parametr <em>min_rf</em> większy od 1 do żądania zawierającego indeksowanie, aby dostać informację, jaki poziom replikacji został osiągnięty przez Solr. </p>



<h2 class="wp-block-heading">Tolerancja odczytu</h2>



<p>W przypadku odczytu sprawy mają się trochę inaczej. Brak spójności danych, np. w przypadku braku jednego lub kliku shardów spowoduje, iż Solr zwróci błąd. Możemy to bardzo prosto pokazać &#8211; tworzymy dwie instancje Solr:</p>



<pre class="wp-block-code"><code class="">$ bin/solr start -c</code></pre>



<pre class="wp-block-code"><code class="">$ bin/solr start -z localhost:9983 -p 6983</code></pre>



<p>Następnie tworzymy prostą kolekcję:</p>



<pre class="wp-block-code"><code class="">$ bin/solr create_collection -c test -shards 2 -replicationFactor 1</code></pre>



<p>A teraz zatrzymujemy jedną z instancji:</p>



<pre class="wp-block-code"><code class="">$ bin/solr stop -p 6983</code></pre>



<p>I teraz wystarczy zadać proste zapytanie:</p>



<pre class="wp-block-code"><code class="">http://localhost:8983/solr/test/select?q=*:*</code></pre>



<p>W odpowiedzi zamiast pustej listy dokumentów dostaniemy błąd:</p>



<pre class="wp-block-code"><code class="">{
  "responseHeader":{
    "status":503,
    "QTime":6,
    "params":{
      "q":"*:*"}},
  "error":{
    "metadata":[
      "error-class","org.apache.solr.common.SolrException",
      "root-error-class","org.apache.solr.common.SolrException"],
    "msg":"no servers hosting shard: shard2",
    "code":503}}</code></pre>



<p>Czasami jednak chcielibyśmy zaprezentować wyniki wyszukiwania pomimo braku części informacji. Nie jest to oczywiście idealna sytuacja, ale czasem lepiej pokazać mniej danych, niż nie pokazać nic, oczywiście jeżeli zdajemy sobie sprawę co robimy. W tym celu przychodzą nam z pomocą dwa parametry: <em>shards.tolerant</em> oraz <em>shards.info</em>. Oba powinny zostać ustawione na wartość <em>true</em>, czyli nasze zapytanie przyjmie następującą formę:</p>



<pre class="wp-block-code"><code class="">http://localhost:8983/solr/test/select?q=*:*&amp;shards.tolerant=true&amp;shards.info=true</code></pre>



<p>Tym razem Solr nie zwróci już błędu, a nagłówek odpowiedzi będzie wyglądał następująco:</p>



<pre class="wp-block-code"><code class="">{
  "responseHeader":{
    "zkConnected":true,
    "partialResults":true,
    "status":0,
    "QTime":45,
    "params":{
      "q":"*:*",
      "shards.tolerant":"true",
      "shards.info":"true"}},
  "shards.info":{
    "":{
      "error":"org.apache.solr.common.SolrException: no servers hosting shard: ",
      "trace":"org.apache.solr.common.SolrException: no servers hosting shard: \n\tat org.apache.solr.handler.component.HttpShardHandler.lambda$submit$0(HttpShardHandler.java:165)\n\tat java.util.concurrent.FutureTask.run(FutureTask.java:266)\n\tat java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)\n\tat java.util.concurrent.FutureTask.run(FutureTask.java:266)\n\tat com.codahale.metrics.InstrumentedExecutorService$InstrumentedRunnable.run(InstrumentedExecutorService.java:176)\n\tat org.apache.solr.common.util.ExecutorUtil$MDCAwareThreadPoolExecutor.lambda$execute$0(ExecutorUtil.java:209)\n\tat java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)\n\tat java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)\n\tat java.lang.Thread.run(Thread.java:748)\n",
      "time":0},
    "http://192.168.1.11:8983/solr/test_shard1_replica_n1/":{
      "numFound":0,
      "maxScore":0.0,
      "shardAddress":"http://192.168.1.11:8983/solr/test_shard1_replica_n1/",
      "time":18}},
  "response":{"numFound":0,"start":0,"maxScore":0.0,"docs":[]
  }}</code></pre>



<p>Jak widać, działa to tak jakbyśmy chcieli. Nie dostaliśmy od Solr błędu, a odpowiedź. Dodatkowo widzimy, iż zwrócone są częściowe rezultaty (<em>partialResults</em> ustawione na <em>true</em>), co pozwala nam lub naszej aplikacji na stwierdzenie, że coś jest nie tak. Oprócz tego opcja <em>shards.info=true</em> pozwoliła Solr zwrócić informacje których shardów brakuje. <br></p>
]]></content:encoded>
					
					<wfw:commentRss>https://solr.pl/2018/12/31/solrcloud-tolerancja-odczytu-i-zapisu/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
