2013-08-16 18 views
6

Używam elasticsearch do indeksu dwa typy obiektów - SzczegółyElasticsearch wydajność kwerendy

danych

Kontrakt obiektów ~ 60 właściwości (wielkość obiektu - 120 bajtów) ryzykiem pozycji obiektów ~ 125 właściwości (wielkość obiektu - 250 bajtów)

Zamówienie jest rodzicem elementu ryzyka (_parent)

mam przechowującej 240 milionów takich obiektów w pojedynczym index (210 milionów elementów ryzyka, 30 milionów umowy)

wielkość indeksu jest - 322 pl

dane Cluster

11 pudełka m2.4x.large EC2 [pamięci 68 pl, 1,6 TB na rdzenie, 8] (1 opakowanie jest węzeł równoważenia obciążenia w node.data = fałsz) 50 odłamki 1 repliki

elasticsearch.yml

node.data: true 
http.enabled: false 
index.number_of_shards: 50 
index.number_of_replicas: 1 
index.translog.flush_threshold_ops: 10000 
index.merge.policy.use_compound_files: false 
indices.memory.index_buffer_size: 30% 
index.refresh_interval: 30s 
index.store.type: mmapfs 
path.data: /data-xvdf,/data-xvdg 

Zaczynam węzły elasticsearch z poleceniem - /home/ec2-user/elasticsearch-0.90.2/bin/elasticsearch -f -Xms30g -Xmx30g

Moim problemem jest to, że jestem uruchamianie następujących kwerend na typ elementu ryzyka i zajmuje około 10-15 sekund, aby zwrócić dane, na 20 rekordów.

Używam tego z obciążeniem 50 równoczesnych użytkowników i obciążeniem indeksu zbiorczego około 5000 elementów ryzyka występujących równolegle.

Zapytanie (Z Dołącz rodzic dziecka)

http: //: 9200/contractindex/riskitem/_search *

{ 
    "query": { 
     "has_parent": { 
      "parent_type": "contract", 
      "query": { 
       "range": { 
        "ContractDate": { 
         "gte": "2010-01-01" 
        } 
       } 
      } 
     } 
    }, 
    "filter": { 
     "and": [{ 
      "query": { 
       "bool": { 
        "must": [{ 
         "query_string": { 
          "fields": ["RiskItemProperty1"], 
          "query": "abc" 
         } 
        }, 
        { 
         "query_string": { 
          "fields": ["RiskItemProperty2"], 
          "query": "xyz" 
         } 
        }] 
       } 
      } 
     }] 
    } 
} 

Zapytania z jednej tabeli

QUERY1 (To zapytanie trwa około 8 sekund.)

<!-- language: lang-json --> 

    { 
     "query": { 
      "constant_score": { 
       "filter": { 
        "and": [{ 
         "term": { 
          "CommonCharacteristic_BuildingScheme": "BuildingScheme1" 
         } 
        }, 
        { 
         "term": { 
          "Address_Admin2Name": "Admin2Name1" 
         } 
        }] 
       } 
      } 
     } 
    } 



**Query2** (This query takes around 6.5 seconds for Top 10 records (but has sort on top of it) 

<!-- language: lang-json --> 

    { 
     "query": { 
      "constant_score": { 
       "filter": { 
        "and": [{ 
         "term": { 
          "Insurer": "Insurer1" 
         } 
        }, 
        { 
         "term": { 
          "Status": "Status1" 
         } 
        }] 
       } 
      } 
     } 
    } 

Czy ktoś może mi pomóc, w jaki sposób mogę poprawić wydajność tego zapytania?

+0

Jestem również zainteresowany odpowiedzią. Czy próbowałeś innych rodzajów relacji między swoimi dokumentami? Mam na myśli obiekty zagnieżdżone. Mogę się mylić, ale powiedziałbym, że relacja rodzic-dziecko jest rodzajem "połączenia zapytań". Zagnieżdżone obiekty znajdują się w tym samym bloku Lucene, więc może być szybsze dla zapytań. – jackdbernier

+0

Mam również pytanie ... Dlaczego 'Xms30g -Xmx30g' i nie więcej? – jackdbernier

+0

obiekty są bardzo duże, a obiekty zagnieżdżone wymagałyby dużo miejsca. – Vishal

Odpowiedz

3

Czy próbowałeś niestandardowego routingu? Bez niestandardowego routingu zapytanie musi zawierać wszystkie 50 odłamków dla Twojego zapytania. Dzięki niestandardowemu routingowi Twoje zapytanie wie, które pliki do przeszukania sprawiają, że zapytania są bardziej wydajne. Więcej here.

Możesz przypisać niestandardowe trasy do każdego artykułu objętego zbiorami, włączając w to wartość routingu w polu _routing, zgodnie z opisem w bulk api docs.

+1

Jakie inne opcje mamy poza routingiem niestandardowym? – Vishal

+0

Jak wspomniał o tym jackdbernier w swoim komentarzu, zwiększenie wielkości sterty pomogłoby w osiągnięciu wydajności. Ten [wątek] (http://elasticsearch-users.115913.n3.nabble.com/Slow-Query-Performance-td4024165.html) ma teraz prawie rok, ale jego informacje prawdopodobnie nadal są dobre. Na przykład zespół Elasticsearch sugeruje tutaj, aby ustawić heap_size na 60% ogólnej pamięci. W takim przypadku spróbuj zwiększyć swój stertę do 40g. –

+0

Po prostu próbowałem z 41 gb wielkości sterty i nadal takie same wyniki. – Vishal

1

Wprowadziliśmy zmiany za pomocą zestawów bitowych.

Uruchomiliśmy 50 jednoczesnych użytkowników (tylko do odczytu) przez godzinę.Wszystkie nasze zapytania są wykonywane od 4 do 5 razy szybciej, z wyjątkiem zapytania rodzica podrzędnego (zapytanie, którego dotyczy zapytanie), które uległo zmniejszeniu z 7 sekund do 3 sekund.

Mam jeszcze jedno zapytanie z has_child w nim. Każdy, kto ma jakąkolwiek inną opinię, możemy dalej ulepszyć tę lub inne zapytania.

{ 
    "query": { 
     "filtered": { 
      "query": { 
       "bool": { 
        "must": [{ 
         "match": { 
          "LineOfBusiness": "LOBValue1" 
         } 
        }] 
       } 
      }, 
      "filter": { 
       "has_child": { 
        "type": "riskitem", 
        "filter": { 
         "bool": { 
          "must": [{ 
           "term": { 
            "Address_Admin1Name": "Admin1Name1" 
           } 
          }] 
         } 
        } 
       } 
      } 
     } 
    } 
} 
+0

Czy ktokolwiek może komentować/pomóc? – Vishal

+0

Zasadniczo zamień filtry AND/OR na BOOL. Aby skorzystać z bitsetów. Nie mam pojęcia dlaczego, ale po prostu zrób to i sprawdź, czy jest szybszy. –

Powiązane problemy