SlideShare uma empresa Scribd logo
1 de 70
Baixar para ler offline
Jak przyspieszyć SOLRa w kilku
prostych krokach
Przemysław Szeremiota
Adam Dudczak
od 33 do 40 mln wyszukiwań na dobę
54 000 000 dokumentów/ofert w indeksie
15 mln aktualizacji dziennie
SOLR w Allegro to 44 piękne kobiety
m[16-62]—c[4-20]-d[12-100]
p50 = 91 ms
throughput = 85k rpm
2015
2016
p50 = 20 ms
throughput = 116k rpm
SOLR w Allegro to 44 piękne kobiety
SOLR w Allegro to ponad 100 serwerów
SOLR w Allegro to 44 piękne kobiety
SOLR w Allegro to ponad 100 serwerów
15 mln komunikatów dziennie
dodatkowe 10k komunikatów na sekundę
SOLR w Allegro to 44 piękne kobiety
SOLR w Allegro to ponad 100 serwerów
p99 czasów odpowiedzi 300ms
p99 czasów odpowiedzi >1000ms
15 mln komunikatów dziennie
dodatkowe 10k komunikatów na sekundę
SOLR w Allegro to 44 piękne kobiety
SOLR w Allegro to ponad 100 serwerów
p99 czasów odpowiedzi 300ms
p99 czasów odpowiedzi >1000ms
Indeks o wielkości 20GB
Indeks o wielkości 40GB
15 mln komunikatów dziennie
dodatkowe 10k komunikatów na sekundę
Silniki wyszukiwawcze w Allegro.pl
1. Apache SOLR standalone jako podstawa głównych
indeksów naszej wyszukiwarki (11 indeksów)
2. Cluster SOLR CLOUD wykorzystywany do indeksów
pomocniczych (10 indeksów)
3. Kilkadziesiąt clustrów Elastic Search wykorzystywany
przez zespoły developerskie jako rozwiązanie as a service
13
Schema matters!
BEZ PRACY…
15
schemaless (adjective sche·ma·less -ləs): definiowanie schematu
bezwiednie, nieświadomie
• Ułatwia szybką implementację wyszukiwarki w aplikacji
• Nieźle nadaje się do niektórych typowych/modnych zastosowań
wyszukiwarek (logi, time-series)
… NIE MA KOŁACZY!
16
• Schemat w SOLR istnieje zawsze
• Projektowanie schematu: projektowanie podstaw funkcjonalności
wyszukiwarki
• Trafność wyników wymaga słowników, synonimów, sprytnych
sposobów indeksowania, tokenizerów, filtrów, analizatorów…
• Szlifowanie schematu: szlifowanie skuteczności i wydajności
wyszukiwarki (pola indeksowane/pola docValues)
KAŻDY SZCZEGÓŁ SIĘ LICZY
17
“Od rana już czymś niedobrym pachniało w powietrzu”
KAŻDY SZCZEGÓŁ SIĘ LICZY
18
• Pola przeznaczone do wyszukiwania pełnotekstowego
(indeksowane)
• Pola przeznaczone do sortowania (docValues?)
• Pola przeznaczone do facetingu (docValues?)
• Pola wykorzystywane w filtrach (indeksowane/docValues)
To cache or not to cache?
TO CACHE OR NOT TO CACHE?
20
• document cache — cache pól składowanych odsyłanych w
ramach wyników zapytania
• query cache — cache całych wyników, z opcją “nadmiaru”
• filter cache — cache “filtrów” (zapytań cząstkowych)
Trzy gotowce do cachowania w SOLR:
TO CACHE OR NOT TO CACHE?
21
• Przyspiesza odsyłanie wyników, ale może lepiej nie odsyłać
kompletnych dokumentów, tylko identyfikatory do udekorowania
na froncie?
• Przechowywać w nim całe dokumenty, czy tylko wybrane pola?
Cache dokumentów
<documentCache class="solr.LFUCache" size="10" initialSize="1" autowarmCount="1"/>
TO CACHE OR NOT TO CACHE?
22
• Wyniki zapytań gotowe do ponownego użycia, ale czy potrafimy
wycelować w ten sam backend?
• Opcja “nadmiaru” przyspiesza pobieranie następnej strony
wyników, ale czy potrafimy wycelować w ten sam backend?
Cache zapytań
<queryResultCache class="solr.LFUCache" size="50" initialSize="50" autowarmCount="50"/>
TO CACHE OR NOT TO CACHE?
23
• Wyniki cząstkowe gotowe do ponownego użycia
• Niezbędny do operacji facetingu
Cache filtrów
<filterCache class="solr.LFUCache" size="600" initialSize="600" autowarmCount=“600" />
/select?q=name:nokia&fq=price:[30 TO 50]
/select?q=name:iphone&fq=published:[NOW-1DAY TO NOW]
/select?q=name:nokia&fq=price:[30 TO 40]&fq=type:auction
TO CACHE OR NOT TO CACHE?
24
• Duża wariancja w czasach wykonania dla nietrafionych zapytań/
filtrów
• Pamięć JVM
• CPU/czas w GC
• CPU/czas przy kompletowaniu zbioru wynikowego filtra
Koszt intensywnego cache-owania
TO CACHE…
25
<queryResultCache class="solr.LFUCache" size="100" initialSize="50" autowarmCount=“50"/>
<documentCache class="solr.FastLRUCache" size="100000" initialSize="50000"
autowarmCount="50000"/>
<filterCache class="solr.LFUCache" size="3000" initialSize="600" autowarmCount="600"/>
rps:126.316667 max:7969 avg:54 p50:3 p75:7 p90:25 p95:58 p99:1160 pp95:3555 pp99:6838
rps:130.083333 max:9279 avg:127 p50:4 p75:11 p90:62 p95:178 p99:4782 pp95:6115 pp99:7882
rps:146.816667 max:9060 avg:39 p50:4 p75:8 p90:30 p95:67 p99:1401 pp95:1896 pp99:3636
rps:145.050000 max:4367 avg:31 p50:3 p75:8 p90:27 p95:58 p99:1087 pp95:1713 pp99:2306
rps:160.683333 max:4956 avg:38 p50:4 p75:10 p90:31 p95:68 p99:1365 pp95:2080 pp99:2809
CPU: ~60%
GC TIME: ~1.8s/min
FilterCache: 82% (inserts: ~7K, lookups: ~45K, evictions: ~5K)
QueryResultCache: 2% (inserts: ~40K, lookups: ~42K, evictions: ~40K)
TO CACHE…
26
…NOT TO CACHE
27
<queryResultCache class="solr.LFUCache" size="50" initialSize="50" autowarmCount="50"/>
<documentCache class="solr.FastLRUCache" size="10" initialSize="1" autowarmCount="1"/>
<filterCache class="solr.LFUCache" size="600" initialSize="600" autowarmCount="600"/>
rps:167.466667 max:7028 avg:8 p50:2 p75:5 p90:15 p95:25 p99:79 pp95:135 pp99:467
rps:156.833333 max:2388 avg:10 p50:2 p75:6 p90:18 p95:31 p99:109 pp95:215 pp99:869
rps:157.566667 max:1499 avg:6 p50:2 p75:6 p90:15 p95:25 p99:72 pp95:121 pp99:439
rps:141.750000 max:4752 avg:7 p50:2 p75:6 p90:17 p95:27 p99:76 pp95:131 pp99:287
rps:159.700000 max:4869 avg:9 p50:2 p75:5 p90:15 p95:27 p99:80 pp95:148 pp99:802
CPU: ~20%
GC TIME: ~200ms/min
FilterCache: 93% (inserts: ~1K, lookups: ~12K, evictions: ~0.5K)
QueryResultCache: 2% (inserts: ~40K, lookups: ~42K, evictions: ~40K)
NOT TOO CACHE!!!
28
• Wyniki zapytań lepiej cachować na load-balancerach
• Do pobierania następnych stron lepiej użyć mechanizmu cursor-
mark
• Filtry nieselektywne lepiej wyznaczać w obrębie query
fq={!cache=false}type:auction
• Filtry częstozmienne lepiej wyznaczać w trybie postfilter
fq={!frange cache=false cost=100 l=30 u=50}price
DocValue your sort/facet fields
DocValue nie tylko do sort/facetingu
“DocValues are a way of recording field values
internally that is more efficient for some purposes,
such as sorting and faceting, than traditional
indexing.”
30
DocValues, ale o co chodzi?
tytuł:
nokia -> 1, 3, 5, 6, 7
lumia -> 3, 5,
cena:
120 -> 1
140 -> 3
500 -> 5
…
query: nokia lumia sort: cena ASC
31
DocValues, ale o co chodzi?
tytuł:
nokia -> 1, 3, 5, 6, 7
lumia -> 3, 5,
cena:
120 -> 1
140 -> 3
500 -> 5
…
pasujące wyniki: 3,5
32
Indeks odwrotny rządzi!
ale co z sortowaniem?
wyniki: 3, 5
cena:
140 -> 3, 6
500 -> 5, 10
…
cena_sort:
3 -> 140
5 -> 500
…
33
W przypadku indeksu odwrotnego musimy
przejrzeć całą listę termów i znaleźć
interesujące nas dokumenty
DocValues
• Dostępne w Lucene od wersji 4.0
• Polecane szczególnie do sortowania, facetowania, highligthingu
• Pozwalają bez większego problemu pobierać wartości z indeksu
<field name="state" type="string" indexed="false" stored="false" docValues="true" />
34
DocValues świetnie sprawdzają się w postfiltrach!
35
Postfiltry - krótkie wprowadzenie
• Postfiltr to filtr wykonywany po zakończeniu przetwarzania kryteriów z q i fq
• Ewaluowane kryterium może zawierać “kosztowną” logikę związaną z
zawartością dokumentu lub kontekstem użytkownika
&fq={!cache=false cost=200}price:200
&fq={!frange l=300 cache=false cost=200}price
&fq={!frange l=5 cache=false cost=200}div(log(popularity),sqrt(geodist()))
36
(source: http://yonik.com/advanced-filter-caching-in-solr/)
A jak to się ma do DocValues?
37
38
(source: http://qaware.blogspot.com/2014/11/how-to-write-postfilter-for-solr-49.html)
Na deser…
• Możliwość modyfikacji DocValues in place, bez konieczności reindeksacji
całego dokumentu.
• Narazie testujemy…
39
Sort your index!
Dlaczego sortowanie indeksu?
• Sortowanie indeksu to zabójcza kombinacja w połączeniu z Early Terminating
Collectorem. O co chodzi?
41
Indeks bez sortowania
Segment 1:
- dokument 4: cena 430
- dokument 1: cena 100
- dokument 5: cena 540
Segment 2:
- dokument 6: cena 510
- dokument 3: cena 110
- dokument 2: cena 440
query: *:*, sort: cena ASC, rows=2
42
Musimy przejrzeć cały indeks, żeby znaleźć
2 najtańsze przedmioty
Indeks posortowany po cenie
Segment 1:
- dokument 1: cena 100
- dokument 4: cena 430
- dokument 5: cena 540
Segment 2:
- dokument 3: cena 110
- dokument 2: cena 440
- dokument 6: cena 510
query: *:*, sort: cena ASC, rows=2
43
Nie musimy przetwarzać wszystkiego
Jak to wywołać?
<indexConfig>
...
<mergePolicyFactory
class="org.apache.solr.index.SortingMergePolicyFactory">
<str name="sort">promoted desc,category1 desc,variant_id desc</str>
<str name="wrapped.prefix">inner</str>
<str name=“inner.class">
org.apache.solr.index.TieredMergePolicyFactory
</str>
<int name="inner.segmentsPerTier">2</int>
<int name="inner.maxMergeAtOnce">7</int>
<int name="inner.maxMergedSegmentMB">12288</int>
<int name="inner.forceMergeDeletesPctAllowed">5</int>
</mergePolicyFactory>
...
</indexConfig>
44
Dlaczego sortowanie indeksu?
• W praktyce niezbyt przydatne
• Jeden porządek sortowania w indeksie
• Wiele metod sortowania w aplikacji
• Ograniczona użyteczność Early Terminating Collectora w przypadku wielu
porządków sortowania
45
Czasem niespodzianki potrafią być miłe…
Rozmiar indeksu się zmniejszył, dzięki temu wszystko zaczęło
działać szybciej i zjadało mniej zasobów.
46
Bądź świadomy tego jak ludzie
korzystają z Twojej wyszukiwarki!
Stabilność przede wszystkim
• Profil wykorzystania wyszukiwarki
• Większości przypadków użytkownicy przechodzą od zapytań
ogólnych do szczegółowych (dodają filtry, zmieniają frazę)
• Oglądają nie więcej niż 20 stron wyników
• To jest nasz biznes!
48
Apache Solr i dalekie strony
• Apache Solr w przypadku przeglądania dalekich strony wyników
nie radzi sobie tak jakbyśmy chcieli
• Im dalej… tym wolniej i drożej
•start=0, rows=10
•start=1000, rows=10
•start=10000, rows=10
49
Separuj zapytania
• Zapytania o dalsze strony są kierowane do dedykowanej puli
maszyn
• Zapytania o ciężkie porządki sortowania do dedykowanej puli
maszyn
50
SOLR w js?
Allegro SOLR-PLUGINS
52
• Gdzie umiejscowić optymalizacje?
• Frontend?
• API?
• Backend (SOLR)?
• SOLR oferuje sporo “gniazdek” do przyłączania funkcjonalności:
• parsery, collectory
• komponenty obsługi zapytań
• procesory dokumentów i wyników zapytań
Allegro SOLR-PLUGINS
53
• SearchComponent
• prepare(request)
• process(response)
• UpdateRequestProcessor
• processAdd(cmd)
• processDelete(cmd)
• …
• QParser
• parse(query)
Allegro SOLR-PLUGINS
54
<requestHandler name="/select" class="solr.SearchHandler">
<arr name="components">
<str>optimizer</str>
<str>query</str>
<str>facet</str>
</arr>
</requestHandler>
<searchComponent name="optimizer" class=“pl.allegro…ScriptedSearchComponent”>
<arr name="script">
<str name="script">optimizer/optimizer.js</str>
</arr>
</searchComponent>
Allegro SOLR-PLUGINS
55
load('…/optimizer/query-params.js');
var nocache = load(‘…/optimizer/nocache-rewriter.js’)(['seller', 'category',
'latitude', 'longitude']);
function prepare(request) {
var query = getQuery(request); // from query-params.js
query.fq = nocache(query.fq)); // from nocache-rewriter.js
setQuery(query);
logger.debug('optimized: {}', request);
}
function process(response) {
logger.debug('process: ' + response);
}
Allegro SOLR-PLUGINS
56
function nocacheRewriter(fields) {
fields = fields || [ 'seller', 'price' ];
var NOCACHEFQ = new RegExp(‘^(?:{!(tag=w+)})?((?:'
+ fields.join(‘|')
+ '):(?:[^&]+))$');
return function(filters) {
return filters.map(function(filter) {
return filter.replace(NOCACHEFQ, function(match, tag, filter) {
return tag ? '{!cache=false ' + tag + '}' + filter : '{!cache=false}' +
filter;
});
});
}
}
More signals?
Motywacja
• Nie dajemy rady indeksować sygnałów zaangażowania w Lucene
• SOLR-owy mechanizm ExternalFileField jest powolny
• Mimo wstrętu do programowania, trza było zakasać rękawy
58
Sorted binary file field
• Sygnał zaangażowania to offerID -> wartość
• Lucene operuje na relacjach luceneID -> offer
• W Lucene relacja offerID -> luceneID jest niestała
59
offerID -> luceneID?
luceneID -> offerID?
luceneID offerID name category bidcount
1 1432 nokia Telefony 0
2 5760 audi Moto 0
3 9811 nike Moda 0
offerID listed
1432 60
5760 22
9811 342
lucene sort_by(“listed”):
foreach (luceneID in docset):
docset[luceneID].sortVal = listedSource.getValue(luceneID)
sort(docset, .sortVal)
luceneID offerID name category bidcount
1 1432 nokia Telefony 0
2 5760 audi Moto 0
3 9811 nike Moda 0
4 1432 nokia Telefony 1
Jak działa ExternalFileField?
61
reload()
getValue(luceneID)
foreach (row in engagement_file):
{ offerID, value } = row.split(“=“)
luceneID = lucene.find("offerID", offerID)
vals[luceneID] = value
return vals[luceneID]
Binary Sort File Field
62
reload()
getValue(luceneID)
eng = mmap(engagement_file)
if (vals[luceneID]):
return vals[luceneID]
else:
id = lucene.get(“offerID”, luceneID)
return vals[luceneID] = bsearch(eng, id).value
ExternalFileField
SortedBinaryFileField
Wczytywanie wartości trwa wieki
Wczytywanie wartości trwa okamgnienie
Mapowanie on-heap float[numDocs]
Mapowanie off-heap, opcjonalnie on-heap
offerId->luceneID
luceneID->offerID
Sorted Binary File Field
<fieldType name="external_defval_0"
cache="true"
keyField="doc_id"
defVal="0"
class="pl.allegro.bestmatch.solr.SortedBinaryFileField"
valType="float" />
<field name="click_ratio" type="external_defval_0" />
64
Sorted Binary File Field - przygotowanie
Wartości:
1;3
2;56
3;89
from struct import pack
import sys
import json
for line in sys.stdin:
try:
vals = line.split(';')
sys.stdout.write(pack('>qf', long(vals[0]), float(vals[1])))
except:
sys.stderr.write("error: " + line)
65
Sorted Binary File Field
Wyliczanie sygnałów zaangażowania odbywa się offline (np.
Hadoop/MapReduce)
Umożliwia wynoszenie z indeksu innych często zmiennych
pól (cena? sztuk?)
Umożliwia stosunkowo łatwe importowanie dodatkowych
sygnałów
66
Do czego wykorzytujemy?
• Liczba odsłon oferty na listingu
• Liczba dodań oferty do koszyków
• Liczba dodań oferty do obserwowanych
• Liczba odsłon oferty
• Ocena sprzedawcy
• Jakość obrazków oferty
67
Dystrybucja plików
SOLR
SOLR
SOLR
SOLR
HTTP SERVER
HDFS
Czy mogę tego użyć?
• Tak… prawie… już niedługo na githubie ;-)
69
Pytania?
Pytania?
Przemysław Szeremiota / Damian Parus / Wojtek Stryszyk / Tomek Jackowiak / Adam Dudczak
imię.nazwisko@allegrogroup.com
Poznań, 6 kwietnia 2017

Mais conteúdo relacionado

Mais procurados

Technologia Xamarin i wprowadzenie do Windows IoT core
Technologia Xamarin i wprowadzenie do Windows IoT coreTechnologia Xamarin i wprowadzenie do Windows IoT core
Technologia Xamarin i wprowadzenie do Windows IoT coreSages
 
100Mpps czyli jak radzić sobie z atakami DDoS?
100Mpps czyli jak radzić sobie z atakami DDoS?100Mpps czyli jak radzić sobie z atakami DDoS?
100Mpps czyli jak radzić sobie z atakami DDoS?Redge Technologies
 
PLNOG 6: Łukasz Jagiełło - Wdrożenie skalowalnego systemu plików GlusterFS w ...
PLNOG 6: Łukasz Jagiełło - Wdrożenie skalowalnego systemu plików GlusterFS w ...PLNOG 6: Łukasz Jagiełło - Wdrożenie skalowalnego systemu plików GlusterFS w ...
PLNOG 6: Łukasz Jagiełło - Wdrożenie skalowalnego systemu plików GlusterFS w ...PROIDEA
 
Metaprogramowanie w JS
Metaprogramowanie w JSMetaprogramowanie w JS
Metaprogramowanie w JSDawid Rusnak
 
Paweł Kucharski: Oswajamy Słonia czyli po co nam Hadoop
Paweł Kucharski: Oswajamy Słonia czyli po co nam HadoopPaweł Kucharski: Oswajamy Słonia czyli po co nam Hadoop
Paweł Kucharski: Oswajamy Słonia czyli po co nam HadoopAnalyticsConf
 
Ochrona przed atakami DDoS na platformie x86. Czy można mieć jednocześnie wyd...
Ochrona przed atakami DDoS na platformie x86. Czy można mieć jednocześnie wyd...Ochrona przed atakami DDoS na platformie x86. Czy można mieć jednocześnie wyd...
Ochrona przed atakami DDoS na platformie x86. Czy można mieć jednocześnie wyd...Redge Technologies
 
Monitoring systemu. Dlaczego mój kardiolog jest bogatym człowiekiem?
Monitoring systemu. Dlaczego mój kardiolog jest bogatym człowiekiem?Monitoring systemu. Dlaczego mój kardiolog jest bogatym człowiekiem?
Monitoring systemu. Dlaczego mój kardiolog jest bogatym człowiekiem?The Software House
 
PLNOG 22 - Krzysztof Załęski - Praktyczne zastosowanie narzędzi NetDevOps
PLNOG 22 - Krzysztof Załęski - Praktyczne zastosowanie narzędzi NetDevOpsPLNOG 22 - Krzysztof Załęski - Praktyczne zastosowanie narzędzi NetDevOps
PLNOG 22 - Krzysztof Załęski - Praktyczne zastosowanie narzędzi NetDevOpsPROIDEA
 
Aplikacje internetowe real-time w oparciu o React/Redux
Aplikacje internetowe real-time w oparciu o React/ReduxAplikacje internetowe real-time w oparciu o React/Redux
Aplikacje internetowe real-time w oparciu o React/ReduxDawid Rusnak
 
Efekt motyla w kodzie maszynowym.
Efekt motyla w kodzie maszynowym.Efekt motyla w kodzie maszynowym.
Efekt motyla w kodzie maszynowym.Semihalf
 
Stosy sieciowe w przestrzeni użytkownika.
Stosy sieciowe w przestrzeni użytkownika.Stosy sieciowe w przestrzeni użytkownika.
Stosy sieciowe w przestrzeni użytkownika.Semihalf
 
Złam zasady i stwórz wydajny stos IP przy użyciu DPDK
Złam zasady i stwórz wydajny stos IP przy użyciu DPDKZłam zasady i stwórz wydajny stos IP przy użyciu DPDK
Złam zasady i stwórz wydajny stos IP przy użyciu DPDKSemihalf
 
Info meet pomiary wydajności
Info meet pomiary wydajnościInfo meet pomiary wydajności
Info meet pomiary wydajnościmagda3695
 
PLNOG16: DNS Catalog Zones łatwe tworzenie i synchronizacja serwowanych ...
PLNOG16: DNS Catalog Zones łatwe tworzenie i synchronizacja serwowanych ...PLNOG16: DNS Catalog Zones łatwe tworzenie i synchronizacja serwowanych ...
PLNOG16: DNS Catalog Zones łatwe tworzenie i synchronizacja serwowanych ...PROIDEA
 
Apache http server - proste i zaawansowane przypadki użycia
Apache http server - proste i zaawansowane przypadki użyciaApache http server - proste i zaawansowane przypadki użycia
Apache http server - proste i zaawansowane przypadki użyciaWojciech Lichota
 
Sekrety magicznego ogrodu Docker
Sekrety magicznego ogrodu DockerSekrety magicznego ogrodu Docker
Sekrety magicznego ogrodu DockerKamil Grabowski
 
Ruby, Ruby on Rails 2010
Ruby, Ruby on Rails 2010Ruby, Ruby on Rails 2010
Ruby, Ruby on Rails 2010Natalia Stanko
 
PLNOG22: Tomasz Jarlaczyk & Tomasz Ludwiczak - DNSv6 i SSL - historie z życia...
PLNOG22: Tomasz Jarlaczyk & Tomasz Ludwiczak - DNSv6 i SSL - historie z życia...PLNOG22: Tomasz Jarlaczyk & Tomasz Ludwiczak - DNSv6 i SSL - historie z życia...
PLNOG22: Tomasz Jarlaczyk & Tomasz Ludwiczak - DNSv6 i SSL - historie z życia...PROIDEA
 

Mais procurados (20)

GlusterFS
GlusterFSGlusterFS
GlusterFS
 
Technologia Xamarin i wprowadzenie do Windows IoT core
Technologia Xamarin i wprowadzenie do Windows IoT coreTechnologia Xamarin i wprowadzenie do Windows IoT core
Technologia Xamarin i wprowadzenie do Windows IoT core
 
Infrastructure As Code
Infrastructure As CodeInfrastructure As Code
Infrastructure As Code
 
100Mpps czyli jak radzić sobie z atakami DDoS?
100Mpps czyli jak radzić sobie z atakami DDoS?100Mpps czyli jak radzić sobie z atakami DDoS?
100Mpps czyli jak radzić sobie z atakami DDoS?
 
PLNOG 6: Łukasz Jagiełło - Wdrożenie skalowalnego systemu plików GlusterFS w ...
PLNOG 6: Łukasz Jagiełło - Wdrożenie skalowalnego systemu plików GlusterFS w ...PLNOG 6: Łukasz Jagiełło - Wdrożenie skalowalnego systemu plików GlusterFS w ...
PLNOG 6: Łukasz Jagiełło - Wdrożenie skalowalnego systemu plików GlusterFS w ...
 
Metaprogramowanie w JS
Metaprogramowanie w JSMetaprogramowanie w JS
Metaprogramowanie w JS
 
Paweł Kucharski: Oswajamy Słonia czyli po co nam Hadoop
Paweł Kucharski: Oswajamy Słonia czyli po co nam HadoopPaweł Kucharski: Oswajamy Słonia czyli po co nam Hadoop
Paweł Kucharski: Oswajamy Słonia czyli po co nam Hadoop
 
Ochrona przed atakami DDoS na platformie x86. Czy można mieć jednocześnie wyd...
Ochrona przed atakami DDoS na platformie x86. Czy można mieć jednocześnie wyd...Ochrona przed atakami DDoS na platformie x86. Czy można mieć jednocześnie wyd...
Ochrona przed atakami DDoS na platformie x86. Czy można mieć jednocześnie wyd...
 
Monitoring systemu. Dlaczego mój kardiolog jest bogatym człowiekiem?
Monitoring systemu. Dlaczego mój kardiolog jest bogatym człowiekiem?Monitoring systemu. Dlaczego mój kardiolog jest bogatym człowiekiem?
Monitoring systemu. Dlaczego mój kardiolog jest bogatym człowiekiem?
 
PLNOG 22 - Krzysztof Załęski - Praktyczne zastosowanie narzędzi NetDevOps
PLNOG 22 - Krzysztof Załęski - Praktyczne zastosowanie narzędzi NetDevOpsPLNOG 22 - Krzysztof Załęski - Praktyczne zastosowanie narzędzi NetDevOps
PLNOG 22 - Krzysztof Załęski - Praktyczne zastosowanie narzędzi NetDevOps
 
Aplikacje internetowe real-time w oparciu o React/Redux
Aplikacje internetowe real-time w oparciu o React/ReduxAplikacje internetowe real-time w oparciu o React/Redux
Aplikacje internetowe real-time w oparciu o React/Redux
 
Efekt motyla w kodzie maszynowym.
Efekt motyla w kodzie maszynowym.Efekt motyla w kodzie maszynowym.
Efekt motyla w kodzie maszynowym.
 
Stosy sieciowe w przestrzeni użytkownika.
Stosy sieciowe w przestrzeni użytkownika.Stosy sieciowe w przestrzeni użytkownika.
Stosy sieciowe w przestrzeni użytkownika.
 
Złam zasady i stwórz wydajny stos IP przy użyciu DPDK
Złam zasady i stwórz wydajny stos IP przy użyciu DPDKZłam zasady i stwórz wydajny stos IP przy użyciu DPDK
Złam zasady i stwórz wydajny stos IP przy użyciu DPDK
 
Info meet pomiary wydajności
Info meet pomiary wydajnościInfo meet pomiary wydajności
Info meet pomiary wydajności
 
PLNOG16: DNS Catalog Zones łatwe tworzenie i synchronizacja serwowanych ...
PLNOG16: DNS Catalog Zones łatwe tworzenie i synchronizacja serwowanych ...PLNOG16: DNS Catalog Zones łatwe tworzenie i synchronizacja serwowanych ...
PLNOG16: DNS Catalog Zones łatwe tworzenie i synchronizacja serwowanych ...
 
Apache http server - proste i zaawansowane przypadki użycia
Apache http server - proste i zaawansowane przypadki użyciaApache http server - proste i zaawansowane przypadki użycia
Apache http server - proste i zaawansowane przypadki użycia
 
Sekrety magicznego ogrodu Docker
Sekrety magicznego ogrodu DockerSekrety magicznego ogrodu Docker
Sekrety magicznego ogrodu Docker
 
Ruby, Ruby on Rails 2010
Ruby, Ruby on Rails 2010Ruby, Ruby on Rails 2010
Ruby, Ruby on Rails 2010
 
PLNOG22: Tomasz Jarlaczyk & Tomasz Ludwiczak - DNSv6 i SSL - historie z życia...
PLNOG22: Tomasz Jarlaczyk & Tomasz Ludwiczak - DNSv6 i SSL - historie z życia...PLNOG22: Tomasz Jarlaczyk & Tomasz Ludwiczak - DNSv6 i SSL - historie z życia...
PLNOG22: Tomasz Jarlaczyk & Tomasz Ludwiczak - DNSv6 i SSL - historie z życia...
 

Semelhante a Allegro Tech Talks Poznań #4: Jak przyspieszyć SOLRa w kilku prostych krokach.

Praktyczne code reviews - PHPConPl
Praktyczne code reviews - PHPConPlPraktyczne code reviews - PHPConPl
Praktyczne code reviews - PHPConPlSebastian Marek
 
Empathy optymalizacja postgre_sql
Empathy optymalizacja postgre_sqlEmpathy optymalizacja postgre_sql
Empathy optymalizacja postgre_sqlSpodek 2.0
 
Confitura 2018 - Sekretne życie jobów Sparkowych
Confitura 2018 - Sekretne życie jobów SparkowychConfitura 2018 - Sekretne życie jobów Sparkowych
Confitura 2018 - Sekretne życie jobów SparkowychMarcin Jasiński
 
PLNOG22 - Piotr Stolarek - Bezpieczeństwo użytkowania platform usługowych Tel...
PLNOG22 - Piotr Stolarek - Bezpieczeństwo użytkowania platform usługowych Tel...PLNOG22 - Piotr Stolarek - Bezpieczeństwo użytkowania platform usługowych Tel...
PLNOG22 - Piotr Stolarek - Bezpieczeństwo użytkowania platform usługowych Tel...PROIDEA
 
Camel-Drools - Javarsovia 2010
Camel-Drools - Javarsovia 2010Camel-Drools - Javarsovia 2010
Camel-Drools - Javarsovia 2010Maciek Próchniak
 
Mysql - bad queries, find them all
Mysql - bad queries, find them allMysql - bad queries, find them all
Mysql - bad queries, find them allPiotr Suszalski
 
4Developers 2015: Property-based testing w języku Scala - Paweł Grajewski
4Developers 2015: Property-based testing w języku Scala - Paweł Grajewski4Developers 2015: Property-based testing w języku Scala - Paweł Grajewski
4Developers 2015: Property-based testing w języku Scala - Paweł GrajewskiPROIDEA
 
Agregacja i analiza logów
Agregacja i analiza logówAgregacja i analiza logów
Agregacja i analiza logówDivante
 
„Need for speed, czyli jak wycisnąć siódme poty z bazy PostgreSQL” - Wojciech...
„Need for speed, czyli jak wycisnąć siódme poty z bazy PostgreSQL” - Wojciech...„Need for speed, czyli jak wycisnąć siódme poty z bazy PostgreSQL” - Wojciech...
„Need for speed, czyli jak wycisnąć siódme poty z bazy PostgreSQL” - Wojciech...krakspot
 
semKRK #13 - Aneta i Dawid Krystosik
semKRK #13 - Aneta i Dawid KrystosiksemKRK #13 - Aneta i Dawid Krystosik
semKRK #13 - Aneta i Dawid KrystosiksemKRK
 
Wielomilonowy ruch na wordpressie wordpress wordcamp gdynia 2016
Wielomilonowy ruch na wordpressie   wordpress wordcamp gdynia 2016Wielomilonowy ruch na wordpressie   wordpress wordcamp gdynia 2016
Wielomilonowy ruch na wordpressie wordpress wordcamp gdynia 2016Lukasz Wilczak
 
tRPC - czy to koniec GraphQL?
tRPC - czy to koniec GraphQL?tRPC - czy to koniec GraphQL?
tRPC - czy to koniec GraphQL?Brainhub
 
Wielomilionowy Ruch na Wordpressie - Łukasz Wilczak & Piotr Federowicz (WordC...
Wielomilionowy Ruch na Wordpressie - Łukasz Wilczak & Piotr Federowicz (WordC...Wielomilionowy Ruch na Wordpressie - Łukasz Wilczak & Piotr Federowicz (WordC...
Wielomilionowy Ruch na Wordpressie - Łukasz Wilczak & Piotr Federowicz (WordC...Grand Parade Poland
 
SQLDay 2014 - Change Tracking & Change Data Capture
SQLDay 2014 - Change Tracking & Change Data CaptureSQLDay 2014 - Change Tracking & Change Data Capture
SQLDay 2014 - Change Tracking & Change Data CaptureKamil Nowinski
 
PLNOG 8: Lucjan Kisiel, Marcin Matyla - Router brzegowy z wydolnością 3 Gb ru...
PLNOG 8: Lucjan Kisiel, Marcin Matyla - Router brzegowy z wydolnością 3 Gb ru...PLNOG 8: Lucjan Kisiel, Marcin Matyla - Router brzegowy z wydolnością 3 Gb ru...
PLNOG 8: Lucjan Kisiel, Marcin Matyla - Router brzegowy z wydolnością 3 Gb ru...PROIDEA
 
CISSPDAY 2011 - 2 AM A Disaster just Began
CISSPDAY 2011 - 2 AM A Disaster just BeganCISSPDAY 2011 - 2 AM A Disaster just Began
CISSPDAY 2011 - 2 AM A Disaster just BeganTobias Koprowski
 
Elasticsearch i Docker - skalowalność, wysoka dostępność i zarządzanie zasobami
Elasticsearch i Docker - skalowalność, wysoka dostępność i zarządzanie zasobamiElasticsearch i Docker - skalowalność, wysoka dostępność i zarządzanie zasobami
Elasticsearch i Docker - skalowalność, wysoka dostępność i zarządzanie zasobamiEnterprise Search Warsaw Meetup
 

Semelhante a Allegro Tech Talks Poznań #4: Jak przyspieszyć SOLRa w kilku prostych krokach. (20)

SphinxSearch
SphinxSearchSphinxSearch
SphinxSearch
 
Jaki hosting pod wordpressa
Jaki hosting pod wordpressaJaki hosting pod wordpressa
Jaki hosting pod wordpressa
 
Praktyczne code reviews - PHPConPl
Praktyczne code reviews - PHPConPlPraktyczne code reviews - PHPConPl
Praktyczne code reviews - PHPConPl
 
Empathy optymalizacja postgre_sql
Empathy optymalizacja postgre_sqlEmpathy optymalizacja postgre_sql
Empathy optymalizacja postgre_sql
 
Confitura 2018 - Sekretne życie jobów Sparkowych
Confitura 2018 - Sekretne życie jobów SparkowychConfitura 2018 - Sekretne życie jobów Sparkowych
Confitura 2018 - Sekretne życie jobów Sparkowych
 
PLNOG22 - Piotr Stolarek - Bezpieczeństwo użytkowania platform usługowych Tel...
PLNOG22 - Piotr Stolarek - Bezpieczeństwo użytkowania platform usługowych Tel...PLNOG22 - Piotr Stolarek - Bezpieczeństwo użytkowania platform usługowych Tel...
PLNOG22 - Piotr Stolarek - Bezpieczeństwo użytkowania platform usługowych Tel...
 
Camel-Drools - Javarsovia 2010
Camel-Drools - Javarsovia 2010Camel-Drools - Javarsovia 2010
Camel-Drools - Javarsovia 2010
 
Mysql - bad queries, find them all
Mysql - bad queries, find them allMysql - bad queries, find them all
Mysql - bad queries, find them all
 
4Developers 2015: Property-based testing w języku Scala - Paweł Grajewski
4Developers 2015: Property-based testing w języku Scala - Paweł Grajewski4Developers 2015: Property-based testing w języku Scala - Paweł Grajewski
4Developers 2015: Property-based testing w języku Scala - Paweł Grajewski
 
Agregacja i analiza logów
Agregacja i analiza logówAgregacja i analiza logów
Agregacja i analiza logów
 
„Need for speed, czyli jak wycisnąć siódme poty z bazy PostgreSQL” - Wojciech...
„Need for speed, czyli jak wycisnąć siódme poty z bazy PostgreSQL” - Wojciech...„Need for speed, czyli jak wycisnąć siódme poty z bazy PostgreSQL” - Wojciech...
„Need for speed, czyli jak wycisnąć siódme poty z bazy PostgreSQL” - Wojciech...
 
semKRK #13 - Aneta i Dawid Krystosik
semKRK #13 - Aneta i Dawid KrystosiksemKRK #13 - Aneta i Dawid Krystosik
semKRK #13 - Aneta i Dawid Krystosik
 
Wielomilonowy ruch na wordpressie wordpress wordcamp gdynia 2016
Wielomilonowy ruch na wordpressie   wordpress wordcamp gdynia 2016Wielomilonowy ruch na wordpressie   wordpress wordcamp gdynia 2016
Wielomilonowy ruch na wordpressie wordpress wordcamp gdynia 2016
 
tRPC - czy to koniec GraphQL?
tRPC - czy to koniec GraphQL?tRPC - czy to koniec GraphQL?
tRPC - czy to koniec GraphQL?
 
Wielomilionowy Ruch na Wordpressie - Łukasz Wilczak & Piotr Federowicz (WordC...
Wielomilionowy Ruch na Wordpressie - Łukasz Wilczak & Piotr Federowicz (WordC...Wielomilionowy Ruch na Wordpressie - Łukasz Wilczak & Piotr Federowicz (WordC...
Wielomilionowy Ruch na Wordpressie - Łukasz Wilczak & Piotr Federowicz (WordC...
 
Platforma Kontentowa
Platforma KontentowaPlatforma Kontentowa
Platforma Kontentowa
 
SQLDay 2014 - Change Tracking & Change Data Capture
SQLDay 2014 - Change Tracking & Change Data CaptureSQLDay 2014 - Change Tracking & Change Data Capture
SQLDay 2014 - Change Tracking & Change Data Capture
 
PLNOG 8: Lucjan Kisiel, Marcin Matyla - Router brzegowy z wydolnością 3 Gb ru...
PLNOG 8: Lucjan Kisiel, Marcin Matyla - Router brzegowy z wydolnością 3 Gb ru...PLNOG 8: Lucjan Kisiel, Marcin Matyla - Router brzegowy z wydolnością 3 Gb ru...
PLNOG 8: Lucjan Kisiel, Marcin Matyla - Router brzegowy z wydolnością 3 Gb ru...
 
CISSPDAY 2011 - 2 AM A Disaster just Began
CISSPDAY 2011 - 2 AM A Disaster just BeganCISSPDAY 2011 - 2 AM A Disaster just Began
CISSPDAY 2011 - 2 AM A Disaster just Began
 
Elasticsearch i Docker - skalowalność, wysoka dostępność i zarządzanie zasobami
Elasticsearch i Docker - skalowalność, wysoka dostępność i zarządzanie zasobamiElasticsearch i Docker - skalowalność, wysoka dostępność i zarządzanie zasobami
Elasticsearch i Docker - skalowalność, wysoka dostępność i zarządzanie zasobami
 

Mais de allegro.tech

allegro.tech Data Science Meetup #2: Elasticsearch w praktyce
allegro.tech Data Science Meetup #2: Elasticsearch w praktyceallegro.tech Data Science Meetup #2: Elasticsearch w praktyce
allegro.tech Data Science Meetup #2: Elasticsearch w praktyceallegro.tech
 
Scaling infrastructure beyond containers
Scaling infrastructure beyond containersScaling infrastructure beyond containers
Scaling infrastructure beyond containersallegro.tech
 
Confitura 2015 - Mikrousługi nie lubią być samotne
Confitura 2015 - Mikrousługi nie lubią być samotneConfitura 2015 - Mikrousługi nie lubią być samotne
Confitura 2015 - Mikrousługi nie lubią być samotneallegro.tech
 
Microservices architecture pitfalls
Microservices architecture pitfallsMicroservices architecture pitfalls
Microservices architecture pitfallsallegro.tech
 
RxJava - introduction & design
RxJava - introduction & designRxJava - introduction & design
RxJava - introduction & designallegro.tech
 
JDD 2014: Adam Dubiel - Import allegro.tech.internal.*
JDD 2014: Adam Dubiel - Import allegro.tech.internal.*JDD 2014: Adam Dubiel - Import allegro.tech.internal.*
JDD 2014: Adam Dubiel - Import allegro.tech.internal.*allegro.tech
 
Fighting with scale
Fighting with scaleFighting with scale
Fighting with scaleallegro.tech
 

Mais de allegro.tech (7)

allegro.tech Data Science Meetup #2: Elasticsearch w praktyce
allegro.tech Data Science Meetup #2: Elasticsearch w praktyceallegro.tech Data Science Meetup #2: Elasticsearch w praktyce
allegro.tech Data Science Meetup #2: Elasticsearch w praktyce
 
Scaling infrastructure beyond containers
Scaling infrastructure beyond containersScaling infrastructure beyond containers
Scaling infrastructure beyond containers
 
Confitura 2015 - Mikrousługi nie lubią być samotne
Confitura 2015 - Mikrousługi nie lubią być samotneConfitura 2015 - Mikrousługi nie lubią być samotne
Confitura 2015 - Mikrousługi nie lubią być samotne
 
Microservices architecture pitfalls
Microservices architecture pitfallsMicroservices architecture pitfalls
Microservices architecture pitfalls
 
RxJava - introduction & design
RxJava - introduction & designRxJava - introduction & design
RxJava - introduction & design
 
JDD 2014: Adam Dubiel - Import allegro.tech.internal.*
JDD 2014: Adam Dubiel - Import allegro.tech.internal.*JDD 2014: Adam Dubiel - Import allegro.tech.internal.*
JDD 2014: Adam Dubiel - Import allegro.tech.internal.*
 
Fighting with scale
Fighting with scaleFighting with scale
Fighting with scale
 

Allegro Tech Talks Poznań #4: Jak przyspieszyć SOLRa w kilku prostych krokach.

  • 1. Jak przyspieszyć SOLRa w kilku prostych krokach Przemysław Szeremiota Adam Dudczak
  • 2.
  • 3. od 33 do 40 mln wyszukiwań na dobę
  • 4. 54 000 000 dokumentów/ofert w indeksie
  • 6. SOLR w Allegro to 44 piękne kobiety m[16-62]—c[4-20]-d[12-100]
  • 7. p50 = 91 ms throughput = 85k rpm 2015
  • 8. 2016 p50 = 20 ms throughput = 116k rpm
  • 9. SOLR w Allegro to 44 piękne kobiety SOLR w Allegro to ponad 100 serwerów
  • 10. SOLR w Allegro to 44 piękne kobiety SOLR w Allegro to ponad 100 serwerów 15 mln komunikatów dziennie dodatkowe 10k komunikatów na sekundę
  • 11. SOLR w Allegro to 44 piękne kobiety SOLR w Allegro to ponad 100 serwerów p99 czasów odpowiedzi 300ms p99 czasów odpowiedzi >1000ms 15 mln komunikatów dziennie dodatkowe 10k komunikatów na sekundę
  • 12. SOLR w Allegro to 44 piękne kobiety SOLR w Allegro to ponad 100 serwerów p99 czasów odpowiedzi 300ms p99 czasów odpowiedzi >1000ms Indeks o wielkości 20GB Indeks o wielkości 40GB 15 mln komunikatów dziennie dodatkowe 10k komunikatów na sekundę
  • 13. Silniki wyszukiwawcze w Allegro.pl 1. Apache SOLR standalone jako podstawa głównych indeksów naszej wyszukiwarki (11 indeksów) 2. Cluster SOLR CLOUD wykorzystywany do indeksów pomocniczych (10 indeksów) 3. Kilkadziesiąt clustrów Elastic Search wykorzystywany przez zespoły developerskie jako rozwiązanie as a service 13
  • 15. BEZ PRACY… 15 schemaless (adjective sche·ma·less -ləs): definiowanie schematu bezwiednie, nieświadomie • Ułatwia szybką implementację wyszukiwarki w aplikacji • Nieźle nadaje się do niektórych typowych/modnych zastosowań wyszukiwarek (logi, time-series)
  • 16. … NIE MA KOŁACZY! 16 • Schemat w SOLR istnieje zawsze • Projektowanie schematu: projektowanie podstaw funkcjonalności wyszukiwarki • Trafność wyników wymaga słowników, synonimów, sprytnych sposobów indeksowania, tokenizerów, filtrów, analizatorów… • Szlifowanie schematu: szlifowanie skuteczności i wydajności wyszukiwarki (pola indeksowane/pola docValues)
  • 17. KAŻDY SZCZEGÓŁ SIĘ LICZY 17 “Od rana już czymś niedobrym pachniało w powietrzu”
  • 18. KAŻDY SZCZEGÓŁ SIĘ LICZY 18 • Pola przeznaczone do wyszukiwania pełnotekstowego (indeksowane) • Pola przeznaczone do sortowania (docValues?) • Pola przeznaczone do facetingu (docValues?) • Pola wykorzystywane w filtrach (indeksowane/docValues)
  • 19. To cache or not to cache?
  • 20. TO CACHE OR NOT TO CACHE? 20 • document cache — cache pól składowanych odsyłanych w ramach wyników zapytania • query cache — cache całych wyników, z opcją “nadmiaru” • filter cache — cache “filtrów” (zapytań cząstkowych) Trzy gotowce do cachowania w SOLR:
  • 21. TO CACHE OR NOT TO CACHE? 21 • Przyspiesza odsyłanie wyników, ale może lepiej nie odsyłać kompletnych dokumentów, tylko identyfikatory do udekorowania na froncie? • Przechowywać w nim całe dokumenty, czy tylko wybrane pola? Cache dokumentów <documentCache class="solr.LFUCache" size="10" initialSize="1" autowarmCount="1"/>
  • 22. TO CACHE OR NOT TO CACHE? 22 • Wyniki zapytań gotowe do ponownego użycia, ale czy potrafimy wycelować w ten sam backend? • Opcja “nadmiaru” przyspiesza pobieranie następnej strony wyników, ale czy potrafimy wycelować w ten sam backend? Cache zapytań <queryResultCache class="solr.LFUCache" size="50" initialSize="50" autowarmCount="50"/>
  • 23. TO CACHE OR NOT TO CACHE? 23 • Wyniki cząstkowe gotowe do ponownego użycia • Niezbędny do operacji facetingu Cache filtrów <filterCache class="solr.LFUCache" size="600" initialSize="600" autowarmCount=“600" /> /select?q=name:nokia&fq=price:[30 TO 50] /select?q=name:iphone&fq=published:[NOW-1DAY TO NOW] /select?q=name:nokia&fq=price:[30 TO 40]&fq=type:auction
  • 24. TO CACHE OR NOT TO CACHE? 24 • Duża wariancja w czasach wykonania dla nietrafionych zapytań/ filtrów • Pamięć JVM • CPU/czas w GC • CPU/czas przy kompletowaniu zbioru wynikowego filtra Koszt intensywnego cache-owania
  • 25. TO CACHE… 25 <queryResultCache class="solr.LFUCache" size="100" initialSize="50" autowarmCount=“50"/> <documentCache class="solr.FastLRUCache" size="100000" initialSize="50000" autowarmCount="50000"/> <filterCache class="solr.LFUCache" size="3000" initialSize="600" autowarmCount="600"/> rps:126.316667 max:7969 avg:54 p50:3 p75:7 p90:25 p95:58 p99:1160 pp95:3555 pp99:6838 rps:130.083333 max:9279 avg:127 p50:4 p75:11 p90:62 p95:178 p99:4782 pp95:6115 pp99:7882 rps:146.816667 max:9060 avg:39 p50:4 p75:8 p90:30 p95:67 p99:1401 pp95:1896 pp99:3636 rps:145.050000 max:4367 avg:31 p50:3 p75:8 p90:27 p95:58 p99:1087 pp95:1713 pp99:2306 rps:160.683333 max:4956 avg:38 p50:4 p75:10 p90:31 p95:68 p99:1365 pp95:2080 pp99:2809 CPU: ~60% GC TIME: ~1.8s/min FilterCache: 82% (inserts: ~7K, lookups: ~45K, evictions: ~5K) QueryResultCache: 2% (inserts: ~40K, lookups: ~42K, evictions: ~40K)
  • 27. …NOT TO CACHE 27 <queryResultCache class="solr.LFUCache" size="50" initialSize="50" autowarmCount="50"/> <documentCache class="solr.FastLRUCache" size="10" initialSize="1" autowarmCount="1"/> <filterCache class="solr.LFUCache" size="600" initialSize="600" autowarmCount="600"/> rps:167.466667 max:7028 avg:8 p50:2 p75:5 p90:15 p95:25 p99:79 pp95:135 pp99:467 rps:156.833333 max:2388 avg:10 p50:2 p75:6 p90:18 p95:31 p99:109 pp95:215 pp99:869 rps:157.566667 max:1499 avg:6 p50:2 p75:6 p90:15 p95:25 p99:72 pp95:121 pp99:439 rps:141.750000 max:4752 avg:7 p50:2 p75:6 p90:17 p95:27 p99:76 pp95:131 pp99:287 rps:159.700000 max:4869 avg:9 p50:2 p75:5 p90:15 p95:27 p99:80 pp95:148 pp99:802 CPU: ~20% GC TIME: ~200ms/min FilterCache: 93% (inserts: ~1K, lookups: ~12K, evictions: ~0.5K) QueryResultCache: 2% (inserts: ~40K, lookups: ~42K, evictions: ~40K)
  • 28. NOT TOO CACHE!!! 28 • Wyniki zapytań lepiej cachować na load-balancerach • Do pobierania następnych stron lepiej użyć mechanizmu cursor- mark • Filtry nieselektywne lepiej wyznaczać w obrębie query fq={!cache=false}type:auction • Filtry częstozmienne lepiej wyznaczać w trybie postfilter fq={!frange cache=false cost=100 l=30 u=50}price
  • 30. DocValue nie tylko do sort/facetingu “DocValues are a way of recording field values internally that is more efficient for some purposes, such as sorting and faceting, than traditional indexing.” 30
  • 31. DocValues, ale o co chodzi? tytuł: nokia -> 1, 3, 5, 6, 7 lumia -> 3, 5, cena: 120 -> 1 140 -> 3 500 -> 5 … query: nokia lumia sort: cena ASC 31
  • 32. DocValues, ale o co chodzi? tytuł: nokia -> 1, 3, 5, 6, 7 lumia -> 3, 5, cena: 120 -> 1 140 -> 3 500 -> 5 … pasujące wyniki: 3,5 32 Indeks odwrotny rządzi!
  • 33. ale co z sortowaniem? wyniki: 3, 5 cena: 140 -> 3, 6 500 -> 5, 10 … cena_sort: 3 -> 140 5 -> 500 … 33 W przypadku indeksu odwrotnego musimy przejrzeć całą listę termów i znaleźć interesujące nas dokumenty
  • 34. DocValues • Dostępne w Lucene od wersji 4.0 • Polecane szczególnie do sortowania, facetowania, highligthingu • Pozwalają bez większego problemu pobierać wartości z indeksu <field name="state" type="string" indexed="false" stored="false" docValues="true" /> 34
  • 35. DocValues świetnie sprawdzają się w postfiltrach! 35
  • 36. Postfiltry - krótkie wprowadzenie • Postfiltr to filtr wykonywany po zakończeniu przetwarzania kryteriów z q i fq • Ewaluowane kryterium może zawierać “kosztowną” logikę związaną z zawartością dokumentu lub kontekstem użytkownika &fq={!cache=false cost=200}price:200 &fq={!frange l=300 cache=false cost=200}price &fq={!frange l=5 cache=false cost=200}div(log(popularity),sqrt(geodist())) 36 (source: http://yonik.com/advanced-filter-caching-in-solr/)
  • 37. A jak to się ma do DocValues? 37
  • 39. Na deser… • Możliwość modyfikacji DocValues in place, bez konieczności reindeksacji całego dokumentu. • Narazie testujemy… 39
  • 41. Dlaczego sortowanie indeksu? • Sortowanie indeksu to zabójcza kombinacja w połączeniu z Early Terminating Collectorem. O co chodzi? 41
  • 42. Indeks bez sortowania Segment 1: - dokument 4: cena 430 - dokument 1: cena 100 - dokument 5: cena 540 Segment 2: - dokument 6: cena 510 - dokument 3: cena 110 - dokument 2: cena 440 query: *:*, sort: cena ASC, rows=2 42 Musimy przejrzeć cały indeks, żeby znaleźć 2 najtańsze przedmioty
  • 43. Indeks posortowany po cenie Segment 1: - dokument 1: cena 100 - dokument 4: cena 430 - dokument 5: cena 540 Segment 2: - dokument 3: cena 110 - dokument 2: cena 440 - dokument 6: cena 510 query: *:*, sort: cena ASC, rows=2 43 Nie musimy przetwarzać wszystkiego
  • 44. Jak to wywołać? <indexConfig> ... <mergePolicyFactory class="org.apache.solr.index.SortingMergePolicyFactory"> <str name="sort">promoted desc,category1 desc,variant_id desc</str> <str name="wrapped.prefix">inner</str> <str name=“inner.class"> org.apache.solr.index.TieredMergePolicyFactory </str> <int name="inner.segmentsPerTier">2</int> <int name="inner.maxMergeAtOnce">7</int> <int name="inner.maxMergedSegmentMB">12288</int> <int name="inner.forceMergeDeletesPctAllowed">5</int> </mergePolicyFactory> ... </indexConfig> 44
  • 45. Dlaczego sortowanie indeksu? • W praktyce niezbyt przydatne • Jeden porządek sortowania w indeksie • Wiele metod sortowania w aplikacji • Ograniczona użyteczność Early Terminating Collectora w przypadku wielu porządków sortowania 45
  • 46. Czasem niespodzianki potrafią być miłe… Rozmiar indeksu się zmniejszył, dzięki temu wszystko zaczęło działać szybciej i zjadało mniej zasobów. 46
  • 47. Bądź świadomy tego jak ludzie korzystają z Twojej wyszukiwarki!
  • 48. Stabilność przede wszystkim • Profil wykorzystania wyszukiwarki • Większości przypadków użytkownicy przechodzą od zapytań ogólnych do szczegółowych (dodają filtry, zmieniają frazę) • Oglądają nie więcej niż 20 stron wyników • To jest nasz biznes! 48
  • 49. Apache Solr i dalekie strony • Apache Solr w przypadku przeglądania dalekich strony wyników nie radzi sobie tak jakbyśmy chcieli • Im dalej… tym wolniej i drożej •start=0, rows=10 •start=1000, rows=10 •start=10000, rows=10 49
  • 50. Separuj zapytania • Zapytania o dalsze strony są kierowane do dedykowanej puli maszyn • Zapytania o ciężkie porządki sortowania do dedykowanej puli maszyn 50
  • 52. Allegro SOLR-PLUGINS 52 • Gdzie umiejscowić optymalizacje? • Frontend? • API? • Backend (SOLR)? • SOLR oferuje sporo “gniazdek” do przyłączania funkcjonalności: • parsery, collectory • komponenty obsługi zapytań • procesory dokumentów i wyników zapytań
  • 53. Allegro SOLR-PLUGINS 53 • SearchComponent • prepare(request) • process(response) • UpdateRequestProcessor • processAdd(cmd) • processDelete(cmd) • … • QParser • parse(query)
  • 54. Allegro SOLR-PLUGINS 54 <requestHandler name="/select" class="solr.SearchHandler"> <arr name="components"> <str>optimizer</str> <str>query</str> <str>facet</str> </arr> </requestHandler> <searchComponent name="optimizer" class=“pl.allegro…ScriptedSearchComponent”> <arr name="script"> <str name="script">optimizer/optimizer.js</str> </arr> </searchComponent>
  • 55. Allegro SOLR-PLUGINS 55 load('…/optimizer/query-params.js'); var nocache = load(‘…/optimizer/nocache-rewriter.js’)(['seller', 'category', 'latitude', 'longitude']); function prepare(request) { var query = getQuery(request); // from query-params.js query.fq = nocache(query.fq)); // from nocache-rewriter.js setQuery(query); logger.debug('optimized: {}', request); } function process(response) { logger.debug('process: ' + response); }
  • 56. Allegro SOLR-PLUGINS 56 function nocacheRewriter(fields) { fields = fields || [ 'seller', 'price' ]; var NOCACHEFQ = new RegExp(‘^(?:{!(tag=w+)})?((?:' + fields.join(‘|') + '):(?:[^&]+))$'); return function(filters) { return filters.map(function(filter) { return filter.replace(NOCACHEFQ, function(match, tag, filter) { return tag ? '{!cache=false ' + tag + '}' + filter : '{!cache=false}' + filter; }); }); } }
  • 58. Motywacja • Nie dajemy rady indeksować sygnałów zaangażowania w Lucene • SOLR-owy mechanizm ExternalFileField jest powolny • Mimo wstrętu do programowania, trza było zakasać rękawy 58
  • 59. Sorted binary file field • Sygnał zaangażowania to offerID -> wartość • Lucene operuje na relacjach luceneID -> offer • W Lucene relacja offerID -> luceneID jest niestała 59 offerID -> luceneID? luceneID -> offerID?
  • 60. luceneID offerID name category bidcount 1 1432 nokia Telefony 0 2 5760 audi Moto 0 3 9811 nike Moda 0 offerID listed 1432 60 5760 22 9811 342 lucene sort_by(“listed”): foreach (luceneID in docset): docset[luceneID].sortVal = listedSource.getValue(luceneID) sort(docset, .sortVal) luceneID offerID name category bidcount 1 1432 nokia Telefony 0 2 5760 audi Moto 0 3 9811 nike Moda 0 4 1432 nokia Telefony 1
  • 61. Jak działa ExternalFileField? 61 reload() getValue(luceneID) foreach (row in engagement_file): { offerID, value } = row.split(“=“) luceneID = lucene.find("offerID", offerID) vals[luceneID] = value return vals[luceneID]
  • 62. Binary Sort File Field 62 reload() getValue(luceneID) eng = mmap(engagement_file) if (vals[luceneID]): return vals[luceneID] else: id = lucene.get(“offerID”, luceneID) return vals[luceneID] = bsearch(eng, id).value
  • 63. ExternalFileField SortedBinaryFileField Wczytywanie wartości trwa wieki Wczytywanie wartości trwa okamgnienie Mapowanie on-heap float[numDocs] Mapowanie off-heap, opcjonalnie on-heap offerId->luceneID luceneID->offerID
  • 64. Sorted Binary File Field <fieldType name="external_defval_0" cache="true" keyField="doc_id" defVal="0" class="pl.allegro.bestmatch.solr.SortedBinaryFileField" valType="float" /> <field name="click_ratio" type="external_defval_0" /> 64
  • 65. Sorted Binary File Field - przygotowanie Wartości: 1;3 2;56 3;89 from struct import pack import sys import json for line in sys.stdin: try: vals = line.split(';') sys.stdout.write(pack('>qf', long(vals[0]), float(vals[1]))) except: sys.stderr.write("error: " + line) 65
  • 66. Sorted Binary File Field Wyliczanie sygnałów zaangażowania odbywa się offline (np. Hadoop/MapReduce) Umożliwia wynoszenie z indeksu innych często zmiennych pól (cena? sztuk?) Umożliwia stosunkowo łatwe importowanie dodatkowych sygnałów 66
  • 67. Do czego wykorzytujemy? • Liczba odsłon oferty na listingu • Liczba dodań oferty do koszyków • Liczba dodań oferty do obserwowanych • Liczba odsłon oferty • Ocena sprzedawcy • Jakość obrazków oferty 67
  • 69. Czy mogę tego użyć? • Tak… prawie… już niedługo na githubie ;-) 69
  • 70. Pytania? Pytania? Przemysław Szeremiota / Damian Parus / Wojtek Stryszyk / Tomek Jackowiak / Adam Dudczak imię.nazwisko@allegrogroup.com Poznań, 6 kwietnia 2017