Envoi de données ElasticSearch


(Math) #1

Bonjour à tous !

j'envoi mes donées dans elasticsearch depuis un programme écrit en java.

Ma méthode n'est peut être pas la plus optimisée mais en bref j'envoi une liste de 30 000 documents chaque jours. Chaque requête n'envoie qu'un seul document.

Question 1 : Existe-t-il une facon d'envoyer mes 30 000 docs en ouvrant qu'une seule connexion depuis Java.

Le problème que je rencontre actuellement c'est que sur les 30 000 doc envoyé seulement la moitié se retrouve dans Kibana (donc dans elasticsearch je présume). Or j'ai testé de bout en bout mon programme java, les 30 000 doc sont bien créer et 30 000 connexions vers elasticsearch sont bien établi.

Question 2 : Avez-vous une petite idée de pourquoi je ne recois que environ la moitié de mes docs ?

Mathieu


(David Pilato) #2

Existe-t-il une facon d'envoyer mes 30 000 docs en ouvrant qu'une seule connexion depuis Java.

Oui. Enfin presque: https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-document-bulk.html

Avez-vous une petite idée de pourquoi je ne recois que environ la moitié de mes docs ?

Non. Mais souvent ça vient de l'utilisation du même _id qui du coup remplace un doc existant.


(Math) #3

Aaaaaah

Du coup une solution est a envisager ou je suis cuit ?
_id est une variable qu'elasticsearch fixe sur chaque document de facon aléatoire ou c'est paramétrable en taille de facon a ce que je puisse regler mes soucis ?


(David Pilato) #4

Si c'est elasticsearch qui fixe l'_id, autrement dit, ce n'est pas toi qui le fournit, alors ce cas là ne peut pas arriver.

Donc peut-être devrais-tu partager ton code ici pour qu'on voit ce que tu fais exactement...


(Math) #5

Réponse tardive de ma part,
Je viens de me remettre sur ce problème pour le traiter, mon problème d'import n'était pas sur l'_id qui remplacer des docs mais sur des caractères spéciaux qui ne passaient pas !

J'ai également utilisé bulk pour envoyer mes 30 000 docs avec une seule connexion à elasticsearch.
Je poste quelques renseignements si cela peut aider quelqu'un à l'avenir !

Temps d'indexation de 30 000 docs JSON en créant une connexion par envoie -> environ 7-8 minutes.
Temps d'indexation de 30 000 docs JSON en créant une seule connexion -> environ 4-5 SECONDES.

Voici comment j'ai utilisé bulk :

public static void executePost(Collection<Message> messages) {
    if (messages.isEmpty()) return;

    BulkRequest request = new BulkRequest();

    messages.stream().forEach(u -> {

      u.getRequests().forEach(r -> {

        request.add(new IndexRequest(u.getIndex(), u.getType()).source(r, XContentType.JSON));

      });

    });

    try (RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost(HOSTNAME, PORT, PROTOCOL)))) {

      client.bulk(request);

    }
    catch (IOException e) {
      LOGGER.error("Unable to send data with bulk", e);
    }

  }

Mes objets Message contiennent deux variables String contenant le nom de l'index et le nom du type ainsi qu'une collection de string contenant les différents documents JSON à indexer !


(David Pilato) #6

Juste une remarque. Tu te retrouves du coup à envoyer un bulk de 30000 documents.

A l'avenir, ça pourrait être un bulk de 1000000 de documents éventuellement.
Ca ne passera plus à un moment...

Le mieux est d'envoyer un bulk toutes les x opérations (x à déterminer mais dans mon cas d'usage, 10000 était une bonne valeur).

Pour simplifier tout ça, tu as le bulk processor en Java. Regarde https://www.elastic.co/guide/en/elasticsearch/client/java-rest/6.1/java-rest-high-document-bulk.html#java-rest-high-document-bulk-processor


(system) #7

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