2013-08-16 11 views
6

Ich verwende Elasticsearch indizieren zwei Arten von Objekten -Elasticsearch Abfrageleistung

Daten Details

Contract Objekt ~ 60 Objekte (Objektgröße - 120 Byte) Risiko Item-Objekt ~ 125 Objekte (Objektgröße - 250 Byte)

Vertrag ist übergeordnete Risikoposition (_parent)

ich bin 240 Millionen solcher Objekte in einzelnen Index (210 Millionen Risikopositionen zu speichern, 30 Millionen Verträge)

Index Größe - 322 gb

Cluster Details

11 m2.4x.large EC2-Boxen [68 GB Speicher, 1,6 TB Speicher, 8 Kerne] (1 Box ein Lastverteilungs-Knoten mit node.data = false) 50 shards 1 Replika

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 

ich die Elasticsearch Knoten mit folgendem Befehl bin ab - /home/ec2-user/elasticsearch-0.90.2/bin/elasticsearch -f -Xms30g -Xmx30g

Mein Problem ist, dass ich bin Es wird eine Abfrage nach dem Risikotyp ausgeführt, und es dauert etwa 10 bis 15 Sekunden, um Daten für 20 Datensätze zurückzugeben.

Ich führe dies mit einer Last von 50 gleichzeitigen Benutzern und einer Massenindexlast von ungefähr 5000 Risikoelementen, die parallel passieren.

Abfrage (mit Join Eltern-Kind)

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" 
         } 
        }] 
       } 
      } 
     }] 
    } 
} 

Abfragen aus einer Tabelle

Query1 (Diese Abfrage dauert ungefähr 8 Sekunden.)

<!-- 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" 
         } 
        }] 
       } 
      } 
     } 
    } 

Kann mir bitte jemand helfen, wie ich diese Abfrageleistung verbessern kann?

+0

Ich bin an der Antwort interessiert. Haben Sie andere Arten von Beziehungen zwischen Ihren Dokumenten versucht? Ich beziehe mich auf verschachtelte Objekte. Ich könnte falsch liegen, aber ich würde sagen, dass die Eltern-Kind-Beziehung eine Art "Query-Join" ist. Verschachtelte Objekte befinden sich im selben Lucene-Block, sodass sie für Suchanfragen möglicherweise schneller sind. – jackdbernier

+0

Ich habe auch eine Frage ... Warum 'Xms30g -Xmx30g' und nicht mehr? – jackdbernier

+0

Objekte sind sehr groß und verschachtelte Objekte benötigen viel Platz. – Vishal

Antwort

3

Haben Sie versucht, benutzerdefinierte Routing? Ohne benutzerdefiniertes Routing muss Ihre Abfrage in allen 50 Shards nach Ihrer Anfrage suchen. Mit benutzerdefiniertem Routing erkennt Ihre Abfrage, welche Shards durchsucht werden sollen, wodurch Abfragen leistungsfähiger werden. Mehr here.

Sie können jedem Bulk-Element ein benutzerdefiniertes Routing zuweisen, indem Sie einen Routing-Wert mit dem Feld _routing eingeben, wie in bulk api docs beschrieben.

+1

Welche anderen Optionen haben wir außer dem benutzerdefinierten Routing? – Vishal

+0

Wie jackdbernier in seinem Kommentar erwähnt, würde die Erhöhung Ihrer Heap-Größe die Leistung verbessern. Dieser [thread] (http://elasticsearch-users.115913.n3.nabble.com/Slow-Query-Performance-td4024165.html) ist jetzt fast ein Jahr alt, aber seine Informationen sind wahrscheinlich immer noch gut. Zum Beispiel schlägt das Elasticsearch-Team vor, heap_size auf 60% des Gesamtspeichers zu setzen. Versuchen Sie in Ihrem Fall, den Heap auf 40 g zu erhöhen. –

+0

Nur mit 41 GB Heap-Größe versucht und immer noch die gleichen Ergebnisse. – Vishal

1

Wir haben Änderungen mit Hilfe von Bitsets vorgenommen.

Wir haben 50 gleichzeitige Benutzer (Read Only) für eine Stunde ausgeführt.Alle unsere Abfragen führen 4- bis 5-mal schneller aus, außer dass die Abfrage des übergeordneten untergeordneten Elements (fragliche Abfrage) von 7 Sekunden auf 3 Sekunden gesunken ist.

Ich habe noch eine Abfrage mit has_child drin. Jeder andere hat andere Rückmeldungen, wir können diese oder andere Fragen weiter verbessern.

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

Kann jemand bitte kommentieren/helfen? – Vishal

+0

Ersetzen Sie grundsätzlich Ihre AND/OR-Filter durch BOOL. Um Vorteile von Bitsets zu nutzen. KEINE Ahnung warum, aber tu es einfach und schau, ob es schneller ist. –

Verwandte Themen