Temps d'indexation (Elasticsearch/Php)


(Thierry) #1

Bonjour a tous,

dans un projet PHP,

  • j'ajoute un objet a un index.
  • Je demande a récupérer tous les objets pour les afficher.

si je ne met pas une pause entre le moment ou j'ajoute l'objet et le moment ou je demande la liste des objets, le dernier objet ajouté n'est pas dans la liste.

Par contre si je met une pause, de 500ms (par exemple) ça marche.

Le fait de mettre une pause ne me plait pas particulièrement...

Y a t'il un moyen de savoir si l'objet que j'ajoute est prêt a être affiché ???

Je travaille avec Symfony 4 et le client Elasticsearch/Elasticsearch.

  //-> Pour ajouter un objet j'utilise    
  $params = [
          "index" => $SElasIndex, 
          "type" => "_doc", 
          'body' => $OSched->getProps()
        ];
        $result = $this->client->index($params);
     -----------------------------------------------------------------------
    //-> Pour récupérer tous les objets j'utilise
        $params = [
          "index" => $SElasIndex, 
          "type" => "_doc", 
          'body' =>
          [
            "size" => 100,
            "query" => [
              "match_all" => (object)[]
            ]
          ]
        ];
        $result = $this->client->search($params);

Quelqu'un a une idée ?


(David Pilato) #2

Dans le cadre d'un test, tu peux utiliser l'API _refresh qui te permet de demander à rendre visible tous les documents.

Si c'est plus pour du code en prod, tu peux ajouter à l'opération d'indexation l'option ?refresh=wait_for ce qui te redonnera la main après qu'un refresh soit passé. Au pire (1 seconde plus tard).


(Thierry) #3

EXCELLENT !
Ça fonctionne.

J'ai modifié mon insertion d'objet comme ceci

    $params = [
          "index" => $SElasIndex,
          "type" => "_doc",
          "refresh" => true,
          'body' => $OSched->getProps()
        ];
    $result = $this->client->index($params); 

Et ça marche... merci

C'est la bonne façon de faire ?

Pourquoi "Dans le cadre d'un test" ?

Pour info la doc dit

/*
$params['index']        = (string) The name of the index (Required)
       ['type']         = (string) The type of the document (Required)
       ['id']           = (string) Specific document ID (when the POST method is used)
       ['consistency']  = (enum) Explicit write consistency setting for the operation
       ['op_type']      = (enum) Explicit operation type
       ['parent']       = (string) ID of the parent document
       ['refresh']      = (boolean) Refresh the index after performing the operation
       ['replication']  = (enum) Specific replication type
       ['routing']      = (string) Specific routing value
       ['timeout']      = (time) Explicit operation timeout
       ['timestamp']    = (time) Explicit timestamp for the document
       ['ttl']          = (duration) Expiration time for the document
       ['version']      = (number) Explicit version number for concurrency control
       ['version_type'] = (enum) Specific version type
       ['body']         = (array) The document
       ['body']  = (array) Request body
*/

(David Pilato) #4

Elasticsearch n'est pas conçu pour faire du temps-réel. Quand tu demandes "refresh" => true, tu essayes de le transformer en outil temps-réel ce qui est contre nature.

Donc je dirais que si tu injectes peu de documents, genre un document toutes les X secondes, faire un refresh comme ça est OK.
Par contre si tu injectes x documents par seconde, là tu vas te mettre à créer énormément de segments Lucene ce qui n'est pas super bon.
Tu constateras ensuite beaucoup d'IO disque consommé à regrouper ces segments en gros.

Le refresh=wait_for est un compromis. Il dit au client d'attendre que le prochain refresh soit passé avant de rendre la main. Ce qui garantit au client que le document est visible sans avoir nécessité toutefois la création d'un segment juste pour ce document.

C'est pour cela que je dis que refresh=true est ok dans un contexte de tests mais certainement pas de prod, sauf très faible volume d'ingestion.


(system) #5

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.