Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Come integrare Elasticsearch e dormire sonni tr...

martino
April 17, 2016

Come integrare Elasticsearch e dormire sonni tranquilli

Some hints on how to use elastic search in your django stack

martino

April 17, 2016
Tweet

More Decks by martino

Other Decks in Programming

Transcript

  1. Atoka ❤ ES Siti web 150 GB Aziende 180 GB

    News 40 GB 170 milioni di documenti 210 milioni di documenti 27 milioni di documenti
  2. { "name" : "Arides", "cluster_name" : "martino-es", "version" : {

    "number" : "2.3.1", "build_hash" : "bd980929010aef404e7 "build_timestamp" : "2016-04-04T12: "build_snapshot" : false, "lucene_version" : "5.5.0" }, "tagline" : "You Know, for Search" } You Know, for Search Download it Extract it Run Elasticsearch Enjoy it
  3. PUT /companies/company/1 { "nomeLegale": "ACME S.R.L.”, "partitaIVA": "02241890223", "ragioneSociale": "Società

    A Responsabilità Limitata", "dataDiFondazione": “2012-02-13", "sedeLegale": { "coordinate": { "lon": 11.10781231, "lat": 46.06241231 }, "indirizzo": { "indirizzoCompleto": "Via dei serpenti, 13, 38122, Trento (TN)", "provincia": "Trento", "cap": "38122", "comune": "Trento", "stato": "Italia" } }, "keywords": [ "python", "django", "big data" ] } { "_index": "companies", "_type": "company", "_id": "1", "_version": 1, "_shards": { "total": 2, "successful": 1, "failed": 0 }, "created": true } Indexing
  4. Full-text Multifield Geo Point Geo Hashes Proximity matching Partial matching

    Query GET /companies/company/_search { "query": { "multi_match": { "query": "Super azienda", "fields": ["nomeLegale^3", "insegne"] } } } GET /companies/company/_search?q=descrizione:bar* bar | baretto | barbaforte GET /companies/company/_search?q=descrizione:bur~ bar | bur GET /companies/company/_search?q=descrizione:"bar rossi"~1 bar dei rossi | bar mario rossi | bar gino rossi
  5. Aggregations GET companies/company/_search { "aggs": { "comuni": { "terms": {

    "field": “sedi.comune", "size": 10 } } } } { "took": 180, "aggregations": { "comuni": { "buckets": [ { "key": "roma", "doc_count": 343969 }, { "key": "milano", "doc_count": 233817 }, { "key": "napoli", "doc_count": 107456 }, {
  6. Aggregations / 2 GET companies/company/_search { "query": { "term": {

    "flags": "startup" } }, "aggs": { "keywords": { "significant_terms": { "field": "websiteMetaKeywords" } } } } { "took": 27, "aggregations": { "keywords": { "doc_count": 5358, "buckets": [ { "key": "startup", "score": 46.3063793145 }, { "key": "wearable", "score": 11.8933947021 }, { "key": "spinoff", "score": 11.4179948602 },
  7. Query driven document design { "dipendente" : [ { "nome"

    : "Mario", "cognome" : "Rossi" }, { "nome" : "Roberto", "cognome" : "Fazzoletti" } ] } { "dipendente.nome" : [ "Mario", "Roberto" ], "dipendente.cognome" : [ "Rossi", "Fazzoletti" ] } Documento Originale Indice creato da ES warning
  8. { "azienda" : "Azienda A" "dipendente" : [ { "nome"

    : "Mario", "cognome" : "Rossi" }, { "nome" : "Roberto", "cognome" : "Fazzoletti" } ] } { "azienda" : "Azienda B" "dipendente" : [ { "nome" : "Roberto", "cognome" : "Rossi" }, { "nome" : "Gino", "cognome" : "Parigino" } ] } GET /companies/company/_search? q=dipendente.nome:Roberto AND dipendente.cognome:Rossi Azienda A Azienda B
  9. Utilizzare sempre i DocType from elasticsearch_dsl import DocType, String, Date

    class Company(DocType): nome_legale = String() data_di_fondazione = Date() partita_iva = String() class Meta: index = 'companies' https://elasticsearch-dsl.readthedocs.org/en/latest/persistence.html
  10. django: build: . command: "echo ‘fake according to https://github.com/docker/compose/pull/ 1754#issuecomment-154218084'"

    links: - elasticsearch:atoka_es - postgres:pg - redis:redis environment: - ES_INDEX_HOST=atoka_es - RDS_HOSTNAME=pg - REDIS_HOSTNAME=redis postgres: image: postgres:latest environment: POSTGRES_USER: user POSTGRES_PASSWORD: password elasticsearch: image: elasticsearch:1.7.5 command: elasticsearch --node.local=true --index.store.type=memory redis: image: docker.io/redis:2.8.21
  11. TestRunner che si occupa di preparare un Elasticsearch per il

    testing class YourAppTestSuiteRunner(DiscoverRunner): 
 def setup_databases(self):
 if os.getenv('SKIP_LOADING_ES_DATA') is None:
 print('Loading es data...')
 print('Set SKIP_LOADING_ES_DATA to avoid this step')
 load_es_data()
 time.sleep(5) # fuck eventual consistency
 return super(YourAppTestSuiteRunner, self).setup_databases()
  12. Elasticsearch Alias • Hot swap di indici • Gruppi di

    indici 
 (utile per indici temporali) • Generare delle “view” POST /_aliases { "actions": [ { "remove": { "index": "companies-20160401", "alias": "companies" } }, { "add": { "index": "companies-20160410", "alias": "companies" } } ] }
  13. Cluster size / 2 Node1 - Master Node2 Node3 1

    2 3 1 2 3 Assicurarsi sempre di impostare la replica per gli shard
  14. Che server uso? Dimensione disco Rapporto dimensione/quantità shard Tipologia di

    disco SSD > Piatti RAID 0 > Piatti Quantità di memoria dipende dalle queries no silver bullet
  15. Gestire in maniera corretta la memoria attenzione alla field data,

    sarà il vostro peggior incubo https://es:9200/_cat/fielddata?v --ES_HEAP_SIZE ~ RAM/2 (max 32GB) evitare un numero eccessivo di shard https://www.elastic.co/blog/a-heap-of-trouble
  16. Monitor your cluster with Cluster API! Stato di salute del

    cluster Stato di salute di ogni singolo nodo Marvel + sistema di alerting https://www.elastic.co/guide/en/elasticsearch/reference/2.3/cluster.html
  17. Tuning insert performance usare la bulk insert utilizzando la dimensione

    ottimale ottimizzare il throttling indexing ricordarsi di disabilitare le repliche https://www.elastic.co/guide/en/elasticsearch/guide/current/indexing- performance.html
  18. Queries essenziali teniamo sotto controllo la dimensione delle risposte (il

    parametro _source ci aiuta) utilizzare la scroll
  19. Rolling restart 1. Fermare se possibile l’indicizzazione 2. Disabilitare la

    shard allocation 3. Spegnere un nodo 4. Fare le operazioni di maintenance etc etc 5. Riavviare il nodo e verificare che sia nel cluster 6. Abilitare la shard allocation 7. Ripetere per ogni nodo PUT /_cluster/settings { "transient" : { "cluster.routing.allocation.enable":"none" } } PUT /_cluster/settings { "transient" : { "cluster.routing.allocation.enable":"all" } }